@openpkg-ts/cli 0.1.0 → 0.2.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/CHANGELOG.md +12 -0
- package/README.md +82 -85
- package/bin/openpkg.ts +61 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +6 -0
- package/package.json +6 -45
- package/src/commands/diff.ts +173 -0
- package/src/commands/docs.ts +122 -0
- package/src/commands/snapshot.ts +116 -0
- package/src/index.ts +2 -0
- package/test/diff.test.ts +336 -0
- package/test/docs.test.ts +599 -0
- package/test/get.test.ts +377 -0
- package/test/spec.test.ts +469 -0
- package/tsconfig.json +15 -0
- package/dist/cli.d.ts +0 -0
- package/dist/cli.js +0 -454
- package/dist/config/index.d.ts +0 -19
- package/dist/config/index.js +0 -110
package/dist/cli.js
DELETED
|
@@ -1,454 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
3
|
-
OPENPKG_CONFIG_FILENAMES,
|
|
4
|
-
loadOpenPkgConfigInternal
|
|
5
|
-
} from "./config/index.js";
|
|
6
|
-
|
|
7
|
-
// src/cli.ts
|
|
8
|
-
import { readFileSync as readFileSync3 } from "node:fs";
|
|
9
|
-
import * as path4 from "node:path";
|
|
10
|
-
import { fileURLToPath } from "node:url";
|
|
11
|
-
import { Command } from "commander";
|
|
12
|
-
|
|
13
|
-
// src/commands/generate.ts
|
|
14
|
-
import * as fs2 from "node:fs";
|
|
15
|
-
import * as path2 from "node:path";
|
|
16
|
-
import chalk2 from "chalk";
|
|
17
|
-
import { OpenPkg } from "@openpkg-ts/sdk";
|
|
18
|
-
import { normalize, validateSpec } from "@openpkg-ts/spec";
|
|
19
|
-
import ora from "ora";
|
|
20
|
-
|
|
21
|
-
// src/utils/filter-options.ts
|
|
22
|
-
import chalk from "chalk";
|
|
23
|
-
var unique = (values) => Array.from(new Set(values));
|
|
24
|
-
var parseListFlag = (value) => {
|
|
25
|
-
if (!value) {
|
|
26
|
-
return;
|
|
27
|
-
}
|
|
28
|
-
const rawItems = Array.isArray(value) ? value : [value];
|
|
29
|
-
const normalized = rawItems.flatMap((item) => String(item).split(",")).map((item) => item.trim()).filter(Boolean);
|
|
30
|
-
return normalized.length > 0 ? unique(normalized) : undefined;
|
|
31
|
-
};
|
|
32
|
-
var formatList = (label, values) => `${label}: ${values.map((value) => chalk.cyan(value)).join(", ")}`;
|
|
33
|
-
var mergeFilterOptions = (config, cliOptions) => {
|
|
34
|
-
const messages = [];
|
|
35
|
-
const configInclude = config?.include;
|
|
36
|
-
const configExclude = config?.exclude;
|
|
37
|
-
const cliInclude = cliOptions.include;
|
|
38
|
-
const cliExclude = cliOptions.exclude;
|
|
39
|
-
let include = configInclude;
|
|
40
|
-
let exclude = configExclude;
|
|
41
|
-
let source = include || exclude ? "config" : undefined;
|
|
42
|
-
if (configInclude) {
|
|
43
|
-
messages.push(formatList("include filters from config", configInclude));
|
|
44
|
-
}
|
|
45
|
-
if (configExclude) {
|
|
46
|
-
messages.push(formatList("exclude filters from config", configExclude));
|
|
47
|
-
}
|
|
48
|
-
if (cliInclude) {
|
|
49
|
-
include = include ? include.filter((item) => cliInclude.includes(item)) : cliInclude;
|
|
50
|
-
source = include ? "combined" : "cli";
|
|
51
|
-
messages.push(formatList("apply include filters from CLI", cliInclude));
|
|
52
|
-
}
|
|
53
|
-
if (cliExclude) {
|
|
54
|
-
exclude = exclude ? unique([...exclude, ...cliExclude]) : cliExclude;
|
|
55
|
-
source = source ? "combined" : "cli";
|
|
56
|
-
messages.push(formatList("apply exclude filters from CLI", cliExclude));
|
|
57
|
-
}
|
|
58
|
-
include = include ? unique(include) : undefined;
|
|
59
|
-
exclude = exclude ? unique(exclude) : undefined;
|
|
60
|
-
if (!include && !exclude) {
|
|
61
|
-
return { messages };
|
|
62
|
-
}
|
|
63
|
-
return {
|
|
64
|
-
include,
|
|
65
|
-
exclude,
|
|
66
|
-
source,
|
|
67
|
-
messages
|
|
68
|
-
};
|
|
69
|
-
};
|
|
70
|
-
|
|
71
|
-
// src/utils/package-utils.ts
|
|
72
|
-
import * as fs from "node:fs";
|
|
73
|
-
import * as path from "node:path";
|
|
74
|
-
async function findEntryPoint(packageDir, preferSource = false) {
|
|
75
|
-
const packageJsonPath = path.join(packageDir, "package.json");
|
|
76
|
-
if (!fs.existsSync(packageJsonPath)) {
|
|
77
|
-
return findDefaultEntryPoint(packageDir);
|
|
78
|
-
}
|
|
79
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
80
|
-
if (preferSource) {
|
|
81
|
-
const srcIndex = path.join(packageDir, "src/index.ts");
|
|
82
|
-
if (fs.existsSync(srcIndex)) {
|
|
83
|
-
return srcIndex;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
if (!preferSource && (packageJson.types || packageJson.typings)) {
|
|
87
|
-
const typesPath = path.join(packageDir, packageJson.types || packageJson.typings);
|
|
88
|
-
if (fs.existsSync(typesPath)) {
|
|
89
|
-
return typesPath;
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
if (packageJson.exports) {
|
|
93
|
-
const exportPath = resolveExportsField(packageJson.exports, packageDir);
|
|
94
|
-
if (exportPath) {
|
|
95
|
-
return exportPath;
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
if (packageJson.main) {
|
|
99
|
-
const mainBase = packageJson.main.replace(/\.(js|mjs|cjs)$/, "");
|
|
100
|
-
const dtsPath = path.join(packageDir, `${mainBase}.d.ts`);
|
|
101
|
-
if (fs.existsSync(dtsPath)) {
|
|
102
|
-
return dtsPath;
|
|
103
|
-
}
|
|
104
|
-
const tsPath = path.join(packageDir, `${mainBase}.ts`);
|
|
105
|
-
if (fs.existsSync(tsPath)) {
|
|
106
|
-
return tsPath;
|
|
107
|
-
}
|
|
108
|
-
const mainPath = path.join(packageDir, packageJson.main);
|
|
109
|
-
if (fs.existsSync(mainPath) && fs.statSync(mainPath).isDirectory()) {
|
|
110
|
-
const indexDts = path.join(mainPath, "index.d.ts");
|
|
111
|
-
const indexTs = path.join(mainPath, "index.ts");
|
|
112
|
-
if (fs.existsSync(indexDts))
|
|
113
|
-
return indexDts;
|
|
114
|
-
if (fs.existsSync(indexTs))
|
|
115
|
-
return indexTs;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
return findDefaultEntryPoint(packageDir);
|
|
119
|
-
}
|
|
120
|
-
function resolveExportsField(exports, packageDir) {
|
|
121
|
-
if (typeof exports === "string") {
|
|
122
|
-
return findTypeScriptFile(path.join(packageDir, exports));
|
|
123
|
-
}
|
|
124
|
-
if (typeof exports === "object" && exports !== null && "." in exports) {
|
|
125
|
-
const dotExport = exports["."];
|
|
126
|
-
if (typeof dotExport === "string") {
|
|
127
|
-
return findTypeScriptFile(path.join(packageDir, dotExport));
|
|
128
|
-
}
|
|
129
|
-
if (dotExport && typeof dotExport === "object") {
|
|
130
|
-
const dotRecord = dotExport;
|
|
131
|
-
const typesEntry = dotRecord.types;
|
|
132
|
-
if (typeof typesEntry === "string") {
|
|
133
|
-
const typesPath = path.join(packageDir, typesEntry);
|
|
134
|
-
if (fs.existsSync(typesPath)) {
|
|
135
|
-
return typesPath;
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
for (const condition of ["import", "require", "default"]) {
|
|
139
|
-
const target = dotRecord[condition];
|
|
140
|
-
if (typeof target === "string") {
|
|
141
|
-
const result = findTypeScriptFile(path.join(packageDir, target));
|
|
142
|
-
if (result)
|
|
143
|
-
return result;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
return null;
|
|
149
|
-
}
|
|
150
|
-
function findTypeScriptFile(jsPath) {
|
|
151
|
-
if (!fs.existsSync(jsPath))
|
|
152
|
-
return null;
|
|
153
|
-
const dtsPath = jsPath.replace(/\.(js|mjs|cjs)$/, ".d.ts");
|
|
154
|
-
if (fs.existsSync(dtsPath)) {
|
|
155
|
-
return dtsPath;
|
|
156
|
-
}
|
|
157
|
-
const tsPath = jsPath.replace(/\.(js|mjs|cjs)$/, ".ts");
|
|
158
|
-
if (fs.existsSync(tsPath)) {
|
|
159
|
-
return tsPath;
|
|
160
|
-
}
|
|
161
|
-
return null;
|
|
162
|
-
}
|
|
163
|
-
async function findDefaultEntryPoint(packageDir) {
|
|
164
|
-
const candidates = [
|
|
165
|
-
"dist/index.d.ts",
|
|
166
|
-
"dist/index.ts",
|
|
167
|
-
"lib/index.d.ts",
|
|
168
|
-
"lib/index.ts",
|
|
169
|
-
"src/index.ts",
|
|
170
|
-
"index.d.ts",
|
|
171
|
-
"index.ts"
|
|
172
|
-
];
|
|
173
|
-
for (const candidate of candidates) {
|
|
174
|
-
const fullPath = path.join(packageDir, candidate);
|
|
175
|
-
if (fs.existsSync(fullPath)) {
|
|
176
|
-
return fullPath;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
throw new Error(`Could not find entry point in ${packageDir}`);
|
|
180
|
-
}
|
|
181
|
-
async function findPackageInMonorepo(rootDir, packageName) {
|
|
182
|
-
const rootPackageJsonPath = path.join(rootDir, "package.json");
|
|
183
|
-
if (!fs.existsSync(rootPackageJsonPath)) {
|
|
184
|
-
return null;
|
|
185
|
-
}
|
|
186
|
-
const rootPackageJson = JSON.parse(fs.readFileSync(rootPackageJsonPath, "utf-8"));
|
|
187
|
-
const workspacePatterns = Array.isArray(rootPackageJson.workspaces) ? rootPackageJson.workspaces : rootPackageJson.workspaces?.packages || [];
|
|
188
|
-
for (const pattern of workspacePatterns) {
|
|
189
|
-
const searchPath = path.join(rootDir, pattern.replace("/**", "").replace("/*", ""));
|
|
190
|
-
if (fs.existsSync(searchPath) && fs.statSync(searchPath).isDirectory()) {
|
|
191
|
-
const entries = fs.readdirSync(searchPath, { withFileTypes: true });
|
|
192
|
-
for (const entry of entries) {
|
|
193
|
-
if (entry.isDirectory()) {
|
|
194
|
-
const packagePath = path.join(searchPath, entry.name);
|
|
195
|
-
const packageJsonPath = path.join(packagePath, "package.json");
|
|
196
|
-
if (fs.existsSync(packageJsonPath)) {
|
|
197
|
-
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf-8"));
|
|
198
|
-
if (packageJson.name === packageName) {
|
|
199
|
-
return packagePath;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
}
|
|
206
|
-
return null;
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
// src/commands/generate.ts
|
|
210
|
-
var defaultDependencies = {
|
|
211
|
-
createOpenPkg: (options) => new OpenPkg(options),
|
|
212
|
-
writeFileSync: fs2.writeFileSync,
|
|
213
|
-
spinner: (text) => ora(text),
|
|
214
|
-
log: console.log,
|
|
215
|
-
error: console.error
|
|
216
|
-
};
|
|
217
|
-
function getArrayLength(value) {
|
|
218
|
-
return Array.isArray(value) ? value.length : 0;
|
|
219
|
-
}
|
|
220
|
-
function registerGenerateCommand(program, dependencies = {}) {
|
|
221
|
-
const { createOpenPkg, writeFileSync: writeFileSync2, spinner, log, error } = {
|
|
222
|
-
...defaultDependencies,
|
|
223
|
-
...dependencies
|
|
224
|
-
};
|
|
225
|
-
program.command("generate [entry]").description("Generate OpenPkg specification").option("-o, --output <file>", "Output file", "openpkg.json").option("-p, --package <name>", "Target package name (for monorepos)").option("--cwd <dir>", "Working directory", process.cwd()).option("--no-external-types", "Skip external type resolution from node_modules").option("--include <ids>", "Filter exports by identifier (comma-separated or repeated)").option("--exclude <ids>", "Exclude exports by identifier (comma-separated or repeated)").option("-y, --yes", "Skip all prompts and use defaults").action(async (entry, options) => {
|
|
226
|
-
try {
|
|
227
|
-
let targetDir = options.cwd;
|
|
228
|
-
let entryFile = entry;
|
|
229
|
-
if (options.package) {
|
|
230
|
-
const packageDir = await findPackageInMonorepo(options.cwd, options.package);
|
|
231
|
-
if (!packageDir) {
|
|
232
|
-
throw new Error(`Package "${options.package}" not found in monorepo`);
|
|
233
|
-
}
|
|
234
|
-
targetDir = packageDir;
|
|
235
|
-
log(chalk2.gray(`Found package at ${path2.relative(options.cwd, packageDir)}`));
|
|
236
|
-
}
|
|
237
|
-
if (!entryFile) {
|
|
238
|
-
entryFile = await findEntryPoint(targetDir, true);
|
|
239
|
-
log(chalk2.gray(`Auto-detected entry point: ${path2.relative(targetDir, entryFile)}`));
|
|
240
|
-
} else {
|
|
241
|
-
entryFile = path2.resolve(targetDir, entryFile);
|
|
242
|
-
}
|
|
243
|
-
const resolveExternalTypes = options.externalTypes !== false;
|
|
244
|
-
const cliFilters = {
|
|
245
|
-
include: parseListFlag(options.include),
|
|
246
|
-
exclude: parseListFlag(options.exclude)
|
|
247
|
-
};
|
|
248
|
-
let config = null;
|
|
249
|
-
try {
|
|
250
|
-
config = await loadOpenPkgConfigInternal(targetDir);
|
|
251
|
-
if (config?.filePath) {
|
|
252
|
-
log(chalk2.gray(`Loaded configuration from ${path2.relative(targetDir, config.filePath)}`));
|
|
253
|
-
}
|
|
254
|
-
} catch (configError) {
|
|
255
|
-
error(chalk2.red("Failed to load OpenPkg config:"), configError instanceof Error ? configError.message : configError);
|
|
256
|
-
process.exit(1);
|
|
257
|
-
}
|
|
258
|
-
const resolvedFilters = mergeFilterOptions(config, cliFilters);
|
|
259
|
-
for (const message of resolvedFilters.messages) {
|
|
260
|
-
log(chalk2.gray(`• ${message}`));
|
|
261
|
-
}
|
|
262
|
-
const spinnerInstance = spinner("Generating OpenPkg spec...");
|
|
263
|
-
spinnerInstance.start();
|
|
264
|
-
let result;
|
|
265
|
-
try {
|
|
266
|
-
const openpkg = createOpenPkg({
|
|
267
|
-
resolveExternalTypes
|
|
268
|
-
});
|
|
269
|
-
const analyzeOptions = resolvedFilters.include || resolvedFilters.exclude ? {
|
|
270
|
-
filters: {
|
|
271
|
-
include: resolvedFilters.include,
|
|
272
|
-
exclude: resolvedFilters.exclude
|
|
273
|
-
}
|
|
274
|
-
} : {};
|
|
275
|
-
result = await openpkg.analyzeFileWithDiagnostics(entryFile, analyzeOptions);
|
|
276
|
-
spinnerInstance.succeed("Generated OpenPkg spec");
|
|
277
|
-
} catch (generationError) {
|
|
278
|
-
spinnerInstance.fail("Failed to generate spec");
|
|
279
|
-
throw generationError;
|
|
280
|
-
}
|
|
281
|
-
if (!result) {
|
|
282
|
-
throw new Error("Failed to produce an OpenPkg spec.");
|
|
283
|
-
}
|
|
284
|
-
const outputPath = path2.resolve(targetDir, options.output);
|
|
285
|
-
const normalized = normalize(result.spec);
|
|
286
|
-
const validation = validateSpec(normalized);
|
|
287
|
-
if (!validation.ok) {
|
|
288
|
-
spinnerInstance.fail("Spec failed schema validation");
|
|
289
|
-
for (const err of validation.errors) {
|
|
290
|
-
error(chalk2.red(`schema: ${err.instancePath || "/"} ${err.message}`));
|
|
291
|
-
}
|
|
292
|
-
process.exit(1);
|
|
293
|
-
}
|
|
294
|
-
writeFileSync2(outputPath, JSON.stringify(normalized, null, 2));
|
|
295
|
-
log(chalk2.green(`✓ Generated ${path2.relative(process.cwd(), outputPath)}`));
|
|
296
|
-
log(chalk2.gray(` ${getArrayLength(normalized.exports)} exports`));
|
|
297
|
-
log(chalk2.gray(` ${getArrayLength(normalized.types)} types`));
|
|
298
|
-
if (result.diagnostics.length > 0) {
|
|
299
|
-
log("");
|
|
300
|
-
log(chalk2.bold("Diagnostics"));
|
|
301
|
-
for (const diagnostic of result.diagnostics) {
|
|
302
|
-
const prefix = diagnostic.severity === "error" ? chalk2.red("✖") : diagnostic.severity === "warning" ? chalk2.yellow("⚠") : chalk2.cyan("ℹ");
|
|
303
|
-
log(`${prefix} ${diagnostic.message}`);
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
} catch (commandError) {
|
|
307
|
-
error(chalk2.red("Error:"), commandError instanceof Error ? commandError.message : commandError);
|
|
308
|
-
process.exit(1);
|
|
309
|
-
}
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
// src/commands/init.ts
|
|
314
|
-
import * as fs3 from "node:fs";
|
|
315
|
-
import * as path3 from "node:path";
|
|
316
|
-
import chalk3 from "chalk";
|
|
317
|
-
var defaultDependencies2 = {
|
|
318
|
-
fileExists: fs3.existsSync,
|
|
319
|
-
writeFileSync: fs3.writeFileSync,
|
|
320
|
-
readFileSync: fs3.readFileSync,
|
|
321
|
-
log: console.log,
|
|
322
|
-
error: console.error
|
|
323
|
-
};
|
|
324
|
-
function registerInitCommand(program, dependencies = {}) {
|
|
325
|
-
const { fileExists, writeFileSync: writeFileSync3, readFileSync: readFileSync3, log, error } = {
|
|
326
|
-
...defaultDependencies2,
|
|
327
|
-
...dependencies
|
|
328
|
-
};
|
|
329
|
-
program.command("init").description("Create an OpenPkg configuration file").option("--cwd <dir>", "Working directory", process.cwd()).option("--format <format>", "Config format: auto, mjs, js, cjs", "auto").action((options) => {
|
|
330
|
-
const cwd = path3.resolve(options.cwd);
|
|
331
|
-
const formatOption = String(options.format ?? "auto").toLowerCase();
|
|
332
|
-
if (!isValidFormat(formatOption)) {
|
|
333
|
-
error(chalk3.red(`Invalid format "${formatOption}". Use auto, mjs, js, or cjs.`));
|
|
334
|
-
process.exitCode = 1;
|
|
335
|
-
return;
|
|
336
|
-
}
|
|
337
|
-
const existing = findExistingConfig(cwd, fileExists);
|
|
338
|
-
if (existing) {
|
|
339
|
-
error(chalk3.red(`An OpenPkg config already exists at ${path3.relative(cwd, existing) || "./openpkg.config.*"}.`));
|
|
340
|
-
process.exitCode = 1;
|
|
341
|
-
return;
|
|
342
|
-
}
|
|
343
|
-
const packageType = detectPackageType(cwd, fileExists, readFileSync3);
|
|
344
|
-
const targetFormat = resolveFormat(formatOption, packageType);
|
|
345
|
-
if (targetFormat === "js" && packageType !== "module") {
|
|
346
|
-
log(chalk3.yellow('Package is not marked as "type": "module"; creating openpkg.config.js may require enabling ESM.'));
|
|
347
|
-
}
|
|
348
|
-
const fileName = `openpkg.config.${targetFormat}`;
|
|
349
|
-
const outputPath = path3.join(cwd, fileName);
|
|
350
|
-
if (fileExists(outputPath)) {
|
|
351
|
-
error(chalk3.red(`Cannot create ${fileName}; file already exists.`));
|
|
352
|
-
process.exitCode = 1;
|
|
353
|
-
return;
|
|
354
|
-
}
|
|
355
|
-
const template = buildTemplate(targetFormat);
|
|
356
|
-
writeFileSync3(outputPath, template, { encoding: "utf8" });
|
|
357
|
-
log(chalk3.green(`✓ Created ${path3.relative(process.cwd(), outputPath)}`));
|
|
358
|
-
});
|
|
359
|
-
}
|
|
360
|
-
var isValidFormat = (value) => {
|
|
361
|
-
return value === "auto" || value === "mjs" || value === "js" || value === "cjs";
|
|
362
|
-
};
|
|
363
|
-
var findExistingConfig = (cwd, fileExists) => {
|
|
364
|
-
let current = path3.resolve(cwd);
|
|
365
|
-
const { root } = path3.parse(current);
|
|
366
|
-
while (true) {
|
|
367
|
-
for (const candidate of OPENPKG_CONFIG_FILENAMES) {
|
|
368
|
-
const candidatePath = path3.join(current, candidate);
|
|
369
|
-
if (fileExists(candidatePath)) {
|
|
370
|
-
return candidatePath;
|
|
371
|
-
}
|
|
372
|
-
}
|
|
373
|
-
if (current === root) {
|
|
374
|
-
break;
|
|
375
|
-
}
|
|
376
|
-
current = path3.dirname(current);
|
|
377
|
-
}
|
|
378
|
-
return null;
|
|
379
|
-
};
|
|
380
|
-
var detectPackageType = (cwd, fileExists, readFileSync3) => {
|
|
381
|
-
const packageJsonPath = findNearestPackageJson(cwd, fileExists);
|
|
382
|
-
if (!packageJsonPath) {
|
|
383
|
-
return;
|
|
384
|
-
}
|
|
385
|
-
try {
|
|
386
|
-
const raw = readFileSync3(packageJsonPath, "utf8");
|
|
387
|
-
const parsed = JSON.parse(raw);
|
|
388
|
-
if (parsed.type === "module") {
|
|
389
|
-
return "module";
|
|
390
|
-
}
|
|
391
|
-
if (parsed.type === "commonjs") {
|
|
392
|
-
return "commonjs";
|
|
393
|
-
}
|
|
394
|
-
} catch (_error) {}
|
|
395
|
-
return;
|
|
396
|
-
};
|
|
397
|
-
var findNearestPackageJson = (cwd, fileExists) => {
|
|
398
|
-
let current = path3.resolve(cwd);
|
|
399
|
-
const { root } = path3.parse(current);
|
|
400
|
-
while (true) {
|
|
401
|
-
const candidate = path3.join(current, "package.json");
|
|
402
|
-
if (fileExists(candidate)) {
|
|
403
|
-
return candidate;
|
|
404
|
-
}
|
|
405
|
-
if (current === root) {
|
|
406
|
-
break;
|
|
407
|
-
}
|
|
408
|
-
current = path3.dirname(current);
|
|
409
|
-
}
|
|
410
|
-
return null;
|
|
411
|
-
};
|
|
412
|
-
var resolveFormat = (format, packageType) => {
|
|
413
|
-
if (format === "auto") {
|
|
414
|
-
return packageType === "module" ? "js" : "mjs";
|
|
415
|
-
}
|
|
416
|
-
return format;
|
|
417
|
-
};
|
|
418
|
-
var buildTemplate = (format) => {
|
|
419
|
-
if (format === "cjs") {
|
|
420
|
-
return [
|
|
421
|
-
"const { defineConfig } = require('@openpkg-ts/cli/config');",
|
|
422
|
-
"",
|
|
423
|
-
"module.exports = defineConfig({",
|
|
424
|
-
" include: [],",
|
|
425
|
-
" exclude: [],",
|
|
426
|
-
"});",
|
|
427
|
-
""
|
|
428
|
-
].join(`
|
|
429
|
-
`);
|
|
430
|
-
}
|
|
431
|
-
return [
|
|
432
|
-
"import { defineConfig } from '@openpkg-ts/cli/config';",
|
|
433
|
-
"",
|
|
434
|
-
"export default defineConfig({",
|
|
435
|
-
" include: [],",
|
|
436
|
-
" exclude: [],",
|
|
437
|
-
"});",
|
|
438
|
-
""
|
|
439
|
-
].join(`
|
|
440
|
-
`);
|
|
441
|
-
};
|
|
442
|
-
|
|
443
|
-
// src/cli.ts
|
|
444
|
-
var __filename2 = fileURLToPath(import.meta.url);
|
|
445
|
-
var __dirname2 = path4.dirname(__filename2);
|
|
446
|
-
var packageJson = JSON.parse(readFileSync3(path4.join(__dirname2, "../package.json"), "utf-8"));
|
|
447
|
-
var program = new Command;
|
|
448
|
-
program.name("openpkg").description("Generate OpenPkg specification for TypeScript packages").version(packageJson.version);
|
|
449
|
-
registerGenerateCommand(program);
|
|
450
|
-
registerInitCommand(program);
|
|
451
|
-
program.command("*", { hidden: true }).action(() => {
|
|
452
|
-
program.outputHelp();
|
|
453
|
-
});
|
|
454
|
-
program.parseAsync();
|
package/dist/config/index.d.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
declare const stringList: z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>;
|
|
3
|
-
declare const openPkgConfigSchema: z.ZodObject<{
|
|
4
|
-
include: z.ZodOptional<typeof stringList>
|
|
5
|
-
exclude: z.ZodOptional<typeof stringList>
|
|
6
|
-
plugins: z.ZodOptional<z.ZodArray<z.ZodUnknown, "many">>
|
|
7
|
-
}>;
|
|
8
|
-
type OpenPkgConfigInput = z.infer<typeof openPkgConfigSchema>;
|
|
9
|
-
interface NormalizedOpenPkgConfig {
|
|
10
|
-
include?: string[];
|
|
11
|
-
exclude?: string[];
|
|
12
|
-
plugins?: unknown[];
|
|
13
|
-
}
|
|
14
|
-
interface LoadedOpenPkgConfig extends NormalizedOpenPkgConfig {
|
|
15
|
-
filePath: string;
|
|
16
|
-
}
|
|
17
|
-
declare const loadOpenPkgConfigInternal: (cwd: string) => Promise<LoadedOpenPkgConfig | null>;
|
|
18
|
-
declare const define: (config: OpenPkgConfigInput) => OpenPkgConfigInput;
|
|
19
|
-
export { loadOpenPkgConfigInternal as loadOpenPkgConfig, define as defineConfig, NormalizedOpenPkgConfig, LoadedOpenPkgConfig };
|
package/dist/config/index.js
DELETED
|
@@ -1,110 +0,0 @@
|
|
|
1
|
-
// src/config/openpkg-config.ts
|
|
2
|
-
import { access } from "node:fs/promises";
|
|
3
|
-
import path from "node:path";
|
|
4
|
-
import { pathToFileURL } from "node:url";
|
|
5
|
-
|
|
6
|
-
// src/config/schema.ts
|
|
7
|
-
import { z } from "zod";
|
|
8
|
-
var stringList = z.union([
|
|
9
|
-
z.string(),
|
|
10
|
-
z.array(z.string())
|
|
11
|
-
]);
|
|
12
|
-
var openPkgConfigSchema = z.object({
|
|
13
|
-
include: stringList.optional(),
|
|
14
|
-
exclude: stringList.optional(),
|
|
15
|
-
plugins: z.array(z.unknown()).optional()
|
|
16
|
-
});
|
|
17
|
-
var normalizeList = (value) => {
|
|
18
|
-
if (!value) {
|
|
19
|
-
return;
|
|
20
|
-
}
|
|
21
|
-
const list = Array.isArray(value) ? value : [value];
|
|
22
|
-
const normalized = list.map((item) => item.trim()).filter(Boolean);
|
|
23
|
-
return normalized.length > 0 ? normalized : undefined;
|
|
24
|
-
};
|
|
25
|
-
var normalizeConfig = (input) => {
|
|
26
|
-
const include = normalizeList(input.include);
|
|
27
|
-
const exclude = normalizeList(input.exclude);
|
|
28
|
-
return {
|
|
29
|
-
include,
|
|
30
|
-
exclude,
|
|
31
|
-
plugins: input.plugins
|
|
32
|
-
};
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
// src/config/openpkg-config.ts
|
|
36
|
-
var OPENPKG_CONFIG_FILENAMES = [
|
|
37
|
-
"openpkg.config.ts",
|
|
38
|
-
"openpkg.config.mts",
|
|
39
|
-
"openpkg.config.cts",
|
|
40
|
-
"openpkg.config.js",
|
|
41
|
-
"openpkg.config.mjs",
|
|
42
|
-
"openpkg.config.cjs"
|
|
43
|
-
];
|
|
44
|
-
var fileExists = async (filePath) => {
|
|
45
|
-
try {
|
|
46
|
-
await access(filePath);
|
|
47
|
-
return true;
|
|
48
|
-
} catch {
|
|
49
|
-
return false;
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
var findConfigFile = async (cwd) => {
|
|
53
|
-
let current = path.resolve(cwd);
|
|
54
|
-
const { root } = path.parse(current);
|
|
55
|
-
while (true) {
|
|
56
|
-
for (const candidate of OPENPKG_CONFIG_FILENAMES) {
|
|
57
|
-
const candidatePath = path.join(current, candidate);
|
|
58
|
-
if (await fileExists(candidatePath)) {
|
|
59
|
-
return candidatePath;
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
if (current === root) {
|
|
63
|
-
return null;
|
|
64
|
-
}
|
|
65
|
-
current = path.dirname(current);
|
|
66
|
-
}
|
|
67
|
-
};
|
|
68
|
-
var importConfigModule = async (absolutePath) => {
|
|
69
|
-
const fileUrl = pathToFileURL(absolutePath);
|
|
70
|
-
fileUrl.searchParams.set("t", Date.now().toString());
|
|
71
|
-
const module = await import(fileUrl.href);
|
|
72
|
-
return module?.default ?? module?.config ?? module;
|
|
73
|
-
};
|
|
74
|
-
var formatIssues = (issues) => issues.map((issue) => `- ${issue}`).join(`
|
|
75
|
-
`);
|
|
76
|
-
var loadOpenPkgConfigInternal = async (cwd) => {
|
|
77
|
-
const configPath = await findConfigFile(cwd);
|
|
78
|
-
if (!configPath) {
|
|
79
|
-
return null;
|
|
80
|
-
}
|
|
81
|
-
let rawConfig;
|
|
82
|
-
try {
|
|
83
|
-
rawConfig = await importConfigModule(configPath);
|
|
84
|
-
} catch (error) {
|
|
85
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
86
|
-
throw new Error(`Failed to load OpenPkg config at ${configPath}: ${message}`);
|
|
87
|
-
}
|
|
88
|
-
const parsed = openPkgConfigSchema.safeParse(rawConfig);
|
|
89
|
-
if (!parsed.success) {
|
|
90
|
-
const issues = parsed.error.issues.map((issue) => {
|
|
91
|
-
const pathLabel = issue.path.length > 0 ? issue.path.join(".") : "(root)";
|
|
92
|
-
return `${pathLabel}: ${issue.message}`;
|
|
93
|
-
});
|
|
94
|
-
throw new Error(`Invalid OpenPkg configuration at ${configPath}.
|
|
95
|
-
${formatIssues(issues)}`);
|
|
96
|
-
}
|
|
97
|
-
const normalized = normalizeConfig(parsed.data);
|
|
98
|
-
return {
|
|
99
|
-
filePath: configPath,
|
|
100
|
-
...normalized
|
|
101
|
-
};
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
// src/config/index.ts
|
|
105
|
-
var define = (config) => config;
|
|
106
|
-
export {
|
|
107
|
-
loadOpenPkgConfigInternal as loadOpenPkgConfig,
|
|
108
|
-
define as defineConfig
|
|
109
|
-
};
|
|
110
|
-
export { OPENPKG_CONFIG_FILENAMES, loadOpenPkgConfigInternal };
|