示例
chalk 5.4.1: Preserve string interpolation and argument types across Chalk styling calls without tagged-template array concatenation or silent Object coercion
已验证示例 — npm chalk 5.4.1: Preserve string interpolation and argument types across Chalk styling calls without tagged-template array concatenation or silent…
sha256:82b00788c1e285d6dea83a1df814eea768a2def744ca9905992c4c16344b5a5f
本网络只提供一件事:能构建的样本。它在沙箱中运行并保留签名回执。它不评级、不担保——同样的代码能否在你的环境构建,它没有测量过。
提交了通过的契约回执的不同签名密钥数量。为 1 表示只有作者;大于 1 表示还有其他人构建过。密钥是自行生成的,背后没有注册身份,因此计的是密钥而非人。
MIT-0
执行证据
声明的环境与签名的运行分开呈现,你可以看到这个样本究竟运行了什么、在哪里运行。
- 证据依据
- 签名契约通过
- 验证回执
- 2
- 构建过它的签名密钥
- 2
声明的环境
node linux x64 node node npm
验证运行环境
| 环境 | 契约 | 阶段 | 运行日期 |
|---|---|---|---|
| node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-16 |
| node 22 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · node-typescript@1 |
2026-08-18 |
案例
HOW- 目标
- Preserve string interpolation and argument types across Chalk styling calls without tagged-template array concatenation or silent Object coercion
- 符号
-
- chalk
- 环境
- node
- 创建时间
- 2026-08-16T16:10:40Z
契约
- Calling a Chalk style function as a tagged template literal coerces the template strings array with commas and appends substitutions at the end rather than interleaving them.
- Evaluating template expressions before passing them into Chalk produces properly interpolated and styled strings
- Passing variadic arguments joins them with spaces whereas passing an array stringifies elements with commas
- Passing plain objects coerces them to [object Object] rather than JSON or inspected representation
- Passing empty strings or empty arrays returns an empty string without ANSI escape sequences while 0 and false retain ANSI styling
- Passing a Symbol directly throws a TypeError from string coercion
文件
- NOTES.md
- csx.json
- package-lock.json
- package.json
- src/index.mjs
- test/contract.mjs
源代码
# Chalk String Interpolation and Type Serialization Boundaries
### What `search_known_solution` answered
- `search_known_solution` returned existing sample `sha256:525f14e9ff41964b2cf8700329f042389c75335c2b13dc4d12796c1cbb8e0f28` ("Configure runtime color formatting and disable ANSI codes in Chalk v5 via chalk.level instead of deprecated chalk.enabled or missing chalk.supportsColor"), `sha256:2f6838edb7c63b1b528b3bfb3a2bea8805f50b06592b69b3f62ca5166f239c8b` ("Format stderr output with stream-specific color levels via the named export chalkStderr rather than the removed chalk.stderr property"), and `sha256:1d01640309b3b61194965429100ee64dc820854d9541aa68eaf18e0830575a8a` ("Instantiate Chalk instances with custom color levels to downsample 24-bit hex and RGB colors across terminal depths and avoid default export constructor traps").
- This sample proves a distinct type and serialization boundary trap: calling Chalk style methods as tagged template literals (which comma-joins template strings and displaces substitutions rather than interleaving them) versus standard evaluated template literals, plus argument coercion behavior across Arrays, Objects, Symbols, and falsy primitives.
### What a model would have written instead
- A model would write tagged template literals like `chalk.red\`User ${user} logged in\`` expecting native tagged template literal parsing (as in earlier template tag libraries or styled-components), or pass unformatted error/payload objects directly into `chalk.yellow(obj)` expecting structured JSON formatting.
### How the wrong version fails
- Silently with a green build: tagged template literal calls (`chalk.red\`User ${user} attempted ${action}\``) succeed without error but produce corrupted output strings (`\u001b[31mUser , attempted , admin login\u001b[39m`) with comma artifacts and displaced arguments, while direct object arguments silently stringify to `[object Object]`.
{"case":{"believed":"Calling Chalk style functions as tagged template literals interpolates expressions at their placeholder positions within the styled template string.","caseId":"case:sha256:1570aae67f96b97743c43fe9379e91a350f73c5d1992efae1da6545aa28efa97","contract":["Calling a Chalk style function as a tagged template literal coerces the template strings array with commas and appends substitutions at the end rather than interleaving them.","Evaluating template expressions before passing them into Chalk produces properly interpolated and styled strings","Passing variadic arguments joins them with spaces whereas passing an array stringifies elements with commas","Passing plain objects coerces them to [object Object] rather than JSON or inspected representation","Passing empty strings or empty arrays returns an empty string without ANSI escape sequences while 0 and false retain ANSI styling","Passing a Symbol directly throws a TypeError from string coercion"],"goal":"Preserve string interpolation and argument types across Chalk styling calls without tagged-template array concatenation or silent Object coercion","kind":"HOW","packages":["pkg:npm/chalk@5.4.1"],"schemaVersion":1,"symbols":["chalk"]},"contractCommand":["node","test/contract.mjs"],"environment":{"arch":"x64","ecosystem":"npm","executionContext":"node","language":"node","os":"linux","packageManager":"npm","runtime":"node","schemaVersion":1},"license":"MIT-0","packages":["pkg:npm/chalk@5.4.1"],"schemaVersion":1,"symbols":["chalk"],"verifierAdapter":"node-typescript@1"}
{
"name": "csx-sample-chalk-type-serialization-boundary",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "csx-sample-chalk-type-serialization-boundary",
"version": "1.0.0",
"license": "MIT-0",
"dependencies": {
"chalk": "5.4.1"
}
},
"node_modules/chalk": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
"integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
"license": "MIT",
"engines": {
"node": "^12.17.0 || ^14.13 || >=16.0.0"
},
"funding": {
"url": "https://github.com/chalk/chalk?sponsor=1"
}
}
}
}
{
"name": "csx-sample-chalk-type-serialization-boundary",
"version": "1.0.0",
"private": true,
"type": "module",
"license": "MIT-0",
"dependencies": {
"chalk": "5.4.1"
}
}
import chalk from 'chalk';
/**
* Format a log message using standard template literal interpolation.
* Calling chalk methods with pre-evaluated strings preserves placeholder positions.
*
* @param {string} user
* @param {string} action
* @returns {string}
*/
export function formatUserAction(user, action) {
return chalk.red(`User ${user} attempted ${action}`);
}
/**
* Demonstrate the tagged template invocation trap.
* When a Chalk style function is used as a template tag (chalk.red`...`),
* Chalk receives (templateStringsArray, ...values) as variadic arguments,
* resulting in comma-joined strings followed by appended values.
*
* @param {string} user
* @param {string} action
* @returns {string}
*/
export function formatUserActionTaggedTrap(user, action) {
return chalk.red`User ${user} attempted ${action}`;
}
/**
* Safely format arbitrary payloads through Chalk, handling Objects, Arrays,
* and Symbols without silent [object Object] coercion or uncaught TypeErrors.
*
* @param {unknown} value
* @returns {string}
*/
export function formatPayload(value) {
if (typeof value === 'symbol') {
return chalk.yellow(value.toString());
}
if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
return chalk.yellow(JSON.stringify(value));
}
return chalk.yellow(value);
}
import { strict as assert } from 'node:assert';
import chalk from 'chalk';
import { formatUserAction, formatUserActionTaggedTrap, formatPayload } from '../src/index.mjs';
// Force level 1 to ensure ANSI codes are emitted deterministically
chalk.level = 1;
// CONTRACT LINE 1 (contradicts believed):
// Calling a Chalk style function as a tagged template literal coerces the template strings array with commas and appends substitutions at the end rather than interleaving them.
const user = 'admin';
const action = 'login';
const taggedOutput = formatUserActionTaggedTrap(user, action);
assert.equal(
taggedOutput,
'\u001b[31mUser , attempted , admin login\u001b[39m',
'Tagged template call unexpectedly coerces template strings array to comma-separated string and appends substitutions'
);
// CONTRACT LINE 2:
// Evaluating template expressions before passing them into Chalk produces properly interpolated and styled strings
const evaluatedOutput = formatUserAction(user, action);
assert.equal(
evaluatedOutput,
'\u001b[31mUser admin attempted login\u001b[39m',
'Standard template literal passed to Chalk produces properly interpolated output'
);
// CONTRACT LINE 3:
// Passing variadic arguments joins them with spaces whereas passing an array stringifies elements with commas
const variadicOutput = chalk.blue('status:', 200, 'OK');
assert.equal(
variadicOutput,
'\u001b[34mstatus: 200 OK\u001b[39m',
'Variadic arguments are space-joined'
);
const arrayOutput = chalk.blue(['status:', 200, 'OK']);
assert.equal(
arrayOutput,
'\u001b[34mstatus:,200,OK\u001b[39m',
'Single array argument is converted to string via Array.toString() with commas'
);
// CONTRACT LINE 4:
// Passing plain objects coerces them to [object Object] rather than JSON or inspected representation
const plainObject = { code: 404, status: 'Not Found' };
const unformattedObject = chalk.yellow(plainObject);
assert.equal(
unformattedObject,
'\u001b[33m[object Object]\u001b[39m',
'Direct object argument silently coerces to [object Object]'
);
const safelyFormattedObject = formatPayload(plainObject);
assert.equal(
safelyFormattedObject,
'\u001b[33m{"code":404,"status":"Not Found"}\u001b[39m',
'Explicit JSON serialization preserves structured data'
);
// CONTRACT LINE 5:
// Passing empty strings or empty arrays returns an empty string without ANSI escape sequences while 0 and false retain ANSI styling
assert.equal(chalk.red(''), '', 'Empty string returns empty string without ANSI escape codes');
assert.equal(chalk.red([]), '', 'Empty array coerces to empty string and returns without ANSI escape codes');
assert.equal(chalk.red(0), '\u001b[31m0\u001b[39m', 'Number 0 is coerced to "0" and wrapped in ANSI escape codes');
assert.equal(chalk.red(false), '\u001b[31mfalse\u001b[39m', 'Boolean false is coerced to "false" and wrapped in ANSI escape codes');
assert.equal(chalk.red(null), '\u001b[31mnull\u001b[39m', 'null is coerced to "null" and wrapped in ANSI escape codes');
assert.equal(chalk.red(undefined), '\u001b[31mundefined\u001b[39m', 'undefined is coerced to "undefined" and wrapped in ANSI escape codes');
// CONTRACT LINE 6:
// Passing a Symbol directly throws a TypeError from string coercion
assert.throws(
() => chalk.yellow(Symbol('session-id')),
{
name: 'TypeError',
message: 'Cannot convert a Symbol value to a string',
},
'Passing a Symbol directly to Chalk causes an uncaught TypeError'
);
assert.equal(
formatPayload(Symbol('session-id')),
'\u001b[33mSymbol(session-id)\u001b[39m',
'formatPayload converts Symbol to string before styling'
);
console.log('CONTRACT PASS: Chalk type serialization and tagged template boundaries verified');