@cmflow/source-pack 0.0.0-stage → 3.19.0

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.
Files changed (37) hide show
  1. package/README.md +183 -2
  2. package/dist/GitRepository-VTAWT6j4.mjs +151 -0
  3. package/dist/GitRepository-VTAWT6j4.mjs.map +1 -0
  4. package/dist/bin/source-pack.d.mts +1 -0
  5. package/dist/bin/source-pack.mjs +3038 -0
  6. package/dist/bin/source-pack.mjs.map +1 -0
  7. package/dist/buildSourcePack-CaaMZ_tw.mjs +11280 -0
  8. package/dist/buildSourcePack-CaaMZ_tw.mjs.map +1 -0
  9. package/dist/buildSourcePack-DIp8G_uL.mjs +3 -0
  10. package/dist/constants-DkiLCuIK.mjs +25 -0
  11. package/dist/constants-DkiLCuIK.mjs.map +1 -0
  12. package/dist/defaults-BJs7a37e.mjs +52 -0
  13. package/dist/defaults-BJs7a37e.mjs.map +1 -0
  14. package/dist/index.d.mts +397 -0
  15. package/dist/index.mjs +73 -0
  16. package/dist/index.mjs.map +1 -0
  17. package/dist/initConfig-ByGsbShR.mjs +185 -0
  18. package/dist/initConfig-ByGsbShR.mjs.map +1 -0
  19. package/dist/loadConfig-CNrL90dq.mjs +224 -0
  20. package/dist/loadConfig-CNrL90dq.mjs.map +1 -0
  21. package/dist/logger-D1XGzzjT.mjs +15 -0
  22. package/dist/logger-D1XGzzjT.mjs.map +1 -0
  23. package/dist/packageVersion-B0749hF6.mjs +4646 -0
  24. package/dist/packageVersion-B0749hF6.mjs.map +1 -0
  25. package/dist/projectIdentity-F97vs1H-.mjs +3331 -0
  26. package/dist/projectIdentity-F97vs1H-.mjs.map +1 -0
  27. package/dist/publishSourcePack-Dj1cdWfT.mjs +3 -0
  28. package/dist/publishSourcePack-xNr9RBgv.mjs +296 -0
  29. package/dist/publishSourcePack-xNr9RBgv.mjs.map +1 -0
  30. package/dist/token-DMtao22Y.mjs +59 -0
  31. package/dist/token-DMtao22Y.mjs.map +1 -0
  32. package/dist/token-util-C3JYrW4-.mjs +498 -0
  33. package/dist/token-util-C3JYrW4-.mjs.map +1 -0
  34. package/dist/token-util-CbjlbIno.mjs +5 -0
  35. package/package.json +44 -3
  36. package/templates/circleci-job.yml +39 -0
  37. package/templates/gitlab-ci.yml +30 -0
