@jterrazz/test 13.0.0 → 13.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1637,17 +1637,18 @@ interface CliSpecificationOptions<Services extends ServiceRecord = ServiceRecord
1637
1637
  */
1638
1638
  docker?: DockerSpecConfig;
1639
1639
  /**
1640
- * Named environment SETS for literate `.cli` specs. A header line
1641
- * `env: frozen` applies the whole `frozen` record; `$WORKDIR` expands and
1642
- * `null` unsets, exactly as in `.env()`. Declared once per app so a
1643
- * scenario file states WHICH ground it stands on, not how to build it.
1640
+ * Named environment SETS for `<case>.spec.yaml` documents. An `env:` entry
1641
+ * `frozen` applies the whole `frozen` record; `$WORKDIR` expands and `null`
1642
+ * unsets, exactly as in `.env()`. Declared once per app so a document
1643
+ * states WHICH ground it stands on, not how to build it.
1644
1644
  */
1645
1645
  env?: Record<string, CliEnv>;
1646
1646
  /**
1647
- * Named servers a literate `.cli` header may start (`serve: mcp KEY=value`).
1648
- * Each entry names the shell `command`, the `ready` regex whose capture
1649
- * group holds the port the server announces, the `url(port)` builder, and
1650
- * the `env` variable that URL is bound to in every block's child.
1647
+ * Named servers a `<case>.spec.yaml` document may start (`serve: [mcp]`, or
1648
+ * `- mcp: { KEY: value }` to add env to that one). Each entry names the
1649
+ * shell `command`, the `ready` regex whose capture group holds the port the
1650
+ * server announces, the `url(port)` builder, and the `env` variable that
1651
+ * URL is bound to in every run's child.
1651
1652
  */
1652
1653
  serve?: Record<string, LiterateServeRegistration>;
1653
1654
  /**
@@ -16,11 +16,51 @@ function detectIndent(text) {
16
16
  }
17
17
  return smallest === 0 ? 2 : smallest;
18
18
  }
19
+ /** The tag every string goes out through — key, plain value and block scalar alike. */
20
+ const STRING_TAG = "tag:yaml.org,2002:str";
21
+ /** An indentation indicator is ONE digit, so nine spaces is the deepest step statable. */
22
+ const DEEPEST_STATABLE_STEP = 9;
23
+ /**
24
+ * Restate a block scalar's indentation indicator from the indentation its
25
+ * content is actually written at.
26
+ *
27
+ * A block scalar whose first line opens on a space NEEDS that indicator: without
28
+ * it a reader takes the space for indentation and gives back a string shorter
29
+ * than the one that was written. The `yaml` writer knows when one is called for
30
+ * and adds it — but it always writes the digit `2`, its own default step, never
31
+ * the step it was asked to indent with. In a four-space document (oxfmt formats
32
+ * YAML at four) `|2` puts every line back two spaces short, so the golden update
33
+ * mode just wrote fails on its very next run.
34
+ *
35
+ * The digit belongs to the block, not to the writer's default: content sits one
36
+ * step below its key, so the file's step is what the indicator names — and `1`
37
+ * at the root, which YAML counts from -1.
38
+ */
39
+ function stateIndentation(written, ctx) {
40
+ if (!/^[|>][1-9]/.test(written)) return written;
41
+ const step = ctx.indent === "" ? 1 : ctx.indentStep.length;
42
+ if (step > DEEPEST_STATABLE_STEP) throw new Error(`A block scalar indented by ${step} spaces cannot state its indentation: YAML writes that indicator as a single digit, so ${DEEPEST_STATABLE_STEP} spaces is the deepest step a document may be written with.`);
43
+ return `${written[0]}${step}${written.slice(2)}`;
44
+ }
45
+ /** A scalar tag among the schema's, told from a collection one by what it may hold. */
46
+ function isScalarTag(tag) {
47
+ return typeof tag !== "string" && tag.collection === void 0;
48
+ }
49
+ /** The string tag, wrapped so every block scalar it writes states its own indentation. */
50
+ function statingItsIndentation(tag) {
51
+ const write = tag.stringify;
52
+ if (write === void 0) return tag;
53
+ return {
54
+ ...tag,
55
+ stringify: (item, ctx, onComment, onChompKeep) => stateIndentation(write(item, ctx, onComment, onChompKeep), ctx)
56
+ };
57
+ }
19
58
  /** Parse a YAML file into its document form, keeping comments and key order. */
20
59
  function parseYamlSource(text) {
21
60
  const lineCounter = new LineCounter();
22
61
  return {
23
62
  document: parseDocument(text, {
63
+ customTags: (tags) => tags.map((tag) => isScalarTag(tag) && tag.tag === STRING_TAG ? statingItsIndentation(tag) : tag),
24
64
  keepSourceTokens: true,
25
65
  lineCounter
26
66
  }),
@@ -38,8 +78,10 @@ function yamlSyntaxErrors(source) {
38
78
  /**
39
79
  * A literal block scalar. The `yaml` writer picks the chomping indicator from
40
80
  * the value itself — `|` when the text ends with a newline, `|-` when it does
41
- * not — and adds the indentation indicator (`|2`) when the first line starts
42
- * with a space, which is exactly the byte-exactness the format promises.
81
+ * not — and decides whether an indentation indicator is called for, which is
82
+ * when the first line opens on a space. What that indicator SAYS is restated on
83
+ * the way out by `stateIndentation` above, and together the two are the
84
+ * byte-exactness the format promises.
43
85
  */
44
86
  function blockScalar(text) {
45
87
  const scalar = new Scalar(text);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jterrazz/test",
3
- "version": "13.0.0",
3
+ "version": "13.0.2",
4
4
  "description": "Declarative testing framework for HTTP APIs, CLIs, and background jobs — one entry point, real infrastructure, golden-file assertions, plus an oxlint convention plugin.",
5
5
  "keywords": [
6
6
  "api-testing",