@cmflow/source-pack 0.0.0-stage → 3.20.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.
- package/README.md +183 -2
- package/dist/GitRepository-VTAWT6j4.mjs +151 -0
- package/dist/GitRepository-VTAWT6j4.mjs.map +1 -0
- package/dist/bin/source-pack.d.mts +1 -0
- package/dist/bin/source-pack.mjs +3038 -0
- package/dist/bin/source-pack.mjs.map +1 -0
- package/dist/buildSourcePack-CaaMZ_tw.mjs +11280 -0
- package/dist/buildSourcePack-CaaMZ_tw.mjs.map +1 -0
- package/dist/buildSourcePack-DIp8G_uL.mjs +3 -0
- package/dist/constants-DkiLCuIK.mjs +25 -0
- package/dist/constants-DkiLCuIK.mjs.map +1 -0
- package/dist/defaults-BJs7a37e.mjs +52 -0
- package/dist/defaults-BJs7a37e.mjs.map +1 -0
- package/dist/index.d.mts +397 -0
- package/dist/index.mjs +73 -0
- package/dist/index.mjs.map +1 -0
- package/dist/initConfig-ByGsbShR.mjs +185 -0
- package/dist/initConfig-ByGsbShR.mjs.map +1 -0
- package/dist/loadConfig-CNrL90dq.mjs +224 -0
- package/dist/loadConfig-CNrL90dq.mjs.map +1 -0
- package/dist/logger-D1XGzzjT.mjs +15 -0
- package/dist/logger-D1XGzzjT.mjs.map +1 -0
- package/dist/packageVersion-B0749hF6.mjs +4646 -0
- package/dist/packageVersion-B0749hF6.mjs.map +1 -0
- package/dist/projectIdentity-F97vs1H-.mjs +3331 -0
- package/dist/projectIdentity-F97vs1H-.mjs.map +1 -0
- package/dist/publishSourcePack-Dj1cdWfT.mjs +3 -0
- package/dist/publishSourcePack-xNr9RBgv.mjs +296 -0
- package/dist/publishSourcePack-xNr9RBgv.mjs.map +1 -0
- package/dist/token-DMtao22Y.mjs +59 -0
- package/dist/token-DMtao22Y.mjs.map +1 -0
- package/dist/token-util-C3JYrW4-.mjs +498 -0
- package/dist/token-util-C3JYrW4-.mjs.map +1 -0
- package/dist/token-util-CbjlbIno.mjs +5 -0
- package/package.json +45 -3
- package/templates/circleci-job.yml +39 -0
- package/templates/gitlab-ci.yml +30 -0
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import { a as DEFAULT_ASSET_NAME_TEMPLATE, c as DEFAULT_GITLAB_API_URL, d as DEFAULT_TAG_TEMPLATE, h as GITLAB_TOKEN_ENV, m as GITHUB_TOKEN_ENV, s as DEFAULT_GITHUB_API_URL, u as DEFAULT_OUTPUT_DIR } from "./constants-DkiLCuIK.mjs";
|
|
2
|
+
import { a as DEFAULT_INCLUDE, c as LOCKFILES_BY_ECOSYSTEM, i as DEFAULT_EXCLUDE, l as NODE_DEPENDENCY_DIRS, n as DEFAULT_API_KEY_ENV, r as DEFAULT_DIMENSIONS, t as BUILD_OUTPUT_DIRS, u as TEST_FILES_BY_ECOSYSTEM } from "./defaults-BJs7a37e.mjs";
|
|
3
|
+
import { t as GitRepository } from "./GitRepository-VTAWT6j4.mjs";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { existsSync } from "node:fs";
|
|
6
|
+
import { access, mkdir, writeFile } from "node:fs/promises";
|
|
7
|
+
|
|
8
|
+
//#region src/git/parseRemoteUrl.ts
|
|
9
|
+
/**
|
|
10
|
+
* Parses an SSH (`git@host:owner/name.git`, `ssh://git@host:22/owner/name.git`) or HTTPS remote URL.
|
|
11
|
+
* GitLab owners may contain subgroups (`group/sub`). Returns undefined for unknown hosts.
|
|
12
|
+
*/
|
|
13
|
+
function parseRemoteUrl(remote) {
|
|
14
|
+
const trimmed = remote.trim();
|
|
15
|
+
const scp = /^(?:[\w.-]+@)?([\w.-]+):(?!\/\/)(.+)$/.exec(trimmed);
|
|
16
|
+
let host;
|
|
17
|
+
let pathname;
|
|
18
|
+
if (scp && !/^[a-z]+:\/\//i.test(trimmed)) {
|
|
19
|
+
host = scp[1];
|
|
20
|
+
pathname = scp[2];
|
|
21
|
+
} else try {
|
|
22
|
+
const url = new URL(trimmed);
|
|
23
|
+
host = url.hostname;
|
|
24
|
+
pathname = url.pathname;
|
|
25
|
+
} catch {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const segments = pathname.replace(/\.git\/?$/, "").split("/").filter(Boolean);
|
|
29
|
+
if (segments.length < 2) return;
|
|
30
|
+
const provider = /(^|\.)github\./i.test(host) ? "github" : /gitlab/i.test(host) ? "gitlab" : void 0;
|
|
31
|
+
if (!provider) return;
|
|
32
|
+
return {
|
|
33
|
+
provider,
|
|
34
|
+
host,
|
|
35
|
+
owner: segments.slice(0, -1).join("/"),
|
|
36
|
+
name: segments.at(-1)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
//#endregion
|
|
41
|
+
//#region src/init/detectProjectType.ts
|
|
42
|
+
const MARKERS = [
|
|
43
|
+
["node", ["package.json"]],
|
|
44
|
+
["python", [
|
|
45
|
+
"pyproject.toml",
|
|
46
|
+
"requirements.txt",
|
|
47
|
+
"setup.py"
|
|
48
|
+
]],
|
|
49
|
+
["jvm", [
|
|
50
|
+
"pom.xml",
|
|
51
|
+
"build.gradle",
|
|
52
|
+
"build.gradle.kts"
|
|
53
|
+
]],
|
|
54
|
+
["go", ["go.mod"]]
|
|
55
|
+
];
|
|
56
|
+
function detectProjectType(directory) {
|
|
57
|
+
return MARKERS.find(([, files]) => files.some((file) => existsSync(path.join(directory, file))))?.[0] ?? "generic";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
//#endregion
|
|
61
|
+
//#region src/init/projectPresets.ts
|
|
62
|
+
const PROJECT_PRESETS = {
|
|
63
|
+
node: {
|
|
64
|
+
include: ["**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs,json,yaml,yml,md,feature,graphql}"],
|
|
65
|
+
exclude: [
|
|
66
|
+
...NODE_DEPENDENCY_DIRS,
|
|
67
|
+
...BUILD_OUTPUT_DIRS,
|
|
68
|
+
...LOCKFILES_BY_ECOSYSTEM.node,
|
|
69
|
+
...TEST_FILES_BY_ECOSYSTEM.node
|
|
70
|
+
]
|
|
71
|
+
},
|
|
72
|
+
python: {
|
|
73
|
+
include: ["**/*.{py,pyi,toml,cfg,ini,json,yaml,yml,md}"],
|
|
74
|
+
exclude: [
|
|
75
|
+
"**/.venv/**",
|
|
76
|
+
"**/venv/**",
|
|
77
|
+
"**/__pycache__/**",
|
|
78
|
+
...BUILD_OUTPUT_DIRS,
|
|
79
|
+
...LOCKFILES_BY_ECOSYSTEM.python,
|
|
80
|
+
...TEST_FILES_BY_ECOSYSTEM.python
|
|
81
|
+
]
|
|
82
|
+
},
|
|
83
|
+
jvm: {
|
|
84
|
+
include: ["**/*.{java,kt,kts,groovy,gradle,xml,properties,json,yaml,yml,md}"],
|
|
85
|
+
exclude: [
|
|
86
|
+
"**/target/**",
|
|
87
|
+
"**/.gradle/**",
|
|
88
|
+
...BUILD_OUTPUT_DIRS,
|
|
89
|
+
...LOCKFILES_BY_ECOSYSTEM.jvm,
|
|
90
|
+
...TEST_FILES_BY_ECOSYSTEM.jvm
|
|
91
|
+
]
|
|
92
|
+
},
|
|
93
|
+
go: {
|
|
94
|
+
include: ["**/*.{go,mod,json,yaml,yml,md,sql}"],
|
|
95
|
+
exclude: [
|
|
96
|
+
"**/vendor/**",
|
|
97
|
+
"**/bin/**",
|
|
98
|
+
...BUILD_OUTPUT_DIRS,
|
|
99
|
+
...LOCKFILES_BY_ECOSYSTEM.go,
|
|
100
|
+
...TEST_FILES_BY_ECOSYSTEM.go
|
|
101
|
+
]
|
|
102
|
+
},
|
|
103
|
+
generic: {
|
|
104
|
+
include: DEFAULT_INCLUDE,
|
|
105
|
+
exclude: DEFAULT_EXCLUDE
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
//#endregion
|
|
110
|
+
//#region src/init/generateConfigSource.ts
|
|
111
|
+
function list(values, indent) {
|
|
112
|
+
return `[\n${values.map((value) => `${indent} ${JSON.stringify(value)}`).join(",\n")}\n${indent}]`;
|
|
113
|
+
}
|
|
114
|
+
function apiUrlLine(remote) {
|
|
115
|
+
if (remote?.provider === "gitlab") return remote.host === "gitlab.com" ? `// apiUrl: ${JSON.stringify(DEFAULT_GITLAB_API_URL)}` : `apiUrl: ${JSON.stringify(`https://${remote.host}/api/v4`)}`;
|
|
116
|
+
return remote && remote.host !== "github.com" ? `apiUrl: ${JSON.stringify(`https://${remote.host}/api/v3`)}` : `// apiUrl: ${JSON.stringify(DEFAULT_GITHUB_API_URL)}`;
|
|
117
|
+
}
|
|
118
|
+
function repositoryBlock(remote) {
|
|
119
|
+
const fields = [
|
|
120
|
+
`provider: ${JSON.stringify(remote?.provider ?? "github")}`,
|
|
121
|
+
`owner: ${JSON.stringify(remote?.owner ?? "TODO-owner")}`,
|
|
122
|
+
`name: ${JSON.stringify(remote?.name ?? "TODO-repository")}`
|
|
123
|
+
];
|
|
124
|
+
const apiUrl = apiUrlLine(remote);
|
|
125
|
+
return `{\n ${(apiUrl.startsWith("//") ? [fields.join(",\n "), apiUrl] : [[...fields, apiUrl].join(",\n ")]).join("\n ")}\n }`;
|
|
126
|
+
}
|
|
127
|
+
/** Source of a default `source-pack.config.ts`, deduced from the Git remote and the project type. */
|
|
128
|
+
function generateConfigSource({ remote, projectType }) {
|
|
129
|
+
const preset = PROJECT_PRESETS[projectType];
|
|
130
|
+
return `import { defineConfig } from "@cmflow/source-pack";
|
|
131
|
+
|
|
132
|
+
// Secrets are read from the environment only: ${DEFAULT_API_KEY_ENV} (embeddings), ${remote?.provider === "gitlab" ? GITLAB_TOKEN_ENV : GITHUB_TOKEN_ENV} (publish).
|
|
133
|
+
export default defineConfig({
|
|
134
|
+
outputDir: ${JSON.stringify(DEFAULT_OUTPUT_DIR)},
|
|
135
|
+
repository: ${repositoryBlock(remote)},
|
|
136
|
+
sources: {
|
|
137
|
+
include: ${list(preset.include, " ")},
|
|
138
|
+
// Adjust to the project: generated data, fixtures, mocks, vendored code...
|
|
139
|
+
exclude: ${list(preset.exclude, " ")}
|
|
140
|
+
},
|
|
141
|
+
chunking: { lines: ${100}, overlap: ${15} },
|
|
142
|
+
embedding: {
|
|
143
|
+
baseUrl: "https://apim-prdaiplatform-frc.azure-api.net/litellm-api",
|
|
144
|
+
model: "text-embedding-3-small-gmdt",
|
|
145
|
+
fallbackModels: ["text-embedding-3-small-swc-gmdt", "text-embedding-3-small-eus2-gmdt"],
|
|
146
|
+
referenceModel: "text-embedding-3-small",
|
|
147
|
+
dimensions: ${DEFAULT_DIMENSIONS},
|
|
148
|
+
batchSize: ${64}
|
|
149
|
+
},
|
|
150
|
+
attachments: [],
|
|
151
|
+
publish: {
|
|
152
|
+
tag: ${JSON.stringify(DEFAULT_TAG_TEMPLATE)},
|
|
153
|
+
assetName: ${JSON.stringify(DEFAULT_ASSET_NAME_TEMPLATE)}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
`;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
//#endregion
|
|
160
|
+
//#region src/commands/initConfig.ts
|
|
161
|
+
/** Writes a default `source-pack.config.ts` next to `configPath`, deduced from the Git remote `origin`. */
|
|
162
|
+
async function initConfig({ configPath, force = false }) {
|
|
163
|
+
const directory = path.dirname(configPath);
|
|
164
|
+
if (!force) {
|
|
165
|
+
if (await access(configPath).then(() => true, () => false)) throw new Error(`${configPath} already exists. Use --force to overwrite it.`);
|
|
166
|
+
}
|
|
167
|
+
const repository = await GitRepository.open(directory).catch(() => void 0);
|
|
168
|
+
const remoteUrl = await repository?.remoteUrl();
|
|
169
|
+
const remote = remoteUrl ? parseRemoteUrl(remoteUrl) : void 0;
|
|
170
|
+
const projectType = detectProjectType(repository?.root ?? directory);
|
|
171
|
+
await mkdir(directory, { recursive: true });
|
|
172
|
+
await writeFile(configPath, generateConfigSource({
|
|
173
|
+
remote,
|
|
174
|
+
projectType
|
|
175
|
+
}), "utf8");
|
|
176
|
+
return {
|
|
177
|
+
configPath,
|
|
178
|
+
remote,
|
|
179
|
+
projectType
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
//#endregion
|
|
184
|
+
export { initConfig };
|
|
185
|
+
//# sourceMappingURL=initConfig-ByGsbShR.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"initConfig-ByGsbShR.mjs","names":[],"sources":["../src/git/parseRemoteUrl.ts","../src/init/detectProjectType.ts","../src/init/projectPresets.ts","../src/init/generateConfigSource.ts","../src/commands/initConfig.ts"],"sourcesContent":["import type { RepositoryProvider } from \"../config/interfaces/UserConfig\";\n\nexport interface ParsedRemote {\n provider: RepositoryProvider;\n host: string;\n owner: string;\n name: string;\n}\n\n/**\n * Parses an SSH (`git@host:owner/name.git`, `ssh://git@host:22/owner/name.git`) or HTTPS remote URL.\n * GitLab owners may contain subgroups (`group/sub`). Returns undefined for unknown hosts.\n */\nexport function parseRemoteUrl(remote: string): ParsedRemote | undefined {\n const trimmed = remote.trim();\n const scp = /^(?:[\\w.-]+@)?([\\w.-]+):(?!\\/\\/)(.+)$/.exec(trimmed);\n let host: string;\n let pathname: string;\n\n if (scp && !/^[a-z]+:\\/\\//i.test(trimmed)) {\n host = scp[1]!;\n pathname = scp[2]!;\n } else {\n try {\n const url = new URL(trimmed);\n host = url.hostname;\n pathname = url.pathname;\n } catch {\n return undefined;\n }\n }\n\n const segments = pathname\n .replace(/\\.git\\/?$/, \"\")\n .split(\"/\")\n .filter(Boolean);\n\n if (segments.length < 2) {\n return undefined;\n }\n\n const provider: RepositoryProvider | undefined = /(^|\\.)github\\./i.test(host) ? \"github\" : /gitlab/i.test(host) ? \"gitlab\" : undefined;\n\n if (!provider) {\n return undefined;\n }\n\n return { provider, host, owner: segments.slice(0, -1).join(\"/\"), name: segments.at(-1)! };\n}\n","import { existsSync } from \"node:fs\";\nimport path from \"node:path\";\n\nexport type ProjectType = \"node\" | \"python\" | \"jvm\" | \"go\" | \"generic\";\n\nconst MARKERS: Array<[ProjectType, string[]]> = [\n [\"node\", [\"package.json\"]],\n [\"python\", [\"pyproject.toml\", \"requirements.txt\", \"setup.py\"]],\n [\"jvm\", [\"pom.xml\", \"build.gradle\", \"build.gradle.kts\"]],\n [\"go\", [\"go.mod\"]]\n];\n\nexport function detectProjectType(directory: string): ProjectType {\n return MARKERS.find(([, files]) => files.some((file) => existsSync(path.join(directory, file))))?.[0] ?? \"generic\";\n}\n","import {\n BUILD_OUTPUT_DIRS,\n DEFAULT_EXCLUDE,\n DEFAULT_INCLUDE,\n LOCKFILES_BY_ECOSYSTEM,\n NODE_DEPENDENCY_DIRS,\n TEST_FILES_BY_ECOSYSTEM\n} from \"../config/defaults\";\nimport type { ProjectType } from \"./detectProjectType\";\n\nexport interface ProjectPreset {\n include: string[];\n exclude: string[];\n}\n\nexport const PROJECT_PRESETS: Record<ProjectType, ProjectPreset> = {\n node: {\n include: [\"**/*.{ts,tsx,mts,cts,js,jsx,mjs,cjs,json,yaml,yml,md,feature,graphql}\"],\n exclude: [...NODE_DEPENDENCY_DIRS, ...BUILD_OUTPUT_DIRS, ...LOCKFILES_BY_ECOSYSTEM.node, ...TEST_FILES_BY_ECOSYSTEM.node]\n },\n python: {\n include: [\"**/*.{py,pyi,toml,cfg,ini,json,yaml,yml,md}\"],\n exclude: [\n \"**/.venv/**\",\n \"**/venv/**\",\n \"**/__pycache__/**\",\n ...BUILD_OUTPUT_DIRS,\n ...LOCKFILES_BY_ECOSYSTEM.python,\n ...TEST_FILES_BY_ECOSYSTEM.python\n ]\n },\n jvm: {\n include: [\"**/*.{java,kt,kts,groovy,gradle,xml,properties,json,yaml,yml,md}\"],\n exclude: [\"**/target/**\", \"**/.gradle/**\", ...BUILD_OUTPUT_DIRS, ...LOCKFILES_BY_ECOSYSTEM.jvm, ...TEST_FILES_BY_ECOSYSTEM.jvm]\n },\n go: {\n include: [\"**/*.{go,mod,json,yaml,yml,md,sql}\"],\n exclude: [\"**/vendor/**\", \"**/bin/**\", ...BUILD_OUTPUT_DIRS, ...LOCKFILES_BY_ECOSYSTEM.go, ...TEST_FILES_BY_ECOSYSTEM.go]\n },\n generic: { include: DEFAULT_INCLUDE, exclude: DEFAULT_EXCLUDE }\n};\n","import {\n DEFAULT_API_KEY_ENV,\n DEFAULT_BATCH_SIZE,\n DEFAULT_CHUNK_LINES,\n DEFAULT_CHUNK_OVERLAP,\n DEFAULT_DIMENSIONS\n} from \"../config/defaults\";\nimport {\n DEFAULT_ASSET_NAME_TEMPLATE,\n DEFAULT_GITHUB_API_URL,\n DEFAULT_GITLAB_API_URL,\n DEFAULT_OUTPUT_DIR,\n DEFAULT_TAG_TEMPLATE,\n GITHUB_TOKEN_ENV,\n GITLAB_TOKEN_ENV\n} from \"../constants\";\nimport type { ParsedRemote } from \"../git/parseRemoteUrl\";\nimport type { ProjectType } from \"./detectProjectType\";\nimport { PROJECT_PRESETS } from \"./projectPresets\";\n\nexport interface GenerateConfigSourceOptions {\n remote?: ParsedRemote;\n projectType: ProjectType;\n}\n\nfunction list(values: string[], indent: string): string {\n return `[\\n${values.map((value) => `${indent} ${JSON.stringify(value)}`).join(\",\\n\")}\\n${indent}]`;\n}\n\nfunction apiUrlLine(remote: ParsedRemote | undefined): string {\n if (remote?.provider === \"gitlab\") {\n return remote.host === \"gitlab.com\"\n ? `// apiUrl: ${JSON.stringify(DEFAULT_GITLAB_API_URL)}`\n : `apiUrl: ${JSON.stringify(`https://${remote.host}/api/v4`)}`;\n }\n\n return remote && remote.host !== \"github.com\"\n ? `apiUrl: ${JSON.stringify(`https://${remote.host}/api/v3`)}`\n : `// apiUrl: ${JSON.stringify(DEFAULT_GITHUB_API_URL)}`;\n}\n\nfunction repositoryBlock(remote: ParsedRemote | undefined): string {\n const fields = [\n `provider: ${JSON.stringify(remote?.provider ?? \"github\")}`,\n `owner: ${JSON.stringify(remote?.owner ?? \"TODO-owner\")}`,\n `name: ${JSON.stringify(remote?.name ?? \"TODO-repository\")}`\n ];\n const apiUrl = apiUrlLine(remote);\n const lines = apiUrl.startsWith(\"//\") ? [fields.join(\",\\n \"), apiUrl] : [[...fields, apiUrl].join(\",\\n \")];\n\n return `{\\n ${lines.join(\"\\n \")}\\n }`;\n}\n\n/** Source of a default `source-pack.config.ts`, deduced from the Git remote and the project type. */\nexport function generateConfigSource({ remote, projectType }: GenerateConfigSourceOptions): string {\n const preset = PROJECT_PRESETS[projectType];\n\n return `import { defineConfig } from \"@cmflow/source-pack\";\n\n// Secrets are read from the environment only: ${DEFAULT_API_KEY_ENV} (embeddings), ${remote?.provider === \"gitlab\" ? GITLAB_TOKEN_ENV : GITHUB_TOKEN_ENV} (publish).\nexport default defineConfig({\n outputDir: ${JSON.stringify(DEFAULT_OUTPUT_DIR)},\n repository: ${repositoryBlock(remote)},\n sources: {\n include: ${list(preset.include, \" \")},\n // Adjust to the project: generated data, fixtures, mocks, vendored code...\n exclude: ${list(preset.exclude, \" \")}\n },\n chunking: { lines: ${DEFAULT_CHUNK_LINES}, overlap: ${DEFAULT_CHUNK_OVERLAP} },\n embedding: {\n baseUrl: \"https://apim-prdaiplatform-frc.azure-api.net/litellm-api\",\n model: \"text-embedding-3-small-gmdt\",\n fallbackModels: [\"text-embedding-3-small-swc-gmdt\", \"text-embedding-3-small-eus2-gmdt\"],\n referenceModel: \"text-embedding-3-small\",\n dimensions: ${DEFAULT_DIMENSIONS},\n batchSize: ${DEFAULT_BATCH_SIZE}\n },\n attachments: [],\n publish: {\n tag: ${JSON.stringify(DEFAULT_TAG_TEMPLATE)},\n assetName: ${JSON.stringify(DEFAULT_ASSET_NAME_TEMPLATE)}\n }\n});\n`;\n}\n","import { access, mkdir, writeFile } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { GitRepository } from \"../git/GitRepository\";\nimport { type ParsedRemote, parseRemoteUrl } from \"../git/parseRemoteUrl\";\nimport { detectProjectType, type ProjectType } from \"../init/detectProjectType\";\nimport { generateConfigSource } from \"../init/generateConfigSource\";\n\nexport interface InitConfigOptions {\n configPath: string;\n force?: boolean;\n}\n\nexport interface InitConfigResult {\n configPath: string;\n remote?: ParsedRemote;\n projectType: ProjectType;\n}\n\n/** Writes a default `source-pack.config.ts` next to `configPath`, deduced from the Git remote `origin`. */\nexport async function initConfig({ configPath, force = false }: InitConfigOptions): Promise<InitConfigResult> {\n const directory = path.dirname(configPath);\n\n if (!force) {\n const exists = await access(configPath).then(\n () => true,\n () => false\n );\n\n if (exists) {\n throw new Error(`${configPath} already exists. Use --force to overwrite it.`);\n }\n }\n\n const repository = await GitRepository.open(directory).catch(() => undefined);\n const remoteUrl = await repository?.remoteUrl();\n const remote = remoteUrl ? parseRemoteUrl(remoteUrl) : undefined;\n const projectType = detectProjectType(repository?.root ?? directory);\n\n await mkdir(directory, { recursive: true });\n await writeFile(configPath, generateConfigSource({ remote, projectType }), \"utf8\");\n\n return { configPath, remote, projectType };\n}\n"],"mappings":";;;;;;;;;;;;AAaA,SAAgB,eAAe,QAA0C;CACvE,MAAM,UAAU,OAAO,KAAK;CAC5B,MAAM,MAAM,wCAAwC,KAAK,OAAO;CAChE,IAAI;CACJ,IAAI;CAEJ,IAAI,OAAO,CAAC,gBAAgB,KAAK,OAAO,GAAG;EACzC,OAAO,IAAI;EACX,WAAW,IAAI;CACjB,OACE,IAAI;EACF,MAAM,MAAM,IAAI,IAAI,OAAO;EAC3B,OAAO,IAAI;EACX,WAAW,IAAI;CACjB,QAAQ;EACN;CACF;CAGF,MAAM,WAAW,SACd,QAAQ,aAAa,EAAE,CAAC,CACxB,MAAM,GAAG,CAAC,CACV,OAAO,OAAO;CAEjB,IAAI,SAAS,SAAS,GACpB;CAGF,MAAM,WAA2C,kBAAkB,KAAK,IAAI,IAAI,WAAW,UAAU,KAAK,IAAI,IAAI,WAAW;CAE7H,IAAI,CAAC,UACH;CAGF,OAAO;EAAE;EAAU;EAAM,OAAO,SAAS,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK,GAAG;EAAG,MAAM,SAAS,GAAG,EAAE;CAAG;AAC1F;;;;AC3CA,MAAM,UAA0C;CAC9C,CAAC,QAAQ,CAAC,cAAc,CAAC;CACzB,CAAC,UAAU;EAAC;EAAkB;EAAoB;CAAU,CAAC;CAC7D,CAAC,OAAO;EAAC;EAAW;EAAgB;CAAkB,CAAC;CACvD,CAAC,MAAM,CAAC,QAAQ,CAAC;AACnB;AAEA,SAAgB,kBAAkB,WAAgC;CAChE,OAAO,QAAQ,MAAM,GAAG,WAAW,MAAM,MAAM,SAAS,WAAW,KAAK,KAAK,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,MAAM;AAC3G;;;;ACCA,MAAa,kBAAsD;CACjE,MAAM;EACJ,SAAS,CAAC,uEAAuE;EACjF,SAAS;GAAC,GAAG;GAAsB,GAAG;GAAmB,GAAG,uBAAuB;GAAM,GAAG,wBAAwB;EAAI;CAC1H;CACA,QAAQ;EACN,SAAS,CAAC,6CAA6C;EACvD,SAAS;GACP;GACA;GACA;GACA,GAAG;GACH,GAAG,uBAAuB;GAC1B,GAAG,wBAAwB;EAC7B;CACF;CACA,KAAK;EACH,SAAS,CAAC,kEAAkE;EAC5E,SAAS;GAAC;GAAgB;GAAiB,GAAG;GAAmB,GAAG,uBAAuB;GAAK,GAAG,wBAAwB;EAAG;CAChI;CACA,IAAI;EACF,SAAS,CAAC,oCAAoC;EAC9C,SAAS;GAAC;GAAgB;GAAa,GAAG;GAAmB,GAAG,uBAAuB;GAAI,GAAG,wBAAwB;EAAE;CAC1H;CACA,SAAS;EAAE,SAAS;EAAiB,SAAS;CAAgB;AAChE;;;;ACfA,SAAS,KAAK,QAAkB,QAAwB;CACtD,OAAO,MAAM,OAAO,KAAK,UAAU,GAAG,OAAO,IAAI,KAAK,UAAU,KAAK,GAAG,CAAC,CAAC,KAAK,KAAK,EAAE,IAAI,OAAO;AACnG;AAEA,SAAS,WAAW,QAA0C;CAC5D,IAAI,QAAQ,aAAa,UACvB,OAAO,OAAO,SAAS,eACnB,cAAc,KAAK,UAAU,sBAAsB,MACnD,WAAW,KAAK,UAAU,WAAW,OAAO,KAAK,QAAQ;CAG/D,OAAO,UAAU,OAAO,SAAS,eAC7B,WAAW,KAAK,UAAU,WAAW,OAAO,KAAK,QAAQ,MACzD,cAAc,KAAK,UAAU,sBAAsB;AACzD;AAEA,SAAS,gBAAgB,QAA0C;CACjE,MAAM,SAAS;EACb,aAAa,KAAK,UAAU,QAAQ,YAAY,QAAQ;EACxD,UAAU,KAAK,UAAU,QAAQ,SAAS,YAAY;EACtD,SAAS,KAAK,UAAU,QAAQ,QAAQ,iBAAiB;CAC3D;CACA,MAAM,SAAS,WAAW,MAAM;CAGhC,OAAO,WAFO,OAAO,WAAW,IAAI,IAAI,CAAC,OAAO,KAAK,SAAS,GAAG,MAAM,IAAI,CAAC,CAAC,GAAG,QAAQ,MAAM,CAAC,CAAC,KAAK,SAAS,CAAC,EAEzF,CAAC,KAAK,QAAQ,EAAE;AACxC;;AAGA,SAAgB,qBAAqB,EAAE,QAAQ,eAAoD;CACjG,MAAM,SAAS,gBAAgB;CAE/B,OAAO;;iDAEwC,oBAAoB,iBAAiB,QAAQ,aAAa,WAAW,mBAAmB,iBAAiB;;eAE3I,KAAK,UAAU,kBAAkB,EAAE;gBAClC,gBAAgB,MAAM,EAAE;;eAEzB,KAAK,OAAO,SAAS,MAAM,EAAE;;eAE7B,KAAK,OAAO,SAAS,MAAM,EAAE;;2BAED,gBAAmC;;;;;;kBAM5D,mBAAmB;oBACD;;;;WAIzB,KAAK,UAAU,oBAAoB,EAAE;iBAC/B,KAAK,UAAU,2BAA2B,EAAE;;;;AAI7D;;;;;ACjEA,eAAsB,WAAW,EAAE,YAAY,QAAQ,SAAuD;CAC5G,MAAM,YAAY,KAAK,QAAQ,UAAU;CAEzC,IAAI,CAAC,OAMH;MAAI,MALiB,OAAO,UAAU,CAAC,CAAC,WAChC,YACA,KACR,GAGE,MAAM,IAAI,MAAM,GAAG,WAAW,8CAA8C;CAC9E;CAGF,MAAM,aAAa,MAAM,cAAc,KAAK,SAAS,CAAC,CAAC,YAAY,MAAS;CAC5E,MAAM,YAAY,MAAM,YAAY,UAAU;CAC9C,MAAM,SAAS,YAAY,eAAe,SAAS,IAAI;CACvD,MAAM,cAAc,kBAAkB,YAAY,QAAQ,SAAS;CAEnE,MAAM,MAAM,WAAW,EAAE,WAAW,KAAK,CAAC;CAC1C,MAAM,UAAU,YAAY,qBAAqB;EAAE;EAAQ;CAAY,CAAC,GAAG,MAAM;CAEjF,OAAO;EAAE;EAAY;EAAQ;CAAY;AAC3C"}
|
|
@@ -0,0 +1,224 @@
|
|
|
1
|
+
import { _ as strictObject, m as number, n as _enum, o as array, s as boolean, v as string, w as errorMessage, x as url, y as union } from "./packageVersion-B0749hF6.mjs";
|
|
2
|
+
import { _ as PACKAGE_NAME, a as DEFAULT_ASSET_NAME_TEMPLATE, c as DEFAULT_GITLAB_API_URL, d as DEFAULT_TAG_TEMPLATE, l as DEFAULT_GITLAB_PACKAGE_NAME, s as DEFAULT_GITHUB_API_URL, u as DEFAULT_OUTPUT_DIR } from "./constants-DkiLCuIK.mjs";
|
|
3
|
+
import { a as DEFAULT_INCLUDE, i as DEFAULT_EXCLUDE, n as DEFAULT_API_KEY_ENV, o as DEFAULT_MAX_FILE_BYTES, r as DEFAULT_DIMENSIONS, s as DEFAULT_MAX_INPUT_CHARS } from "./defaults-BJs7a37e.mjs";
|
|
4
|
+
import { register } from "node:module";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { access } from "node:fs/promises";
|
|
7
|
+
import { pathToFileURL } from "node:url";
|
|
8
|
+
|
|
9
|
+
//#region src/config/registerSelfResolution.ts
|
|
10
|
+
let registered = false;
|
|
11
|
+
const hookSource = `
|
|
12
|
+
let selfUrl;
|
|
13
|
+
export function initialize(data) { selfUrl = data.selfUrl; }
|
|
14
|
+
export async function resolve(specifier, context, nextResolve) {
|
|
15
|
+
try {
|
|
16
|
+
return await nextResolve(specifier, context);
|
|
17
|
+
} catch (error) {
|
|
18
|
+
if (specifier === ${JSON.stringify(PACKAGE_NAME)} && selfUrl) {
|
|
19
|
+
return { url: selfUrl, shortCircuit: true };
|
|
20
|
+
}
|
|
21
|
+
throw error;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
`;
|
|
25
|
+
/**
|
|
26
|
+
* Lets a config file `import { defineConfig } from "@cmflow/source-pack"` even when the package is not installed
|
|
27
|
+
* in the project (e.g. `npx @cmflow/source-pack build` in CI): the import falls back to the running package.
|
|
28
|
+
*/
|
|
29
|
+
function registerSelfResolution() {
|
|
30
|
+
if (registered) return;
|
|
31
|
+
let selfUrl;
|
|
32
|
+
try {
|
|
33
|
+
selfUrl = import.meta.resolve(PACKAGE_NAME);
|
|
34
|
+
} catch {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
register(`data:text/javascript,${encodeURIComponent(hookSource)}`, { data: { selfUrl } });
|
|
38
|
+
registered = true;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
//#endregion
|
|
42
|
+
//#region src/config/configSchema.ts
|
|
43
|
+
const nonEmptyString = string().trim().min(1, "expected a non-empty string");
|
|
44
|
+
const globList = array(nonEmptyString, "expected an array of glob strings");
|
|
45
|
+
const positiveInt = number("expected a number").int("expected an integer").positive("expected a positive integer");
|
|
46
|
+
const repositorySchema = strictObject({
|
|
47
|
+
provider: _enum(["github", "gitlab"], "expected \"github\" or \"gitlab\""),
|
|
48
|
+
owner: nonEmptyString.optional(),
|
|
49
|
+
name: nonEmptyString.optional(),
|
|
50
|
+
projectId: union([nonEmptyString, positiveInt], "expected a GitLab project id or path").optional(),
|
|
51
|
+
apiUrl: url("expected an absolute URL").optional()
|
|
52
|
+
}).superRefine((repository, ctx) => {
|
|
53
|
+
if (repository.provider === "github" && (!repository.owner || !repository.name)) ctx.addIssue({
|
|
54
|
+
code: "custom",
|
|
55
|
+
path: [repository.owner ? "name" : "owner"],
|
|
56
|
+
message: "required for a GitHub repository"
|
|
57
|
+
});
|
|
58
|
+
if (repository.provider === "gitlab" && repository.projectId === void 0 && (!repository.owner || !repository.name)) ctx.addIssue({
|
|
59
|
+
code: "custom",
|
|
60
|
+
path: ["projectId"],
|
|
61
|
+
message: "required for a GitLab project (or set both owner and name)"
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
const sourcesSchema = strictObject({
|
|
65
|
+
include: globList.min(1, "expected at least one glob").optional(),
|
|
66
|
+
exclude: globList.optional(),
|
|
67
|
+
maxFileBytes: positiveInt.optional()
|
|
68
|
+
});
|
|
69
|
+
const chunkingSchema = strictObject({
|
|
70
|
+
lines: positiveInt.optional(),
|
|
71
|
+
overlap: number("expected a number").int("expected an integer").min(0, "expected an integer >= 0").optional()
|
|
72
|
+
}).superRefine((chunking, ctx) => {
|
|
73
|
+
if ((chunking.overlap ?? 15) >= (chunking.lines ?? 100)) ctx.addIssue({
|
|
74
|
+
code: "custom",
|
|
75
|
+
path: ["overlap"],
|
|
76
|
+
message: "expected a value lower than chunking.lines"
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
const embeddingSchema = strictObject({
|
|
80
|
+
baseUrl: url("expected an absolute URL"),
|
|
81
|
+
model: nonEmptyString,
|
|
82
|
+
fallbackModels: array(nonEmptyString, "expected an array of model names").optional(),
|
|
83
|
+
referenceModel: nonEmptyString.optional(),
|
|
84
|
+
dimensions: positiveInt.optional(),
|
|
85
|
+
batchSize: positiveInt.max(2048, "expected at most 2048").optional(),
|
|
86
|
+
concurrency: positiveInt.optional(),
|
|
87
|
+
maxRetries: number("expected a number").int("expected an integer").min(0, "expected an integer >= 0").optional(),
|
|
88
|
+
maxInputChars: positiveInt.optional(),
|
|
89
|
+
apiKeyEnv: nonEmptyString.optional()
|
|
90
|
+
});
|
|
91
|
+
const templateWithVersion = nonEmptyString.refine((value) => value.includes("{version}"), "expected a template containing \"{version}\"");
|
|
92
|
+
const publishSchema = strictObject({
|
|
93
|
+
tag: templateWithVersion.optional(),
|
|
94
|
+
assetName: templateWithVersion.optional(),
|
|
95
|
+
packageName: string().regex(/^[A-Za-z0-9._-]+$/, "expected letters, digits, dots, dashes or underscores").optional(),
|
|
96
|
+
createRelease: boolean("expected a boolean").optional()
|
|
97
|
+
});
|
|
98
|
+
const userConfigSchema = strictObject({
|
|
99
|
+
outputDir: nonEmptyString.optional(),
|
|
100
|
+
repository: repositorySchema,
|
|
101
|
+
sources: sourcesSchema.optional(),
|
|
102
|
+
chunking: chunkingSchema.optional(),
|
|
103
|
+
embedding: embeddingSchema.optional(),
|
|
104
|
+
attachments: array(nonEmptyString, "expected an array of repository paths").optional(),
|
|
105
|
+
publish: publishSchema.optional()
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
//#endregion
|
|
109
|
+
//#region src/config/formatConfigIssues.ts
|
|
110
|
+
function describeInput(input) {
|
|
111
|
+
if (input === void 0) return "nothing";
|
|
112
|
+
const text = JSON.stringify(input) ?? String(input);
|
|
113
|
+
return text.length > 80 ? `${text.slice(0, 77)}...` : text;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Turns zod issues into one explicit line per field: `<field>: <expected> (received <value>)`.
|
|
117
|
+
*/
|
|
118
|
+
function formatConfigIssues(issues) {
|
|
119
|
+
return issues.map((issue) => {
|
|
120
|
+
const field = issue.path.length ? issue.path.map(String).join(".") : "(root)";
|
|
121
|
+
if (issue.code === "unrecognized_keys") return `${field}: unknown option(s) ${issue.keys.map((key) => `"${key}"`).join(", ")}`;
|
|
122
|
+
const received = "input" in issue && issue.code !== "custom" ? ` (received ${describeInput(issue.input)})` : "";
|
|
123
|
+
return `${field}: ${issue.message}${received}`;
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
//#endregion
|
|
128
|
+
//#region src/config/resolveConfig.ts
|
|
129
|
+
/**
|
|
130
|
+
* Validates a raw user config and fills every default. Throws an explicit, field-level error message on invalid input.
|
|
131
|
+
*/
|
|
132
|
+
function resolveConfig(raw, { cwd = process.cwd(), configPath = "", env = process.env } = {}) {
|
|
133
|
+
const result = userConfigSchema.safeParse(raw, { reportInput: true });
|
|
134
|
+
if (!result.success) {
|
|
135
|
+
const lines = formatConfigIssues(result.error.issues);
|
|
136
|
+
throw new Error(`Invalid source-pack config${configPath ? ` (${configPath})` : ""}:\n${lines.map((line) => ` - ${line}`).join("\n")}`);
|
|
137
|
+
}
|
|
138
|
+
const config = result.data;
|
|
139
|
+
const { repository } = config;
|
|
140
|
+
const defaultApiUrl = repository.provider === "github" ? DEFAULT_GITHUB_API_URL : env.CI_API_V4_URL ?? "https://gitlab.com/api/v4";
|
|
141
|
+
const embedding = config.embedding;
|
|
142
|
+
return {
|
|
143
|
+
configPath,
|
|
144
|
+
cwd,
|
|
145
|
+
outputDir: path.resolve(cwd, config.outputDir ?? "./tmp/source-pack"),
|
|
146
|
+
repository: {
|
|
147
|
+
provider: repository.provider,
|
|
148
|
+
owner: repository.owner,
|
|
149
|
+
name: repository.name,
|
|
150
|
+
projectId: repository.projectId === void 0 ? void 0 : String(repository.projectId),
|
|
151
|
+
apiUrl: (repository.apiUrl ?? defaultApiUrl).replace(/\/+$/, "")
|
|
152
|
+
},
|
|
153
|
+
sources: {
|
|
154
|
+
include: config.sources?.include ?? DEFAULT_INCLUDE,
|
|
155
|
+
exclude: config.sources?.exclude ?? DEFAULT_EXCLUDE,
|
|
156
|
+
maxFileBytes: config.sources?.maxFileBytes ?? 1048576
|
|
157
|
+
},
|
|
158
|
+
chunking: {
|
|
159
|
+
lines: config.chunking?.lines ?? 100,
|
|
160
|
+
overlap: config.chunking?.overlap ?? 15
|
|
161
|
+
},
|
|
162
|
+
embedding: embedding ? {
|
|
163
|
+
baseUrl: embedding.baseUrl,
|
|
164
|
+
model: embedding.model,
|
|
165
|
+
fallbackModels: embedding.fallbackModels ?? [],
|
|
166
|
+
referenceModel: embedding.referenceModel ?? embedding.model,
|
|
167
|
+
dimensions: embedding.dimensions ?? 1536,
|
|
168
|
+
batchSize: embedding.batchSize ?? 64,
|
|
169
|
+
concurrency: embedding.concurrency ?? 4,
|
|
170
|
+
maxRetries: embedding.maxRetries ?? 3,
|
|
171
|
+
maxInputChars: embedding.maxInputChars ?? 12e3,
|
|
172
|
+
apiKeyEnv: embedding.apiKeyEnv ?? "LITELLM_API_KEY"
|
|
173
|
+
} : null,
|
|
174
|
+
attachments: config.attachments ?? [],
|
|
175
|
+
publish: {
|
|
176
|
+
tag: config.publish?.tag ?? "version-{version}",
|
|
177
|
+
assetName: config.publish?.assetName ?? "source-pack-{version}.tar.gz",
|
|
178
|
+
packageName: config.publish?.packageName ?? "source-pack",
|
|
179
|
+
createRelease: config.publish?.createRelease ?? false
|
|
180
|
+
}
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
//#endregion
|
|
185
|
+
//#region src/config/loadConfig.ts
|
|
186
|
+
async function importConfigModule(filePath) {
|
|
187
|
+
const url = pathToFileURL(filePath).href;
|
|
188
|
+
if (!/\.[cm]?ts$/.test(filePath)) return import(url);
|
|
189
|
+
const { register } = await import("tsx/esm/api");
|
|
190
|
+
const unregister = register();
|
|
191
|
+
try {
|
|
192
|
+
return await import(url);
|
|
193
|
+
} finally {
|
|
194
|
+
await unregister();
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Loads `source-pack.config.ts` (through tsx) or a `.mjs`/`.js` config, then validates it.
|
|
199
|
+
* Relative paths of the config are resolved against `cwd` (the command's directory).
|
|
200
|
+
*/
|
|
201
|
+
async function loadConfig(configPath, { cwd = process.cwd(), env = process.env } = {}) {
|
|
202
|
+
const filePath = path.resolve(cwd, configPath);
|
|
203
|
+
try {
|
|
204
|
+
await access(filePath);
|
|
205
|
+
} catch {
|
|
206
|
+
throw new Error(`source-pack config not found at ${filePath}. Run "source-pack init" or pass --config <path>.`);
|
|
207
|
+
}
|
|
208
|
+
registerSelfResolution();
|
|
209
|
+
let mod;
|
|
210
|
+
try {
|
|
211
|
+
mod = await importConfigModule(filePath);
|
|
212
|
+
} catch (error) {
|
|
213
|
+
throw new Error(`Unable to load source-pack config at ${filePath}: ${errorMessage(error)}`);
|
|
214
|
+
}
|
|
215
|
+
return resolveConfig(mod.default ?? mod, {
|
|
216
|
+
cwd,
|
|
217
|
+
configPath: filePath,
|
|
218
|
+
env
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
//#endregion
|
|
223
|
+
export { resolveConfig as n, loadConfig as t };
|
|
224
|
+
//# sourceMappingURL=loadConfig-CNrL90dq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loadConfig-CNrL90dq.mjs","names":["z.string","z.array","z.number","z\n .strictObject","z.enum","z.union","z.url","z.strictObject","z\n .string","z.boolean"],"sources":["../src/config/registerSelfResolution.ts","../src/config/configSchema.ts","../src/config/formatConfigIssues.ts","../src/config/resolveConfig.ts","../src/config/loadConfig.ts"],"sourcesContent":["import { register } from \"node:module\";\nimport { PACKAGE_NAME } from \"../constants\";\n\nlet registered = false;\n\nconst hookSource = `\nlet selfUrl;\nexport function initialize(data) { selfUrl = data.selfUrl; }\nexport async function resolve(specifier, context, nextResolve) {\n try {\n return await nextResolve(specifier, context);\n } catch (error) {\n if (specifier === ${JSON.stringify(PACKAGE_NAME)} && selfUrl) {\n return { url: selfUrl, shortCircuit: true };\n }\n throw error;\n }\n}\n`;\n\n/**\n * Lets a config file `import { defineConfig } from \"@cmflow/source-pack\"` even when the package is not installed\n * in the project (e.g. `npx @cmflow/source-pack build` in CI): the import falls back to the running package.\n */\nexport function registerSelfResolution(): void {\n if (registered) {\n return;\n }\n\n let selfUrl: string;\n\n try {\n selfUrl = import.meta.resolve(PACKAGE_NAME);\n } catch {\n return;\n }\n\n register(`data:text/javascript,${encodeURIComponent(hookSource)}`, { data: { selfUrl } });\n registered = true;\n}\n","import { z } from \"zod\";\nimport { DEFAULT_CHUNK_LINES, DEFAULT_CHUNK_OVERLAP } from \"./defaults\";\n\nconst nonEmptyString = z.string().trim().min(1, \"expected a non-empty string\");\nconst globList = z.array(nonEmptyString, \"expected an array of glob strings\");\nconst positiveInt = z.number(\"expected a number\").int(\"expected an integer\").positive(\"expected a positive integer\");\n\nexport const repositorySchema = z\n .strictObject({\n provider: z.enum([\"github\", \"gitlab\"], 'expected \"github\" or \"gitlab\"'),\n owner: nonEmptyString.optional(),\n name: nonEmptyString.optional(),\n projectId: z.union([nonEmptyString, positiveInt], \"expected a GitLab project id or path\").optional(),\n apiUrl: z.url(\"expected an absolute URL\").optional()\n })\n .superRefine((repository, ctx) => {\n if (repository.provider === \"github\" && (!repository.owner || !repository.name)) {\n ctx.addIssue({ code: \"custom\", path: [repository.owner ? \"name\" : \"owner\"], message: \"required for a GitHub repository\" });\n }\n\n if (repository.provider === \"gitlab\" && repository.projectId === undefined && (!repository.owner || !repository.name)) {\n ctx.addIssue({ code: \"custom\", path: [\"projectId\"], message: \"required for a GitLab project (or set both owner and name)\" });\n }\n });\n\nexport const sourcesSchema = z.strictObject({\n include: globList.min(1, \"expected at least one glob\").optional(),\n exclude: globList.optional(),\n maxFileBytes: positiveInt.optional()\n});\n\nexport const chunkingSchema = z\n .strictObject({\n lines: positiveInt.optional(),\n overlap: z.number(\"expected a number\").int(\"expected an integer\").min(0, \"expected an integer >= 0\").optional()\n })\n .superRefine((chunking, ctx) => {\n if ((chunking.overlap ?? DEFAULT_CHUNK_OVERLAP) >= (chunking.lines ?? DEFAULT_CHUNK_LINES)) {\n ctx.addIssue({ code: \"custom\", path: [\"overlap\"], message: \"expected a value lower than chunking.lines\" });\n }\n });\n\nexport const embeddingSchema = z.strictObject({\n baseUrl: z.url(\"expected an absolute URL\"),\n model: nonEmptyString,\n fallbackModels: z.array(nonEmptyString, \"expected an array of model names\").optional(),\n referenceModel: nonEmptyString.optional(),\n dimensions: positiveInt.optional(),\n batchSize: positiveInt.max(2048, \"expected at most 2048\").optional(),\n concurrency: positiveInt.optional(),\n maxRetries: z.number(\"expected a number\").int(\"expected an integer\").min(0, \"expected an integer >= 0\").optional(),\n maxInputChars: positiveInt.optional(),\n apiKeyEnv: nonEmptyString.optional()\n});\n\nconst templateWithVersion = nonEmptyString.refine((value) => value.includes(\"{version}\"), 'expected a template containing \"{version}\"');\n\nexport const publishSchema = z.strictObject({\n tag: templateWithVersion.optional(),\n assetName: templateWithVersion.optional(),\n packageName: z\n .string()\n .regex(/^[A-Za-z0-9._-]+$/, \"expected letters, digits, dots, dashes or underscores\")\n .optional(),\n createRelease: z.boolean(\"expected a boolean\").optional()\n});\n\nexport const userConfigSchema = z.strictObject({\n outputDir: nonEmptyString.optional(),\n repository: repositorySchema,\n sources: sourcesSchema.optional(),\n chunking: chunkingSchema.optional(),\n embedding: embeddingSchema.optional(),\n attachments: z.array(nonEmptyString, \"expected an array of repository paths\").optional(),\n publish: publishSchema.optional()\n});\n","import type { z } from \"zod\";\n\nfunction describeInput(input: unknown): string {\n if (input === undefined) {\n return \"nothing\";\n }\n\n const text = JSON.stringify(input) ?? String(input);\n\n return text.length > 80 ? `${text.slice(0, 77)}...` : text;\n}\n\n/**\n * Turns zod issues into one explicit line per field: `<field>: <expected> (received <value>)`.\n */\nexport function formatConfigIssues(issues: z.core.$ZodIssue[]): string[] {\n return issues.map((issue) => {\n const field = issue.path.length ? issue.path.map(String).join(\".\") : \"(root)\";\n\n if (issue.code === \"unrecognized_keys\") {\n return `${field}: unknown option(s) ${issue.keys.map((key) => `\"${key}\"`).join(\", \")}`;\n }\n\n const received = \"input\" in issue && issue.code !== \"custom\" ? ` (received ${describeInput(issue.input)})` : \"\";\n\n return `${field}: ${issue.message}${received}`;\n });\n}\n","import path from \"node:path\";\nimport {\n DEFAULT_ASSET_NAME_TEMPLATE,\n DEFAULT_GITHUB_API_URL,\n DEFAULT_GITLAB_API_URL,\n DEFAULT_GITLAB_PACKAGE_NAME,\n DEFAULT_OUTPUT_DIR,\n DEFAULT_TAG_TEMPLATE\n} from \"../constants\";\nimport { userConfigSchema } from \"./configSchema\";\nimport {\n DEFAULT_API_KEY_ENV,\n DEFAULT_BATCH_SIZE,\n DEFAULT_CHUNK_LINES,\n DEFAULT_CHUNK_OVERLAP,\n DEFAULT_DIMENSIONS,\n DEFAULT_EMBEDDING_CONCURRENCY,\n DEFAULT_EXCLUDE,\n DEFAULT_INCLUDE,\n DEFAULT_MAX_FILE_BYTES,\n DEFAULT_MAX_INPUT_CHARS,\n DEFAULT_MAX_RETRIES\n} from \"./defaults\";\nimport { formatConfigIssues } from \"./formatConfigIssues\";\nimport type { ResolvedConfig } from \"./interfaces/ResolvedConfig\";\n\nexport interface ResolveConfigOptions {\n cwd?: string;\n configPath?: string;\n env?: NodeJS.ProcessEnv;\n}\n\n/**\n * Validates a raw user config and fills every default. Throws an explicit, field-level error message on invalid input.\n */\nexport function resolveConfig(\n raw: unknown,\n { cwd = process.cwd(), configPath = \"\", env = process.env }: ResolveConfigOptions = {}\n): ResolvedConfig {\n const result = userConfigSchema.safeParse(raw, { reportInput: true });\n\n if (!result.success) {\n const lines = formatConfigIssues(result.error.issues);\n throw new Error(`Invalid source-pack config${configPath ? ` (${configPath})` : \"\"}:\\n${lines.map((line) => ` - ${line}`).join(\"\\n\")}`);\n }\n\n const config = result.data;\n const { repository } = config;\n const defaultApiUrl = repository.provider === \"github\" ? DEFAULT_GITHUB_API_URL : (env.CI_API_V4_URL ?? DEFAULT_GITLAB_API_URL);\n const embedding = config.embedding;\n\n return {\n configPath,\n cwd,\n outputDir: path.resolve(cwd, config.outputDir ?? DEFAULT_OUTPUT_DIR),\n repository: {\n provider: repository.provider,\n owner: repository.owner,\n name: repository.name,\n projectId: repository.projectId === undefined ? undefined : String(repository.projectId),\n apiUrl: (repository.apiUrl ?? defaultApiUrl).replace(/\\/+$/, \"\")\n },\n sources: {\n include: config.sources?.include ?? DEFAULT_INCLUDE,\n exclude: config.sources?.exclude ?? DEFAULT_EXCLUDE,\n maxFileBytes: config.sources?.maxFileBytes ?? DEFAULT_MAX_FILE_BYTES\n },\n chunking: {\n lines: config.chunking?.lines ?? DEFAULT_CHUNK_LINES,\n overlap: config.chunking?.overlap ?? DEFAULT_CHUNK_OVERLAP\n },\n embedding: embedding\n ? {\n baseUrl: embedding.baseUrl,\n model: embedding.model,\n fallbackModels: embedding.fallbackModels ?? [],\n referenceModel: embedding.referenceModel ?? embedding.model,\n dimensions: embedding.dimensions ?? DEFAULT_DIMENSIONS,\n batchSize: embedding.batchSize ?? DEFAULT_BATCH_SIZE,\n concurrency: embedding.concurrency ?? DEFAULT_EMBEDDING_CONCURRENCY,\n maxRetries: embedding.maxRetries ?? DEFAULT_MAX_RETRIES,\n maxInputChars: embedding.maxInputChars ?? DEFAULT_MAX_INPUT_CHARS,\n apiKeyEnv: embedding.apiKeyEnv ?? DEFAULT_API_KEY_ENV\n }\n : null,\n attachments: config.attachments ?? [],\n publish: {\n tag: config.publish?.tag ?? DEFAULT_TAG_TEMPLATE,\n assetName: config.publish?.assetName ?? DEFAULT_ASSET_NAME_TEMPLATE,\n packageName: config.publish?.packageName ?? DEFAULT_GITLAB_PACKAGE_NAME,\n createRelease: config.publish?.createRelease ?? false\n }\n };\n}\n","import { access } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { errorMessage } from \"../utils/errorMessage\";\nimport type { ResolvedConfig } from \"./interfaces/ResolvedConfig\";\nimport { registerSelfResolution } from \"./registerSelfResolution\";\nimport { resolveConfig } from \"./resolveConfig\";\n\nasync function importConfigModule(filePath: string): Promise<unknown> {\n const url = pathToFileURL(filePath).href;\n\n if (!/\\.[cm]?ts$/.test(filePath)) {\n return import(url);\n }\n\n const { register } = await import(\"tsx/esm/api\");\n const unregister = register();\n\n try {\n return await import(url);\n } finally {\n await unregister();\n }\n}\n\n/**\n * Loads `source-pack.config.ts` (through tsx) or a `.mjs`/`.js` config, then validates it.\n * Relative paths of the config are resolved against `cwd` (the command's directory).\n */\nexport async function loadConfig(\n configPath: string,\n { cwd = process.cwd(), env = process.env }: { cwd?: string; env?: NodeJS.ProcessEnv } = {}\n): Promise<ResolvedConfig> {\n const filePath = path.resolve(cwd, configPath);\n\n try {\n await access(filePath);\n } catch {\n throw new Error(`source-pack config not found at ${filePath}. Run \"source-pack init\" or pass --config <path>.`);\n }\n\n registerSelfResolution();\n\n let mod: { default?: unknown };\n\n try {\n mod = (await importConfigModule(filePath)) as { default?: unknown };\n } catch (error) {\n throw new Error(`Unable to load source-pack config at ${filePath}: ${errorMessage(error)}`);\n }\n\n return resolveConfig(mod.default ?? mod, { cwd, configPath: filePath, env });\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
//#region src/utils/logger.ts
|
|
2
|
+
const logger = {
|
|
3
|
+
info: (message) => void process.stdout.write(`[source-pack] ${message}\n`),
|
|
4
|
+
warn: (message) => void process.stderr.write(`[source-pack] warn: ${message}\n`),
|
|
5
|
+
error: (message) => void process.stderr.write(`[source-pack] error: ${message}\n`)
|
|
6
|
+
};
|
|
7
|
+
const silentLogger = {
|
|
8
|
+
info: () => void 0,
|
|
9
|
+
warn: () => void 0,
|
|
10
|
+
error: () => void 0
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { silentLogger as n, logger as t };
|
|
15
|
+
//# sourceMappingURL=logger-D1XGzzjT.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger-D1XGzzjT.mjs","names":[],"sources":["../src/utils/logger.ts"],"sourcesContent":["export interface Logger {\n info(message: string): void;\n warn(message: string): void;\n error(message: string): void;\n}\n\nexport const logger: Logger = {\n info: (message) => void process.stdout.write(`[source-pack] ${message}\\n`),\n warn: (message) => void process.stderr.write(`[source-pack] warn: ${message}\\n`),\n error: (message) => void process.stderr.write(`[source-pack] error: ${message}\\n`)\n};\n\nexport const silentLogger: Logger = {\n info: () => undefined,\n warn: () => undefined,\n error: () => undefined\n};\n"],"mappings":";AAMA,MAAa,SAAiB;CAC5B,OAAO,YAAY,KAAK,QAAQ,OAAO,MAAM,iBAAiB,QAAQ,GAAG;CACzE,OAAO,YAAY,KAAK,QAAQ,OAAO,MAAM,uBAAuB,QAAQ,GAAG;CAC/E,QAAQ,YAAY,KAAK,QAAQ,OAAO,MAAM,wBAAwB,QAAQ,GAAG;AACnF;AAEA,MAAa,eAAuB;CAClC,YAAY;CACZ,YAAY;CACZ,aAAa;AACf"}
|