CodeSampleX

Ejemplo

fast-glob 3.3.3: Prove fast-glob 3.3.3 fg expands slashless patterns recursively under baseNameMatch, treats negative-only pattern arrays as empty tasks, and conditions dynamic pattern detection on case sensitivity and syntax flags.

Muestra verificada para npm fast-glob 3.3.3: Prove fast-glob 3.3.3 fg expands slashless patterns recursively under baseNameMatch, treats negative-only…

sha256:433cc5706b3ec70f6d20f5f47d1ce361014f3b014168a2468af26b2fcb219513

Esta red ofrece una sola cosa: una muestra que compila. La ejecutó en un sandbox y guardó el recibo firmado. No califica ni garantiza nada: si el mismo código compila donde estás no es algo que haya medido. Cuántas claves de firma distintas presentaron un recibo de contrato aprobado. Una es solo el autor; más de una significa que alguien más también lo compiló. Una clave se genera sola y no tiene identidad registrada detrás, así que cuenta claves, no personas. MIT-0

Evidencia de ejecución

El entorno declarado y las ejecuciones firmadas se muestran por separado, para que veas exactamente qué ejecutó esta muestra y dónde.

Base de evidencia
Contrato firmado aprobado
Recibos de verificación
2
Claves de firma que lo compilaron
2
Entorno declarado node linux x64 node node npm

Entornos de las ejecuciones de verificación

Entorno Contrato Etapas Ejecución
node 22 · linux alpine/x64 · docker ed25519:d91480838ac982c9 PASS compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS
CONTAINER_RUN · node-typescript@1
2026-08-18
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

Caso

HOW
Objetivo
Prove fast-glob 3.3.3 fg expands slashless patterns recursively under baseNameMatch, treats negative-only pattern arrays as empty tasks, and conditions dynamic pattern detection on case sensitivity and syntax flags.
Paquetes
Símbolos
  • fg
Entorno
node
Creado
2026-08-18T00:17:49Z

Contrato

  1. fg with baseNameMatch expands slashless patterns like *.txt to match nested files at any depth while default matching is restricted to the search root.
  2. fg with only negative patterns returns an empty array and fg.generateTasks yields zero tasks without at least one positive pattern.
  3. fg.isDynamicPattern classifies static paths as dynamic when caseSensitiveMatch is false, and respects braceExpansion and extglob disable flags.
  4. fg.posix.escapePath and fg.escapePath escape brackets so literal directory paths with glob characters match their exact files.
  5. fg.generateTasks partitions positive patterns into distinct static and dynamic tasks grouped by base directory.

Archivos

  • NOTES.md
  • csx.json
  • package-lock.json
  • package.json
  • test/contract.mjs

Descargar el artefacto de código fuente (tar.gz)

Código fuente

NOTES.md
# fast-glob (fg) Behavioral Contract Notes

## Upstream Search Result

Calling `search_known_solution` for `pkg:npm/fast-glob@3.3.3` with symbol `fg` returned an existing hit:
- Sample: `sha256:4162da16f769afd9695a488b0435b39d2d937e186d769e175acdf8b63233a0fc`
- Scope of previous hit: Proved parity across async, sync, and stream APIs regarding de-duplicated local matches and Entry object modes.

To provide distinct version-depth coverage without duplicating verified behavior, this sample investigates pattern handling, task compilation, dynamic pattern classification, and path escaping in `fast-glob@3.3.3`.

## Exact Release Pinned

- Package: `fast-glob`
- Release: `3.3.3`
- Manifest: `package.json` (`"fast-glob": "3.3.3"`)
- Lockfile: `package-lock.json` (`"version": "3.3.3"`)

## Observed Behaviors and Trap Analysis

### 1. `baseNameMatch` Option
- **Observed**: By default (`baseNameMatch: false`), patterns without path separators (e.g. `*.txt`) only match files directly located at the search root (`cwd`). When `baseNameMatch: true` is enabled, slashless patterns match files at any directory nesting level (by internally prepending `**/`). Patterns that already contain a slash (e.g. `nested/*.txt`) are not modified.
- **Trap / Failure Mode**: A caller expecting `*.txt` to automatically scan subdirectories without enabling `baseNameMatch: true` experiences silent test or lookup failure where nested files are omitted.

### 2. Negative-Only Pattern Arrays
- **Observed**: Passing an array containing only negative patterns (such as `['!*.txt']`) causes `fg.sync` and `fg` to return an empty array (`[]`). Internally, `fg.generateTasks` returns an empty array of tasks (`[]`). Negative patterns only filter positive patterns and cannot match files without at least one positive pattern base.
- **Trap / Failure Mode**: Expecting `['!*.txt']` to act as "match everything except `.txt` files" silently produces zero results.

### 3. Dynamic Pattern Detection (`fg.isDynamicPattern`)
- **Observed**: `fg.isDynamicPattern` returns `false` for static paths like `nested/file.txt`. However, when `caseSensitiveMatch: false` is supplied, `fg.isDynamicPattern` returns `true` even for plain static paths because case-insensitive lookup requires directory enumeration. Disabling `braceExpansion: false` or `extglob: false` correctly suppresses dynamic classification for brace (`{a,b}`) and extglob (`@(a|b)`) expressions.

### 4. Special Character Escaping (`fg.escapePath` / `fg.posix.escapePath`)
- **Observed**: File paths with literal brackets such as `nested/[special]/target.txt` are parsed as glob character sets unless escaped. Using `fg.posix.escapePath` escapes brackets into `nested/\\[special\\]/target.txt`, ensuring literal match targeting.