package/README.md CHANGED
@@ -1,3 +1,184 @@
1
- # Temporary Holding Version
1
+ <div style="text-align: center" align="center">
2
+ <img src="https://ns.clubmed.com/fbs/RWD/branding2023/Logo/MicrosoftTeams-image%20(9).png" width="200" alt="Club Med"/>
3
+ </div>
2
4
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
5
+ <div align="center">
6
+ <h1>@cmflow/source-pack</h1>
7
+ <hr />
8
+
9
+ [![npm version](https://badge.fury.io/js/%40cmflow%2Fsource-pack.svg)](https://badge.fury.io/js/%40cmflow%2Fsource-pack)
10
+ [![code style: oxfmt](https://img.shields.io/badge/code_style-oxfmt-ef4444.svg?style=flat-square)](https://oxc.rs/docs/guide/usage/formatter)
11
+
12
+ </div>
13
+
14
+ `source-pack` builds, at each production release of a project hosted on GitHub or GitLab, a **versioned index of its code**
15
+ (chunks + embeddings + optional attachments + manifest) and publishes it on the release of the tag. The Dataviz loads it with
16
+ `readSourcePack()` to answer `source_search` on any production version, without a local checkout.
17
+
18
+ The package is generic: everything that depends on a project lives in its `source-pack.config.ts`.
19
+
20
+ ## Commands
21
+
22
+ ```bash
23
+ npx @cmflow/source-pack init # create ./source-pack.config.ts
24
+ npx @cmflow/source-pack build # index HEAD, version from package.json
25
+ npx @cmflow/source-pack build --tag version-1.2.3 # index the tag, version extracted from it
26
+ npx @cmflow/source-pack publish # upload the last build on the release of its tag
27
+ ```
28
+
29
+ Global option: `-c, --config <path>` (default `./source-pack.config.ts`). Paths of the config are resolved against the directory
30
+ the command is run from. The config may be a `.ts` file (loaded with `tsx`) or a `.mjs` file. It can import `defineConfig` from
31
+ `@cmflow/source-pack` even when the package is not installed in the project (`npx` usage): the import resolves to the running CLI.
32
+
33
+ | Command | Options |
34
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
35
+ | `init` | `--force` overwrites an existing file. `repository` is deduced from the `origin` remote; exclusions are pre-filled for the detected project type (node, python, jvm, go). |
36
+ | `build` | `--ref <commit-ish>` (default: `--tag`, otherwise `HEAD`), `--tag <tag>`, `--release-version <v>` (default: from `--tag` with `publish.tag`, otherwise `version` of `package.json` at the ref), `--skip-embeddings`, `--dry-run` (no LiteLLM call, nothing written, sizes estimated). |
37
+ | `publish` | `--archive <path>` (default: last build of `outputDir`), `--dry-run` (logs the planned upload, no HTTP call). |
38
+
39
+ Secrets are read from the environment only, never from the config, and are never logged nor written to the pack:
40
+
41
+ | Variable | Used by |
42
+ | ----------------- | ------------------------------------------------------------------------- |
43
+ | `LITELLM_API_KEY` | `build` (embeddings; the name can be changed with `embedding.apiKeyEnv`) |
44
+ | `GITHUB_TOKEN` | `publish` on a GitHub repository (`contents: write`) |
45
+ | `GITLAB_TOKEN` | `publish` on a GitLab project (`api` scope; falls back to `CI_JOB_TOKEN`) |
46
+
47
+ ## Configuration
48
+
49
+ ```ts
50
+ import { defineConfig } from "@cmflow/source-pack";
51
+
52
+ export default defineConfig({
53
+ outputDir: "./tmp/source-pack",
54
+ repository: { provider: "github", owner: "ClubMediterranee", name: "digital-api" },
55
+ // GitLab: { provider: "gitlab", projectId: "group/project" (or 1234), apiUrl: "https://gitlab.example.com/api/v4" }
56
+ sources: {
57
+ include: ["**/*.{ts,tsx,js,json,yaml,yml,md,feature}"],
58
+ exclude: ["mock/**", "test/functionnal/**", "package-lock.json", "coverage/**", "dist/**"],
59
+ maxFileBytes: 1048576
60
+ },
61
+ chunking: { lines: 100, overlap: 15 },
62
+ embedding: {
63
+ baseUrl: "https://apim-prdaiplatform-frc.azure-api.net/litellm-api",
64
+ model: "text-embedding-3-small-gmdt",
65
+ fallbackModels: ["text-embedding-3-small-swc-gmdt", "text-embedding-3-small-eus2-gmdt"],
66
+ referenceModel: "text-embedding-3-small",
67
+ dimensions: 1536,
68
+ batchSize: 64,
69
+ concurrency: 4
70
+ },
71
+ attachments: ["tools/build/cache-layers-adjacency-list-reference.json"],
72
+ publish: {
73
+ tag: "version-{version}",
74
+ assetName: "source-pack-{version}.tar.gz"
75
+ }
76
+ });
77
+ ```
78
+
79
+ - Only files **tracked by Git at the indexed commit** are read (from the Git objects, not the working tree: the result does not depend
80
+ on the checkout, line endings or the OS). Binary files (NUL byte in the first 8000 bytes), symlinks, submodules and files above
81
+ `maxFileBytes` are skipped. Test files (`*.spec.*`, `*.test.*` and their Python, Go and JVM equivalents) are excluded by
82
+ default: they double the index size without describing production behavior.
83
+ - Globs use minimatch with dot files. Defaults when `sources` is omitted: common text extensions, excluding tests, `node_modules`, `dist`,
84
+ `build`, `coverage` and lockfiles.
85
+ - Chunks are windows of `lines` lines advancing by `lines - overlap`; blank windows are skipped;
86
+ `id = sha256("<path>:<startLine>:<text>")` — identical to the state-control indexer.
87
+ - Embeddings use the OpenAI-compatible `/v1/embeddings` endpoint of LiteLLM (`/v1` is appended to `baseUrl`), in batches of
88
+ `batchSize`, `concurrency` (4) batches at a time, each retried `maxRetries` (3) times before switching to the next `fallbackModels` alias. The embedded text of a chunk is
89
+ `"<path>\n<text>"` truncated to `maxInputChars` (12000). The manifest records the **reference model** (`referenceModel`, default:
90
+ `model`): set it to the public model behind the gateway aliases so the manifest never names the regional alias that answered.
91
+ - Omit `embedding` (or use `--skip-embeddings`) for a lexical-only pack.
92
+ - `attachments` are copied verbatim (they do not need to match `sources`).
93
+ - `publish.createRelease` (default `false`) creates the release when the tag has none; by default the release tool owns releases and a
94
+ missing release is an error.
95
+
96
+ An invalid config is rejected with one line per field, e.g.:
97
+
98
+ ```
99
+ Invalid source-pack config (/repo/source-pack.config.ts):
100
+ - repository.provider: expected "github" or "gitlab" (received "bitbucket")
101
+ - chunking.overlap: expected a value lower than chunking.lines
102
+ ```
103
+
104
+ ## Pack format (`source-pack-<version>.tar.gz`)
105
+
106
+ | Entry | Content |
107
+ | -------------------- | ------------------------------------------------------------------------------------------------------------------- |
108
+ | `manifest.json` | Project, version, tag, ref, SHA, dates, chunking version + config fingerprint, embedding model, counts, attachments |
109
+ | `chunks.jsonl.gz` | One JSON object per line: `{ id, path, startLine, endLine, text }` (lines are 1-based and inclusive) |
110
+ | `embeddings.f32` | `chunks.count × dimensions` little-endian float32, in chunk order (absent without embeddings) |
111
+ | `attachments/<path>` | Files declared in `attachments` |
112
+
113
+ `manifest.project.id` (`github:<owner>/<repo>` or `gitlab:<project>`), `sha`, `config.fingerprint` (sha256 of `sources` +
114
+ `chunking` + chunking format version) and `embedding.model`/`dimensions` uniquely identify the pack content.
115
+
116
+ ### Publishing
117
+
118
+ The destination follows `repository.provider`:
119
+
120
+ - GitHub: asset of the GitHub release of the tag; an asset with the same name is deleted first (idempotent).
121
+ - GitLab: `PUT /projects/:id/packages/generic/<packageName>/<version>/<assetName>` (Generic Package Registry, `packageName`
122
+ defaults to `source-pack`), older files with the same name in that package version are deleted, then a `package` link with the same
123
+ name is created or updated on the GitLab release of the tag.
124
+
125
+ ## Reading a pack (Dataviz)
126
+
127
+ ```ts
128
+ import { embeddingInput, readSourcePack } from "@cmflow/source-pack";
129
+
130
+ const pack = await readSourcePack("./source-pack-0.3503.0.tar.gz"); // or the downloaded bytes (Uint8Array)
131
+
132
+ pack.manifest.sha;
133
+ pack.chunks[0]; // { id, path, startLine, endLine, text }
134
+ pack.getEmbedding(0); // Float32Array(1536) | null
135
+ pack.attachments.get("tools/build/cache-layers-adjacency-list-reference.json");
136
+ ```
137
+
138
+ `readSourcePack` checks the format version, the chunk count and the embeddings size. Embed queries with the same
139
+ `manifest.embedding.model`/`dimensions`; use `embeddingInput()` to re-embed chunks consistently.
140
+
141
+ ## Onboarding a project
142
+
143
+ 1. In the project root: `npx @cmflow/source-pack init`, then adjust `sources.exclude` (mocks, fixtures, generated data, vendored
144
+ code…) and `attachments`.
145
+ 2. Check the result locally: `npx @cmflow/source-pack build --dry-run` (chunk count and estimated size), then
146
+ `LITELLM_API_KEY=… npx @cmflow/source-pack build` and `npx @cmflow/source-pack publish --dry-run`.
147
+ 3. Commit `source-pack.config.ts` and add `tmp/source-pack` to `.gitignore`.
148
+ 4. Add the job to the **production merge pipeline only**, after the job that creates the tag and its release (snippets below). It must
149
+ not be required by any other job so that a failure never blocks the release; rerunning it republishes the pack.
150
+ 5. Provide the secrets: `LITELLM_API_KEY` and `GITHUB_TOKEN` (CircleCI shared context `source-pack`) or `LITELLM_API_KEY` and
151
+ `GITLAB_TOKEN` (masked GitLab CI/CD variables).
152
+ 6. Enable the project in the « Source pack » tab of the Dataviz.
153
+
154
+ ### CircleCI
155
+
156
+ Copy [`templates/circleci-job.yml`](./templates/circleci-job.yml) under `jobs:` and add to the production workflow:
157
+
158
+ ```yaml
159
+ - source-pack:
160
+ requires: [cm-release-prod]
161
+ filters:
162
+ branches:
163
+ only: /^production$/
164
+ context: source-pack
165
+ ```
166
+
167
+ The job resolves the first `version-*` tag containing the pipeline commit (the release commit created by `cmrelease`), then runs
168
+ `build --tag "$TAG"` and `publish`.
169
+
170
+ ### GitLab CI
171
+
172
+ ```yaml
173
+ include:
174
+ - remote: "https://raw.githubusercontent.com/ClubMediterranee/cmflow/master/packages/source-pack/templates/gitlab-ci.yml"
175
+
176
+ source-pack:
177
+ extends: .source-pack
178
+ needs: ["release"]
179
+ rules:
180
+ - if: $CI_COMMIT_BRANCH == "production"
181
+ ```
182
+
183
+ The `.source-pack` template ([`templates/gitlab-ci.yml`](./templates/gitlab-ci.yml)) is `allow_failure: true` and accepts
184
+ `SOURCE_PACK_VERSION` and `SOURCE_PACK_TAG_PATTERN` variables.
@@ -0,0 +1,151 @@
1
+ import { execFile, spawn } from "node:child_process";
2
+ import { promisify } from "node:util";
3
+
4
+ //#region src/git/parseLsTree.ts
5
+ /** Parses `git ls-tree -r -z --long` output, keeping regular files only (no symlinks, no submodules). */
6
+ function parseLsTree(output) {
7
+ return output.split("\0").filter(Boolean).flatMap((record) => {
8
+ const tab = record.indexOf(" ");
9
+ const [mode, type, object, size] = record.slice(0, tab).trim().split(/\s+/);
10
+ if (type !== "blob" || !(mode === "100644" || mode === "100755")) return [];
11
+ return [{
12
+ mode,
13
+ object,
14
+ size: Number(size),
15
+ path: record.slice(tab + 1)
16
+ }];
17
+ });
18
+ }
19
+
20
+ //#endregion
21
+ //#region src/git/GitRepository.ts
22
+ const execFileAsync = promisify(execFile);
23
+ /**
24
+ * Read-only access to the Git objects of a repository: everything is read at a commit, never from the working tree,
25
+ * so the result does not depend on the checkout state, line-ending conversion or the OS.
26
+ */
27
+ var GitRepository = class GitRepository {
28
+ #trees = /* @__PURE__ */ new Map();
29
+ constructor(root) {
30
+ this.root = root;
31
+ }
32
+ static async open(cwd) {
33
+ try {
34
+ const { stdout } = await execFileAsync("git", ["rev-parse", "--show-toplevel"], { cwd });
35
+ return new GitRepository(stdout.trim());
36
+ } catch {
37
+ throw new Error(`${cwd} is not inside a Git repository`);
38
+ }
39
+ }
40
+ async git(args) {
41
+ const { stdout } = await execFileAsync("git", args, {
42
+ cwd: this.root,
43
+ maxBuffer: 536870912
44
+ });
45
+ return stdout;
46
+ }
47
+ async resolveCommit(ref) {
48
+ try {
49
+ return (await this.git([
50
+ "rev-parse",
51
+ "--verify",
52
+ "--end-of-options",
53
+ `${ref}^{commit}`
54
+ ])).trim();
55
+ } catch {
56
+ throw new Error(`Git ref "${ref}" not found (fetch the tag or branch first)`);
57
+ }
58
+ }
59
+ async commitDate(sha) {
60
+ return new Date((await this.git([
61
+ "show",
62
+ "-s",
63
+ "--format=%cI",
64
+ sha
65
+ ])).trim()).toISOString();
66
+ }
67
+ /** Regular files tracked at `sha` (cached per commit). */
68
+ listFiles(sha) {
69
+ let tree = this.#trees.get(sha);
70
+ if (!tree) {
71
+ tree = this.git([
72
+ "ls-tree",
73
+ "-r",
74
+ "-z",
75
+ "--long",
76
+ "--full-tree",
77
+ sha
78
+ ]).then(parseLsTree);
79
+ this.#trees.set(sha, tree);
80
+ }
81
+ return tree;
82
+ }
83
+ async remoteUrl(remote = "origin") {
84
+ try {
85
+ return (await this.git([
86
+ "remote",
87
+ "get-url",
88
+ remote
89
+ ])).trim() || void 0;
90
+ } catch {
91
+ return;
92
+ }
93
+ }
94
+ /** Reads `path` at `sha`; undefined when the file is not tracked at that commit. */
95
+ async readFile(sha, path) {
96
+ const entry = (await this.listFiles(sha)).find((file) => file.path === path);
97
+ if (!entry) return;
98
+ return (await this.readBlobs([entry.object])).get(entry.object);
99
+ }
100
+ /** Reads many blobs through a single `git cat-file --batch` process. */
101
+ readBlobs(objects) {
102
+ const unique = [...new Set(objects)];
103
+ const blobs = /* @__PURE__ */ new Map();
104
+ if (!unique.length) return Promise.resolve(blobs);
105
+ return new Promise((resolve, reject) => {
106
+ const child = spawn("git", ["cat-file", "--batch"], {
107
+ cwd: this.root,
108
+ stdio: [
109
+ "pipe",
110
+ "pipe",
111
+ "pipe"
112
+ ]
113
+ });
114
+ let buffer = Buffer.alloc(0);
115
+ let stderr = "";
116
+ child.stdout.on("data", (data) => {
117
+ buffer = buffer.length ? Buffer.concat([buffer, data]) : data;
118
+ for (;;) {
119
+ const newline = buffer.indexOf(10);
120
+ if (newline < 0) return;
121
+ const [object, type, size] = buffer.subarray(0, newline).toString("utf8").split(" ");
122
+ if (type === "missing" || size === void 0) {
123
+ child.kill();
124
+ reject(/* @__PURE__ */ new Error(`Git object ${object} is missing`));
125
+ return;
126
+ }
127
+ const length = Number(size);
128
+ if (buffer.length < newline + 1 + length + 1) return;
129
+ blobs.set(object, Buffer.from(buffer.subarray(newline + 1, newline + 1 + length)));
130
+ buffer = buffer.subarray(newline + 1 + length + 1);
131
+ }
132
+ });
133
+ child.stderr.on("data", (data) => {
134
+ stderr += data.toString("utf8");
135
+ });
136
+ child.on("error", reject);
137
+ child.on("close", (code) => {
138
+ if (code !== 0 && blobs.size !== unique.length) {
139
+ reject(/* @__PURE__ */ new Error(`git cat-file failed (${code}): ${stderr.trim()}`));
140
+ return;
141
+ }
142
+ resolve(blobs);
143
+ });
144
+ child.stdin.end(`${unique.join("\n")}\n`);
145
+ });
146
+ }
147
+ };
148
+
149
+ //#endregion
150
+ export { GitRepository as t };
151
+ //# sourceMappingURL=GitRepository-VTAWT6j4.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"GitRepository-VTAWT6j4.mjs","names":["#trees"],"sources":["../src/git/parseLsTree.ts","../src/git/GitRepository.ts"],"sourcesContent":["import type { GitTreeEntry } from \"./interfaces\";\n\n/** Parses `git ls-tree -r -z --long` output, keeping regular files only (no symlinks, no submodules). */\nexport function parseLsTree(output: string): GitTreeEntry[] {\n return output\n .split(\"\\0\")\n .filter(Boolean)\n .flatMap((record) => {\n const tab = record.indexOf(\"\\t\");\n const [mode, type, object, size] = record.slice(0, tab).trim().split(/\\s+/) as [string, string, string, string];\n\n if (type !== \"blob\" || !(mode === \"100644\" || mode === \"100755\")) {\n return [];\n }\n\n return [{ mode, object, size: Number(size), path: record.slice(tab + 1) }];\n });\n}\n","import { execFile, spawn } from \"node:child_process\";\nimport { promisify } from \"node:util\";\nimport type { GitTreeEntry } from \"./interfaces\";\nimport { parseLsTree } from \"./parseLsTree\";\n\nconst execFileAsync = promisify(execFile);\n\n/**\n * Read-only access to the Git objects of a repository: everything is read at a commit, never from the working tree,\n * so the result does not depend on the checkout state, line-ending conversion or the OS.\n */\nexport class GitRepository {\n readonly #trees = new Map<string, Promise<GitTreeEntry[]>>();\n\n private constructor(readonly root: string) {}\n\n static async open(cwd: string): Promise<GitRepository> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"rev-parse\", \"--show-toplevel\"], { cwd });\n\n return new GitRepository(stdout.trim());\n } catch {\n throw new Error(`${cwd} is not inside a Git repository`);\n }\n }\n\n async git(args: string[]): Promise<string> {\n const { stdout } = await execFileAsync(\"git\", args, { cwd: this.root, maxBuffer: 512 * 1024 * 1024 });\n\n return stdout;\n }\n\n async resolveCommit(ref: string): Promise<string> {\n try {\n return (await this.git([\"rev-parse\", \"--verify\", \"--end-of-options\", `${ref}^{commit}`])).trim();\n } catch {\n throw new Error(`Git ref \"${ref}\" not found (fetch the tag or branch first)`);\n }\n }\n\n async commitDate(sha: string): Promise<string> {\n return new Date((await this.git([\"show\", \"-s\", \"--format=%cI\", sha])).trim()).toISOString();\n }\n\n /** Regular files tracked at `sha` (cached per commit). */\n listFiles(sha: string): Promise<GitTreeEntry[]> {\n let tree = this.#trees.get(sha);\n\n if (!tree) {\n tree = this.git([\"ls-tree\", \"-r\", \"-z\", \"--long\", \"--full-tree\", sha]).then(parseLsTree);\n this.#trees.set(sha, tree);\n }\n\n return tree;\n }\n\n async remoteUrl(remote = \"origin\"): Promise<string | undefined> {\n try {\n return (await this.git([\"remote\", \"get-url\", remote])).trim() || undefined;\n } catch {\n return undefined;\n }\n }\n\n /** Reads `path` at `sha`; undefined when the file is not tracked at that commit. */\n async readFile(sha: string, path: string): Promise<Buffer | undefined> {\n const entry = (await this.listFiles(sha)).find((file) => file.path === path);\n\n if (!entry) {\n return undefined;\n }\n\n return (await this.readBlobs([entry.object])).get(entry.object);\n }\n\n /** Reads many blobs through a single `git cat-file --batch` process. */\n readBlobs(objects: string[]): Promise<Map<string, Buffer>> {\n const unique = [...new Set(objects)];\n const blobs = new Map<string, Buffer>();\n\n if (!unique.length) {\n return Promise.resolve(blobs);\n }\n\n return new Promise((resolve, reject) => {\n const child = spawn(\"git\", [\"cat-file\", \"--batch\"], { cwd: this.root, stdio: [\"pipe\", \"pipe\", \"pipe\"] });\n let buffer: Buffer = Buffer.alloc(0);\n let stderr = \"\";\n\n child.stdout.on(\"data\", (data: Buffer) => {\n buffer = buffer.length ? Buffer.concat([buffer, data]) : data;\n\n for (;;) {\n const newline = buffer.indexOf(10);\n\n if (newline < 0) {\n return;\n }\n\n const header = buffer.subarray(0, newline).toString(\"utf8\");\n const [object, type, size] = header.split(\" \");\n\n if (type === \"missing\" || size === undefined) {\n child.kill();\n reject(new Error(`Git object ${object} is missing`));\n return;\n }\n\n const length = Number(size);\n\n if (buffer.length < newline + 1 + length + 1) {\n return;\n }\n\n blobs.set(object!, Buffer.from(buffer.subarray(newline + 1, newline + 1 + length)));\n buffer = buffer.subarray(newline + 1 + length + 1);\n }\n });\n child.stderr.on(\"data\", (data: Buffer) => {\n stderr += data.toString(\"utf8\");\n });\n child.on(\"error\", reject);\n child.on(\"close\", (code) => {\n if (code !== 0 && blobs.size !== unique.length) {\n reject(new Error(`git cat-file failed (${code}): ${stderr.trim()}`));\n return;\n }\n\n resolve(blobs);\n });\n\n child.stdin.end(`${unique.join(\"\\n\")}\\n`);\n });\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {}