Ejemplo
fast-glob 3.3.3: Stream matching file paths using fg.stream with async iteration and objectMode entry metadata
Muestra verificada para npm fast-glob 3.3.3: Stream matching file paths using fg.stream with async iteration and objectMode entry metadata. El contrato se…
sha256:a87b82ea63e7604672d60f57009d959121e6fd22442e75c1ece5a79e10bfedd7
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-17 |
| 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
- Stream matching file paths using fg.stream with async iteration and objectMode entry metadata
- Paquetes
- Símbolos
-
- fg.stream
- Entorno
- node
- Creado
- 2026-08-17T22:43:43Z
Contrato
- fg.stream returns a readable object stream that emits POSIX-normalized relative file path strings and can be consumed directly via async iteration (for await...of).
- fg.stream with { objectMode: true } emits Entry objects containing base name, relative path, and fs.Dirent instances.
- fg.stream throws a synchronous TypeError immediately on invalid or empty pattern inputs rather than emitting an asynchronous stream error.
- fg.stream multiplexes array pattern inputs into a single merged readable stream.
- fg.stream on non-matching patterns completes cleanly with zero emitted chunks.
Archivos
- NOTES.md
- csx.json
- package-lock.json
- package.json
- test/contract.mjs
Código fuente
# fast-glob stream behavior
## Prior Search
`search_known_solution` returned `NO_SAFE_MATCH` for `fast-glob@3.3.3` on symbol `fg.stream`.
## Pinned Release
`fast-glob@3.3.3` pinned in `package.json` and `package-lock.json`.
## Observed Behavior
1. **Async Iteration and Stream Interface**: `fg.stream` returns a readable object stream (backed by a multiplexed stream instance) that implements the async iterator protocol (`Symbol.asyncIterator`), allowing direct iteration using `for await (const chunk of fg.stream(...))` as well as standard stream event listeners (`data`, `end`, `error`).
2. **Path Normalization**: By default, `fg.stream` yields relative path strings with normalized forward-slash (`/`) separators across all platforms.
3. **Object Mode and Metadata**: When `{ objectMode: true }` is supplied, chunks are emitted as structured entry objects containing `name`, `path`, and `dirent` instances with helper methods such as `dirent.isFile()`. When `{ stats: true }` is enabled alongside `objectMode: true`, an `fs.Stats` instance is attached under `stats`.
4. **Synchronous Validation on Invalid Input**: Passing an invalid pattern (such as an empty string `""`, `null`, or numbers) causes `fg.stream` to immediately throw a synchronous `TypeError` (`"Patterns must be a string (non empty) or an array of strings"`) during call evaluation, rather than returning a stream instance that emits an asynchronous stream `'error'` event.
5. **Multi-Pattern Multiplexing**: Providing an array of patterns multiplexes each task stream and merges the results into a single unified stream sequence. Non-matching patterns complete cleanly with zero emitted chunks and trigger the `'end'` event.
{"case":{"caseId":"case:sha256:384d1ef87416f46bc68c7ae3efe9f91a9b05f3573c1eec23a06b422907caf7ef","contract":["fg.stream returns a readable object stream that emits POSIX-normalized relative file path strings and can be consumed directly via async iteration (for await...of).","fg.stream with { objectMode: true } emits Entry objects containing base name, relative path, and fs.Dirent instances.","fg.stream throws a synchronous TypeError immediately on invalid or empty pattern inputs rather than emitting an asynchronous stream error.","fg.stream multiplexes array pattern inputs into a single merged readable stream.","fg.stream on non-matching patterns completes cleanly with zero emitted chunks."],"goal":"Stream matching file paths using fg.stream with async iteration and objectMode entry metadata","kind":"HOW","packages":["pkg:npm/fast-glob@3.3.3"],"schemaVersion":1,"symbols":["fg.stream"]},"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.stream"],"verifierAdapter":"node-typescript@1"}
{
"name": "npm-fast-glob-wanted-3-3-3-fg-stream-1d37707cf408bbd07464aa4c",
"version": "1.0.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "npm-fast-glob-wanted-3-3-3-fg-stream-1d37707cf408bbd07464aa4c",
"version": "1.0.0",
"license": "ISC",
"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"
}
}
}
}
{
"name": "npm-fast-glob-wanted-3-3-3-fg-stream-1d37707cf408bbd07464aa4c",
"version": "1.0.0",
"private": true,
"type": "module",
"scripts": {
"test": "node test/contract.mjs"
},
"dependencies": {
"fast-glob": "3.3.3"
}
}
import assert from 'node:assert/strict';
import fs from 'node:fs';
import fg from 'fast-glob';
const fixtureDir = 'fixtures';
try {
// Setup isolated fixture directory
fs.mkdirSync('fixtures/sub', { recursive: true });
fs.writeFileSync('fixtures/file1.txt', 'hello');
fs.writeFileSync('fixtures/file2.json', '{"ok":true}');
fs.writeFileSync('fixtures/sub/file3.txt', 'world');
// 1. Primary behavior: fg.stream returns an object-mode readable stream that can be consumed as an async iterator
const matches = [];
const stream = fg.stream('**/*', { cwd: fixtureDir, onlyFiles: true });
for await (const entry of stream) {
matches.push(entry);
}
matches.sort();
assert.deepStrictEqual(
matches,
['file1.txt', 'file2.json', 'sub/file3.txt'],
'fg.stream yields forward-slash relative path strings for all matched files'
);
// 2. objectMode: true emits Entry objects with name, path, and dirent methods
const objectEntries = [];
for await (const entry of fg.stream('**/*.txt', { cwd: fixtureDir, objectMode: true, stats: true })) {
objectEntries.push(entry);
}
objectEntries.sort((a, b) => a.path.localeCompare(b.path));
assert.strictEqual(objectEntries.length, 2);
assert.strictEqual(objectEntries[0].name, 'file1.txt');
assert.strictEqual(objectEntries[0].path, 'file1.txt');
assert.strictEqual(objectEntries[0].dirent.isFile(), true);
assert.strictEqual(typeof objectEntries[0].stats.size, 'number');
assert.strictEqual(objectEntries[1].name, 'file3.txt');
assert.strictEqual(objectEntries[1].path, 'sub/file3.txt');
assert.strictEqual(objectEntries[1].dirent.isFile(), true);
assert.strictEqual(typeof objectEntries[1].stats.size, 'number');
// 3. Invalid patterns throw synchronous TypeError immediately rather than emitting an async stream error
assert.throws(
() => fg.stream(''),
{
name: 'TypeError',
message: 'Patterns must be a string (non empty) or an array of strings'
}
);
assert.throws(
() => fg.stream(null),
{
name: 'TypeError',
message: 'Patterns must be a string (non empty) or an array of strings'
}
);
// 4. Multiplexing multiple patterns via array
const multiMatches = [];
for await (const entry of fg.stream(['*.json', 'sub/*.txt'], { cwd: fixtureDir })) {
multiMatches.push(entry);
}
multiMatches.sort();
assert.deepStrictEqual(multiMatches, ['file2.json', 'sub/file3.txt']);
// 5. Non-matching pattern stream completes cleanly with 0 items
const noMatches = [];
for await (const entry of fg.stream('*.nonexistent', { cwd: fixtureDir })) {
noMatches.push(entry);
}
assert.strictEqual(noMatches.length, 0);
} finally {
// Cleanup fixture directory
fs.rmSync(fixtureDir, { recursive: true, force: true });
}