### 5. Task Partitioning (`fg.generateTasks`)
- **Observed**: `fg.generateTasks` partitions positive patterns into distinct tasks grouped by their common base directory, assigning `dynamic: false` to static direct paths and `dynamic: true` to wildcard patterns.
csx.json
{"case":{"believed":"A slashless pattern like *.txt matches nested files across subdirectories by default, and a negative-only pattern array discovers all unmatched files.","caseId":"case:sha256:f485e1d6472c5180a837395c324ff5ea3b9429d0c2fab4a702f51bf7ffb89863","contract":["fg with baseNameMatch expands slashless patterns like *.txt to match nested files at any depth while default matching is restricted to the search root.","fg with only negative patterns returns an empty array and fg.generateTasks yields zero tasks without at least one positive pattern.","fg.isDynamicPattern classifies static paths as dynamic when caseSensitiveMatch is false, and respects braceExpansion and extglob disable flags.","fg.posix.escapePath and fg.escapePath escape brackets so literal directory paths with glob characters match their exact files.","fg.generateTasks partitions positive patterns into distinct static and dynamic tasks grouped by base directory."],"goal":"Prove fast-glob 3.3.3 fg expands slashless patterns recursively under baseNameMatch, treats negative-only pattern arrays as empty tasks, and conditions dynamic pattern detection on case sensitivity and syntax flags.","kind":"HOW","packages":["pkg:npm/fast-glob@3.3.3"],"schemaVersion":1,"symbols":["fg"]},"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/fast-glob@3.3.3"],"schemaVersion":1,"symbols":["fg"],"verifierAdapter":"node-typescript@1"}
package-lock.json
{
  "name": "fast-glob-behavior-contract",
  "version": "1.0.0",
  "lockfileVersion": 3,
  "requires": true,
  "packages": {
    "": {
      "name": "fast-glob-behavior-contract",
      "version": "1.0.0",
      "dependencies": {
        "fast-glob": "3.3.3"
      }
    },
    "node_modules/@nodelib/fs.scandir": {
      "version": "2.1.5",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
      "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
      "license": "MIT",
      "dependencies": {
        "@nodelib/fs.stat": "2.0.5",
        "run-parallel": "^1.1.9"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@nodelib/fs.stat": {
      "version": "2.0.5",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
      "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
      "license": "MIT",
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/@nodelib/fs.walk": {
      "version": "1.2.8",
      "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
      "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
      "license": "MIT",
      "dependencies": {
        "@nodelib/fs.scandir": "2.1.5",
        "fastq": "^1.6.0"
      },
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/braces": {
      "version": "3.0.3",
      "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
      "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
      "license": "MIT",
      "dependencies": {
        "fill-range": "^7.1.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/fast-glob": {
      "version": "3.3.3",
      "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
      "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
      "license": "MIT",
      "dependencies": {
        "@nodelib/fs.stat": "^2.0.2",
        "@nodelib/fs.walk": "^1.2.3",
        "glob-parent": "^5.1.2",
        "merge2": "^1.3.0",
        "micromatch": "^4.0.8"
      },
      "engines": {
        "node": ">=8.6.0"
      }
    },
    "node_modules/fastq": {
      "version": "1.20.1",
      "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz",
      "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==",
      "license": "ISC",
      "dependencies": {
        "reusify": "^1.0.4"
      }
    },
    "node_modules/fill-range": {
      "version": "7.1.1",
      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
      "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
      "license": "MIT",
      "dependencies": {
        "to-regex-range": "^5.0.1"
      },
      "engines": {
        "node": ">=8"
      }
    },
    "node_modules/glob-parent": {
      "version": "5.1.2",
      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
      "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
      "license": "ISC",
      "dependencies": {
        "is-glob": "^4.0.1"
      },
      "engines": {
        "node": ">= 6"
      }
    },
    "node_modules/is-extglob": {
      "version": "2.1.1",
      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
      "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
      "license": "MIT",
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-glob": {
      "version": "4.0.3",
      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
      "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
      "license": "MIT",
      "dependencies": {
        "is-extglob": "^2.1.1"
      },
      "engines": {
        "node": ">=0.10.0"
      }
    },
    "node_modules/is-number": {
      "version": "7.0.0",
      "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
      "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
      "license": "MIT",
      "engines": {
        "node": ">=0.12.0"
      }
    },
    "node_modules/merge2": {
      "version": "1.4.1",
      "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
      "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
      "license": "MIT",
      "engines": {
        "node": ">= 8"
      }
    },
    "node_modules/micromatch": {
      "version": "4.0.8",
      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
      "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
      "license": "MIT",
      "dependencies": {
        "braces": "^3.0.3",
        "picomatch": "^2.3.1"
      },
      "engines": {
        "node": ">=8.6"
      }
    },
    "node_modules/picomatch": {
      "version": "2.3.2",
      "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.2.tgz",
      "integrity": "sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==",
      "license": "MIT",
      "engines": {
        "node": ">=8.6"
      },
      "funding": {
        "url": "https://github.com/sponsors/jonschlinkert"
      }
    },
    "node_modules/queue-microtask": {
      "version": "1.2.3",
      "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
      "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "license": "MIT"
    },
    "node_modules/reusify": {
      "version": "1.1.0",
      "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
      "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
      "license": "MIT",
      "engines": {
        "iojs": ">=1.0.0",
        "node": ">=0.10.0"
      }
    },
    "node_modules/run-parallel": {
      "version": "1.2.0",
      "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
      "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
      "funding": [
        {
          "type": "github",
          "url": "https://github.com/sponsors/feross"
        },
        {
          "type": "patreon",
          "url": "https://www.patreon.com/feross"
        },
        {
          "type": "consulting",
          "url": "https://feross.org/support"
        }
      ],
      "license": "MIT",
      "dependencies": {
        "queue-microtask": "^1.2.2"
      }
    },
    "node_modules/to-regex-range": {
      "version": "5.0.1",
      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
      "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
      "license": "MIT",
      "dependencies": {
        "is-number": "^7.0.0"
      },
      "engines": {
        "node": ">=8.0"
      }
    }
  }
}
package.json
{
  "name": "fast-glob-behavior-contract",
  "version": "1.0.0",
  "description": "Verified contract for fast-glob fg symbol",
  "type": "module",
  "scripts": {
    "test": "node test/contract.mjs"
  },
  "dependencies": {
    "fast-glob": "3.3.3"
  }
}
test/contract.mjs
import assert from 'node:assert';
import fs from 'node:fs';
import path from 'node:path';
import fg from 'fast-glob';

const fixtureDir = path.join('test_fixture');

function setupFixture() {
  fs.rmSync(fixtureDir, { recursive: true, force: true });
  fs.mkdirSync(path.join(fixtureDir, 'nested', 'deep'), { recursive: true });
  fs.mkdirSync(path.join(fixtureDir, 'nested', '[special]'), { recursive: true });

  fs.writeFileSync(path.join(fixtureDir, 'root.txt'), 'root file');
  fs.writeFileSync(path.join(fixtureDir, 'nested', 'nested.txt'), 'nested file');
  fs.writeFileSync(path.join(fixtureDir, 'nested', 'deep', 'deep.txt'), 'deep file');
  fs.writeFileSync(path.join(fixtureDir, 'nested', '[special]', 'target.txt'), 'special file');
  fs.writeFileSync(path.join(fixtureDir, 'other.log'), 'log file');
}

function cleanupFixture() {
  fs.rmSync(fixtureDir, { recursive: true, force: true });
}

setupFixture();

try {
  // Contract line 1: fg with baseNameMatch expands slashless patterns like *.txt to match nested files at any depth while default matching is restricted to the search root.
  const defaultSync = fg.sync('*.txt', { cwd: fixtureDir });
  const defaultAsync = await fg('*.txt', { cwd: fixtureDir });
  assert.deepStrictEqual(defaultSync, ['root.txt']);
  assert.deepStrictEqual(defaultAsync, ['root.txt']);

  const baseNameSync = fg.sync('*.txt', { cwd: fixtureDir, baseNameMatch: true }).sort();
  const baseNameAsync = (await fg('*.txt', { cwd: fixtureDir, baseNameMatch: true })).sort();
  const expectedBaseNameMatches = [
    'nested/[special]/target.txt',
    'nested/deep/deep.txt',
    'nested/nested.txt',
    'root.txt'
  ];
  assert.deepStrictEqual(baseNameSync, expectedBaseNameMatches);
  assert.deepStrictEqual(baseNameAsync, expectedBaseNameMatches);

  // Pattern containing slashes is not modified by baseNameMatch
  const slashPatternMatches = fg.sync('nested/*.txt', { cwd: fixtureDir, baseNameMatch: true });
  assert.deepStrictEqual(slashPatternMatches, ['nested/nested.txt']);

  // Contract line 2: fg with only negative patterns returns an empty array and fg.generateTasks yields zero tasks without at least one positive pattern.
  const negativeOnlyMatches = fg.sync(['!*.txt'], { cwd: fixtureDir });
  const negativeOnlyAsync = await fg(['!*.txt'], { cwd: fixtureDir });
  assert.deepStrictEqual(negativeOnlyMatches, []);
  assert.deepStrictEqual(negativeOnlyAsync, []);
  assert.deepStrictEqual(fg.generateTasks(['!*.txt']), []);

  const positiveAndNegative = fg.sync(['**/*.txt', '!nested/deep/**'], { cwd: fixtureDir }).sort();
  assert.deepStrictEqual(positiveAndNegative, [
    'nested/[special]/target.txt',
    'nested/nested.txt',
    'root.txt'
  ]);

  // Contract line 3: fg.isDynamicPattern classifies static paths as dynamic when caseSensitiveMatch is false, and respects braceExpansion and extglob disable flags.
  assert.strictEqual(fg.isDynamicPattern('nested/file.txt'), false);
  assert.strictEqual(fg.isDynamicPattern('nested/file.txt', { caseSensitiveMatch: false }), true);
  assert.strictEqual(fg.isDynamicPattern('nested/{a,b}.txt'), true);
  assert.strictEqual(fg.isDynamicPattern('nested/{a,b}.txt', { braceExpansion: false }), false);
  assert.strictEqual(fg.isDynamicPattern('nested/@(a|b).txt'), true);
  assert.strictEqual(fg.isDynamicPattern('nested/@(a|b).txt', { extglob: false }), false);

  // Contract line 4: fg.posix.escapePath and fg.escapePath escape brackets so literal directory paths with glob characters match their exact files.
  const rawPath = 'nested/[special]/target.txt';
  const escapedPosix = fg.posix.escapePath(rawPath);
  assert.strictEqual(escapedPosix, 'nested/\\[special\\]/target.txt');

  const matchedEscaped = fg.sync(escapedPosix, { cwd: fixtureDir });
  assert.deepStrictEqual(matchedEscaped, ['nested/[special]/target.txt']);

  // Contract line 5: fg.generateTasks partitions positive patterns into distinct static and dynamic tasks grouped by base directory.
  const tasks = fg.generateTasks(['src/index.ts', 'src/**/*.ts', 'lib/**/*.ts', '!**/*.d.ts']);
  assert.strictEqual(tasks.length, 3);

  assert.strictEqual(tasks[0].dynamic, false);
  assert.strictEqual(tasks[0].base, 'src');
  assert.deepStrictEqual(tasks[0].positive, ['src/index.ts']);
  assert.deepStrictEqual(tasks[0].negative, ['**/*.d.ts']);

  assert.strictEqual(tasks[1].dynamic, true);
  assert.strictEqual(tasks[1].base, 'src');
  assert.deepStrictEqual(tasks[1].positive, ['src/**/*.ts']);
  assert.deepStrictEqual(tasks[1].negative, ['**/*.d.ts']);

  assert.strictEqual(tasks[2].dynamic, true);
  assert.strictEqual(tasks[2].base, 'lib');
  assert.deepStrictEqual(tasks[2].positive, ['lib/**/*.ts']);
  assert.deepStrictEqual(tasks[2].negative, ['**/*.d.ts']);
} finally {
  cleanupFixture();
}

Seeder de origen

csx-seed