@asagiri-design/labels-config 0.2.2 → 0.3.1
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 +62 -0
- package/dist/chunk-MM4GCVPE.mjs +549 -0
- package/dist/cli.js +522 -98
- package/dist/cli.mjs +256 -103
- package/dist/github/index.d.mts +49 -1
- package/dist/github/index.d.ts +49 -1
- package/dist/github/index.js +212 -0
- package/dist/github/index.mjs +3 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/docs/BATCH_SYNC.md +396 -0
- package/docs/NPM_SETUP.md +200 -0
- package/docs/QUICK_START.md +457 -0
- package/docs/RELEASE_FLOW.md +436 -0
- package/package.json +3 -6
- package/dist/chunk-4ZUJQMV7.mjs +0 -285
- package/dist/chunk-DGUMSQAI.mjs +0 -496
- package/dist/chunk-ZYHIDOG2.mjs +0 -247
package/dist/cli.mjs
CHANGED
|
@@ -11,15 +11,75 @@ import {
|
|
|
11
11
|
validateWithDetails
|
|
12
12
|
} from "./chunk-VU2JB66N.mjs";
|
|
13
13
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
14
|
+
BatchLabelSync,
|
|
15
|
+
GitHubLabelSync,
|
|
16
|
+
Spinner,
|
|
17
|
+
colorize,
|
|
18
|
+
error,
|
|
19
|
+
header,
|
|
20
|
+
info,
|
|
21
|
+
success,
|
|
22
|
+
warning
|
|
23
|
+
} from "./chunk-MM4GCVPE.mjs";
|
|
24
|
+
import "./chunk-QZ7TP4HQ.mjs";
|
|
19
25
|
|
|
20
26
|
// src/cli.ts
|
|
21
27
|
import { promises as fs } from "fs";
|
|
22
28
|
|
|
29
|
+
// src/config/batch-config.ts
|
|
30
|
+
var BatchConfigLoader = class {
|
|
31
|
+
/**
|
|
32
|
+
* バッチ設定ファイルの読み込み
|
|
33
|
+
*/
|
|
34
|
+
static async load(filePath) {
|
|
35
|
+
const { promises: fs2 } = await import("fs");
|
|
36
|
+
try {
|
|
37
|
+
const content = await fs2.readFile(filePath, "utf-8");
|
|
38
|
+
const config = JSON.parse(content);
|
|
39
|
+
this.validate(config);
|
|
40
|
+
return config;
|
|
41
|
+
} catch (error2) {
|
|
42
|
+
throw new Error(`Failed to load batch config: ${error2}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* バッチ設定のバリデーション
|
|
47
|
+
*/
|
|
48
|
+
static validate(config) {
|
|
49
|
+
if (!config.version) {
|
|
50
|
+
throw new Error("Batch config version is required");
|
|
51
|
+
}
|
|
52
|
+
if (!config.targets || config.targets.length === 0) {
|
|
53
|
+
throw new Error("At least one target is required");
|
|
54
|
+
}
|
|
55
|
+
config.targets.forEach((target, index) => {
|
|
56
|
+
const hasRepoSpec = target.organization || target.user || target.repositories;
|
|
57
|
+
if (!hasRepoSpec) {
|
|
58
|
+
throw new Error(`Target ${index}: One of organization, user, or repositories is required`);
|
|
59
|
+
}
|
|
60
|
+
const hasLabelSpec = target.template || target.file;
|
|
61
|
+
if (!hasLabelSpec) {
|
|
62
|
+
throw new Error(`Target ${index}: Either template or file is required`);
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* BatchConfigTargetをBatchSyncOptionsに変換
|
|
68
|
+
*/
|
|
69
|
+
static targetToOptions(target, defaults) {
|
|
70
|
+
return {
|
|
71
|
+
organization: target.organization,
|
|
72
|
+
user: target.user,
|
|
73
|
+
repositories: target.repositories,
|
|
74
|
+
template: target.template || defaults?.template,
|
|
75
|
+
mode: target.mode || defaults?.mode || "append",
|
|
76
|
+
parallel: target.parallel || defaults?.parallel || 3,
|
|
77
|
+
filter: target.filter,
|
|
78
|
+
dryRun: false
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
23
83
|
// src/utils/args.ts
|
|
24
84
|
function parseArgs(argv) {
|
|
25
85
|
const result = {
|
|
@@ -77,104 +137,6 @@ function getPositional(args, index) {
|
|
|
77
137
|
return args.positional[index];
|
|
78
138
|
}
|
|
79
139
|
|
|
80
|
-
// src/utils/ui.ts
|
|
81
|
-
var colors = {
|
|
82
|
-
reset: "\x1B[0m",
|
|
83
|
-
bright: "\x1B[1m",
|
|
84
|
-
dim: "\x1B[2m",
|
|
85
|
-
// Foreground colors
|
|
86
|
-
red: "\x1B[31m",
|
|
87
|
-
green: "\x1B[32m",
|
|
88
|
-
yellow: "\x1B[33m",
|
|
89
|
-
blue: "\x1B[34m",
|
|
90
|
-
magenta: "\x1B[35m",
|
|
91
|
-
cyan: "\x1B[36m",
|
|
92
|
-
white: "\x1B[37m",
|
|
93
|
-
gray: "\x1B[90m",
|
|
94
|
-
// Background colors
|
|
95
|
-
bgRed: "\x1B[41m",
|
|
96
|
-
bgGreen: "\x1B[42m",
|
|
97
|
-
bgYellow: "\x1B[43m",
|
|
98
|
-
bgBlue: "\x1B[44m"
|
|
99
|
-
};
|
|
100
|
-
function supportsColor() {
|
|
101
|
-
if (process.env.NO_COLOR) {
|
|
102
|
-
return false;
|
|
103
|
-
}
|
|
104
|
-
if (process.env.FORCE_COLOR) {
|
|
105
|
-
return true;
|
|
106
|
-
}
|
|
107
|
-
if (!process.stdout.isTTY) {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
if (process.platform === "win32") {
|
|
111
|
-
return true;
|
|
112
|
-
}
|
|
113
|
-
return true;
|
|
114
|
-
}
|
|
115
|
-
function colorize(text, color) {
|
|
116
|
-
if (!supportsColor()) {
|
|
117
|
-
return text;
|
|
118
|
-
}
|
|
119
|
-
return `${colors[color]}${text}${colors.reset}`;
|
|
120
|
-
}
|
|
121
|
-
function success(message) {
|
|
122
|
-
return colorize("\u2713", "green") + " " + message;
|
|
123
|
-
}
|
|
124
|
-
function error(message) {
|
|
125
|
-
return colorize("\u2717", "red") + " " + message;
|
|
126
|
-
}
|
|
127
|
-
function warning(message) {
|
|
128
|
-
return colorize("\u26A0", "yellow") + " " + message;
|
|
129
|
-
}
|
|
130
|
-
function info(message) {
|
|
131
|
-
return colorize("\u2139", "blue") + " " + message;
|
|
132
|
-
}
|
|
133
|
-
function header(text) {
|
|
134
|
-
return "\n" + colorize(text, "bright") + "\n" + "\u2500".repeat(Math.min(text.length, 50));
|
|
135
|
-
}
|
|
136
|
-
var Spinner = class {
|
|
137
|
-
constructor() {
|
|
138
|
-
__publicField(this, "frames", ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"]);
|
|
139
|
-
__publicField(this, "interval", null);
|
|
140
|
-
__publicField(this, "frameIndex", 0);
|
|
141
|
-
__publicField(this, "message", "");
|
|
142
|
-
}
|
|
143
|
-
start(message) {
|
|
144
|
-
this.message = message;
|
|
145
|
-
if (!process.stdout.isTTY || !supportsColor()) {
|
|
146
|
-
console.log(message + "...");
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
this.interval = setInterval(() => {
|
|
150
|
-
const frame = this.frames[this.frameIndex];
|
|
151
|
-
process.stdout.write(`\r${colorize(frame, "cyan")} ${this.message}`);
|
|
152
|
-
this.frameIndex = (this.frameIndex + 1) % this.frames.length;
|
|
153
|
-
}, 80);
|
|
154
|
-
}
|
|
155
|
-
succeed(message) {
|
|
156
|
-
this.stop();
|
|
157
|
-
console.log(success(message || this.message));
|
|
158
|
-
}
|
|
159
|
-
fail(message) {
|
|
160
|
-
this.stop();
|
|
161
|
-
console.log(error(message || this.message));
|
|
162
|
-
}
|
|
163
|
-
warn(message) {
|
|
164
|
-
this.stop();
|
|
165
|
-
console.log(warning(message || this.message));
|
|
166
|
-
}
|
|
167
|
-
stop() {
|
|
168
|
-
if (this.interval) {
|
|
169
|
-
clearInterval(this.interval);
|
|
170
|
-
this.interval = null;
|
|
171
|
-
if (process.stdout.isTTY) {
|
|
172
|
-
process.stdout.write("\r\x1B[K");
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
|
|
178
140
|
// src/cli.ts
|
|
179
141
|
var rawArgs = process.argv.slice(2);
|
|
180
142
|
var parsedArgs = parseArgs(rawArgs);
|
|
@@ -183,6 +145,8 @@ function printUsage() {
|
|
|
183
145
|
console.log(header("Commands"));
|
|
184
146
|
console.log(" " + colorize("validate", "cyan") + " <file> Validate label configuration file");
|
|
185
147
|
console.log(" " + colorize("sync", "cyan") + " Sync labels to GitHub repository");
|
|
148
|
+
console.log(" " + colorize("batch-sync", "cyan") + " Sync labels to multiple repositories");
|
|
149
|
+
console.log(" " + colorize("batch-config", "cyan") + " <file> Sync using batch configuration file");
|
|
186
150
|
console.log(" " + colorize("export", "cyan") + " Export labels from GitHub repository");
|
|
187
151
|
console.log(" " + colorize("init", "cyan") + " <template> Initialize new configuration");
|
|
188
152
|
console.log(" " + colorize("help", "cyan") + " Show this help message");
|
|
@@ -194,6 +158,13 @@ function printUsage() {
|
|
|
194
158
|
console.log(" " + colorize("--owner", "green") + " <owner> Repository owner (required for sync/export)");
|
|
195
159
|
console.log(" " + colorize("--repo", "green") + " <repo> Repository name (required for sync/export)");
|
|
196
160
|
console.log(" " + colorize("--file", "green") + " <file> Configuration file path");
|
|
161
|
+
console.log(" " + colorize("--template", "green") + " <name> Template name (for batch-sync)");
|
|
162
|
+
console.log(" " + colorize("--org", "green") + " <org> Organization name (for batch-sync)");
|
|
163
|
+
console.log(" " + colorize("--user", "green") + " <user> User name (for batch-sync)");
|
|
164
|
+
console.log(" " + colorize("--repos", "green") + " <repos> Comma-separated repository list");
|
|
165
|
+
console.log(" " + colorize("--parallel", "green") + " <num> Number of parallel executions (default: 3)");
|
|
166
|
+
console.log(" " + colorize("--filter-lang", "green") + " <lang> Filter by programming language");
|
|
167
|
+
console.log(" " + colorize("--filter-vis", "green") + " <vis> Filter by visibility (public/private/all)");
|
|
197
168
|
console.log(" " + colorize("--dry-run", "green") + " Dry run mode (don't make changes)");
|
|
198
169
|
console.log(" " + colorize("--delete-extra", "green") + " Replace mode: delete labels not in config");
|
|
199
170
|
console.log(" " + colorize("--verbose", "green") + " Verbose output");
|
|
@@ -220,6 +191,18 @@ function printUsage() {
|
|
|
220
191
|
console.log(" # Sync with dry run");
|
|
221
192
|
console.log(" " + colorize("labels-config sync --owner user --repo repo --file labels.json --dry-run", "gray"));
|
|
222
193
|
console.log("");
|
|
194
|
+
console.log(" # Batch sync to all org repositories");
|
|
195
|
+
console.log(" " + colorize("labels-config batch-sync --org your-org --template prod-ja --dry-run", "gray"));
|
|
196
|
+
console.log("");
|
|
197
|
+
console.log(" # Batch sync to specific repositories");
|
|
198
|
+
console.log(" " + colorize("labels-config batch-sync --repos your-org/repo1,your-org/repo2 --file labels.json", "gray"));
|
|
199
|
+
console.log("");
|
|
200
|
+
console.log(" # Batch sync with filters");
|
|
201
|
+
console.log(" " + colorize("labels-config batch-sync --user your-username --template react --filter-lang TypeScript --filter-vis public", "gray"));
|
|
202
|
+
console.log("");
|
|
203
|
+
console.log(" # Batch sync using config file");
|
|
204
|
+
console.log(" " + colorize("labels-config batch-config batch-config.json --dry-run", "gray"));
|
|
205
|
+
console.log("");
|
|
223
206
|
}
|
|
224
207
|
async function validateCommand() {
|
|
225
208
|
const file = getPositional(parsedArgs, 0);
|
|
@@ -405,6 +388,170 @@ async function initCommand() {
|
|
|
405
388
|
process.exit(1);
|
|
406
389
|
}
|
|
407
390
|
}
|
|
391
|
+
async function batchSyncCommand() {
|
|
392
|
+
const spinner = new Spinner();
|
|
393
|
+
try {
|
|
394
|
+
const file = getOption(parsedArgs, "--file");
|
|
395
|
+
const template = getOption(parsedArgs, "--template");
|
|
396
|
+
const org = getOption(parsedArgs, "--org");
|
|
397
|
+
const user = getOption(parsedArgs, "--user");
|
|
398
|
+
const reposOption = getOption(parsedArgs, "--repos");
|
|
399
|
+
const parallel = parseInt(getOption(parsedArgs, "--parallel") || "3");
|
|
400
|
+
const filterLang = getOption(parsedArgs, "--filter-lang");
|
|
401
|
+
const filterVis = getOption(parsedArgs, "--filter-vis");
|
|
402
|
+
const dryRun = hasFlag(parsedArgs, "--dry-run");
|
|
403
|
+
const deleteExtra = hasFlag(parsedArgs, "--delete-extra");
|
|
404
|
+
if (!file && !template) {
|
|
405
|
+
console.error(error("Error: Either --file or --template is required for batch-sync"));
|
|
406
|
+
console.log(info("Available templates: ") + listTemplates().map((t) => colorize(t, "magenta")).join(", "));
|
|
407
|
+
process.exit(1);
|
|
408
|
+
}
|
|
409
|
+
if (!org && !user && !reposOption) {
|
|
410
|
+
console.error(error("Error: One of --org, --user, or --repos is required"));
|
|
411
|
+
console.log(info("Specify target repositories using:"));
|
|
412
|
+
console.log(" --org <organization> (sync all org repos)");
|
|
413
|
+
console.log(" --user <username> (sync all user repos)");
|
|
414
|
+
console.log(" --repos owner/repo1,owner/repo2 (specific repos)");
|
|
415
|
+
process.exit(1);
|
|
416
|
+
}
|
|
417
|
+
let labels;
|
|
418
|
+
if (file) {
|
|
419
|
+
try {
|
|
420
|
+
await fs.access(file);
|
|
421
|
+
} catch {
|
|
422
|
+
console.error(error(`File not found: ${file}`));
|
|
423
|
+
process.exit(1);
|
|
424
|
+
}
|
|
425
|
+
spinner.start(`Loading labels from ${file}`);
|
|
426
|
+
const content = await fs.readFile(file, "utf-8");
|
|
427
|
+
const loader = new ConfigLoader();
|
|
428
|
+
labels = loader.loadFromString(content);
|
|
429
|
+
spinner.succeed(`Loaded ${labels.length} labels from file`);
|
|
430
|
+
} else if (template) {
|
|
431
|
+
if (!listTemplates().includes(template)) {
|
|
432
|
+
console.error(error(`Invalid template "${template}"`));
|
|
433
|
+
console.log(info("Available templates: ") + listTemplates().map((t) => colorize(t, "magenta")).join(", "));
|
|
434
|
+
process.exit(1);
|
|
435
|
+
}
|
|
436
|
+
spinner.start(`Loading "${template}" template`);
|
|
437
|
+
labels = CONFIG_TEMPLATES[template];
|
|
438
|
+
spinner.succeed(`Loaded ${labels.length} labels from "${template}" template`);
|
|
439
|
+
} else {
|
|
440
|
+
throw new Error("Either --file or --template is required");
|
|
441
|
+
}
|
|
442
|
+
const repositories = reposOption ? reposOption.split(",").map((r) => r.trim()) : void 0;
|
|
443
|
+
const batchSync = new BatchLabelSync();
|
|
444
|
+
const options = {
|
|
445
|
+
repositories,
|
|
446
|
+
organization: org,
|
|
447
|
+
user,
|
|
448
|
+
template,
|
|
449
|
+
mode: deleteExtra ? "replace" : "append",
|
|
450
|
+
dryRun,
|
|
451
|
+
parallel,
|
|
452
|
+
filter: {
|
|
453
|
+
visibility: filterVis,
|
|
454
|
+
language: filterLang,
|
|
455
|
+
archived: false
|
|
456
|
+
}
|
|
457
|
+
};
|
|
458
|
+
const modeText = dryRun ? colorize("[DRY RUN] ", "yellow") : "";
|
|
459
|
+
console.log(`
|
|
460
|
+
${modeText}${header("Batch Sync Configuration")}`);
|
|
461
|
+
console.log(info(`Labels: ${labels.length}`));
|
|
462
|
+
if (org) console.log(info(`Organization: ${org}`));
|
|
463
|
+
if (user) console.log(info(`User: ${user}`));
|
|
464
|
+
if (repositories) console.log(info(`Repositories: ${repositories.length} specified`));
|
|
465
|
+
if (filterLang) console.log(info(`Filter (language): ${filterLang}`));
|
|
466
|
+
if (filterVis) console.log(info(`Filter (visibility): ${filterVis}`));
|
|
467
|
+
console.log(info(`Parallel: ${parallel}`));
|
|
468
|
+
console.log(info(`Mode: ${deleteExtra ? "replace" : "append"}`));
|
|
469
|
+
const results = await batchSync.syncMultiple(labels, options);
|
|
470
|
+
const summary = batchSync.generateSummary(results);
|
|
471
|
+
console.log(summary);
|
|
472
|
+
const hasErrors = results.some((r) => r.status === "failed");
|
|
473
|
+
if (hasErrors) {
|
|
474
|
+
process.exit(1);
|
|
475
|
+
}
|
|
476
|
+
} catch (err) {
|
|
477
|
+
spinner.fail("Batch sync failed");
|
|
478
|
+
console.error(error(err instanceof Error ? err.message : String(err)));
|
|
479
|
+
process.exit(1);
|
|
480
|
+
}
|
|
481
|
+
}
|
|
482
|
+
async function batchConfigCommand() {
|
|
483
|
+
const configFile = getPositional(parsedArgs, 0);
|
|
484
|
+
const dryRun = hasFlag(parsedArgs, "--dry-run");
|
|
485
|
+
const spinner = new Spinner();
|
|
486
|
+
if (!configFile) {
|
|
487
|
+
console.error(error("Configuration file path required"));
|
|
488
|
+
console.error("Usage: labels-config batch-config <file>");
|
|
489
|
+
console.log(info("Example: labels-config batch-config batch-config.json --dry-run"));
|
|
490
|
+
process.exit(1);
|
|
491
|
+
}
|
|
492
|
+
try {
|
|
493
|
+
spinner.start(`Loading batch configuration from ${configFile}`);
|
|
494
|
+
const config = await BatchConfigLoader.load(configFile);
|
|
495
|
+
spinner.succeed(`Loaded batch configuration with ${config.targets.length} targets`);
|
|
496
|
+
const modeText = dryRun ? colorize("[DRY RUN] ", "yellow") : "";
|
|
497
|
+
console.log(`
|
|
498
|
+
${modeText}${header("Batch Configuration")}`);
|
|
499
|
+
console.log(info(`Version: ${config.version}`));
|
|
500
|
+
if (config.description) console.log(info(`Description: ${config.description}`));
|
|
501
|
+
console.log(info(`Targets: ${config.targets.length}`));
|
|
502
|
+
let totalSuccess = 0;
|
|
503
|
+
let totalFailed = 0;
|
|
504
|
+
for (let i = 0; i < config.targets.length; i++) {
|
|
505
|
+
const target = config.targets[i];
|
|
506
|
+
console.log(`
|
|
507
|
+
${header(`Target ${i + 1}/${config.targets.length}`)}`);
|
|
508
|
+
let labels;
|
|
509
|
+
if (target.file) {
|
|
510
|
+
spinner.start(`Loading labels from ${target.file}`);
|
|
511
|
+
const content = await fs.readFile(target.file, "utf-8");
|
|
512
|
+
const loader = new ConfigLoader();
|
|
513
|
+
labels = loader.loadFromString(content);
|
|
514
|
+
spinner.succeed(`Loaded ${labels.length} labels`);
|
|
515
|
+
} else if (target.template) {
|
|
516
|
+
const templateName = target.template || config.defaults?.template;
|
|
517
|
+
if (!templateName || !listTemplates().includes(templateName)) {
|
|
518
|
+
console.error(error(`Invalid template "${templateName}"`));
|
|
519
|
+
continue;
|
|
520
|
+
}
|
|
521
|
+
spinner.start(`Loading "${templateName}" template`);
|
|
522
|
+
labels = CONFIG_TEMPLATES[templateName];
|
|
523
|
+
spinner.succeed(`Loaded ${labels.length} labels`);
|
|
524
|
+
} else {
|
|
525
|
+
console.error(error("No template or file specified"));
|
|
526
|
+
continue;
|
|
527
|
+
}
|
|
528
|
+
const batchSync = new BatchLabelSync();
|
|
529
|
+
const options = BatchConfigLoader.targetToOptions(target, config.defaults);
|
|
530
|
+
options.dryRun = dryRun;
|
|
531
|
+
console.log(info(`Mode: ${options.mode}`));
|
|
532
|
+
if (target.organization) console.log(info(`Organization: ${target.organization}`));
|
|
533
|
+
if (target.user) console.log(info(`User: ${target.user}`));
|
|
534
|
+
if (target.repositories) console.log(info(`Repositories: ${target.repositories.length}`));
|
|
535
|
+
const results = await batchSync.syncMultiple(labels, options);
|
|
536
|
+
const successful = results.filter((r) => r.status === "success").length;
|
|
537
|
+
const failed = results.filter((r) => r.status === "failed").length;
|
|
538
|
+
totalSuccess += successful;
|
|
539
|
+
totalFailed += failed;
|
|
540
|
+
console.log(success(`Target ${i + 1}: ${successful} successful, ${failed} failed`));
|
|
541
|
+
}
|
|
542
|
+
console.log(`
|
|
543
|
+
${header("Overall Summary")}`);
|
|
544
|
+
console.log(success(`Total successful: ${totalSuccess}`));
|
|
545
|
+
if (totalFailed > 0) {
|
|
546
|
+
console.log(error(`Total failed: ${totalFailed}`));
|
|
547
|
+
process.exit(1);
|
|
548
|
+
}
|
|
549
|
+
} catch (err) {
|
|
550
|
+
spinner.fail("Batch config execution failed");
|
|
551
|
+
console.error(error(err instanceof Error ? err.message : String(err)));
|
|
552
|
+
process.exit(1);
|
|
553
|
+
}
|
|
554
|
+
}
|
|
408
555
|
async function main() {
|
|
409
556
|
const command = parsedArgs.command;
|
|
410
557
|
if (!command || command === "help" || hasFlag(parsedArgs, "--help", "-h")) {
|
|
@@ -418,6 +565,12 @@ async function main() {
|
|
|
418
565
|
case "sync":
|
|
419
566
|
await syncCommand();
|
|
420
567
|
break;
|
|
568
|
+
case "batch-sync":
|
|
569
|
+
await batchSyncCommand();
|
|
570
|
+
break;
|
|
571
|
+
case "batch-config":
|
|
572
|
+
await batchConfigCommand();
|
|
573
|
+
break;
|
|
421
574
|
case "export":
|
|
422
575
|
await exportCommand();
|
|
423
576
|
break;
|
package/dist/github/index.d.mts
CHANGED
|
@@ -110,4 +110,52 @@ declare class GitHubLabelSync {
|
|
|
110
110
|
updateLabel(name: string, updates: Partial<LabelConfig>): Promise<void>;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
interface BatchSyncOptions {
|
|
114
|
+
repositories?: string[];
|
|
115
|
+
organization?: string;
|
|
116
|
+
user?: string;
|
|
117
|
+
template?: string;
|
|
118
|
+
mode?: 'append' | 'replace';
|
|
119
|
+
dryRun?: boolean;
|
|
120
|
+
parallel?: number;
|
|
121
|
+
filter?: {
|
|
122
|
+
visibility?: 'public' | 'private' | 'all';
|
|
123
|
+
language?: string;
|
|
124
|
+
archived?: boolean;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
interface BatchSyncResult {
|
|
128
|
+
repository: string;
|
|
129
|
+
status: 'success' | 'failed' | 'skipped';
|
|
130
|
+
result?: any;
|
|
131
|
+
error?: string;
|
|
132
|
+
}
|
|
133
|
+
declare class BatchLabelSync {
|
|
134
|
+
private static readonly DEFAULT_PARALLEL;
|
|
135
|
+
/**
|
|
136
|
+
* 複数リポジトリへのラベル一括同期
|
|
137
|
+
*/
|
|
138
|
+
syncMultiple(labels: LabelConfig[], options: BatchSyncOptions): Promise<BatchSyncResult[]>;
|
|
139
|
+
/**
|
|
140
|
+
* 単一リポジトリへの同期
|
|
141
|
+
*/
|
|
142
|
+
private syncSingleRepo;
|
|
143
|
+
/**
|
|
144
|
+
* 対象リポジトリリストの取得
|
|
145
|
+
*/
|
|
146
|
+
private getTargetRepositories;
|
|
147
|
+
/**
|
|
148
|
+
* 組織のリポジトリ一覧を取得
|
|
149
|
+
*/
|
|
150
|
+
private getOrganizationRepos;
|
|
151
|
+
/**
|
|
152
|
+
* ユーザーのリポジトリ一覧を取得
|
|
153
|
+
*/
|
|
154
|
+
private getUserRepos;
|
|
155
|
+
/**
|
|
156
|
+
* 結果サマリーの生成
|
|
157
|
+
*/
|
|
158
|
+
generateSummary(results: BatchSyncResult[]): string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { BatchLabelSync, type BatchSyncOptions, type BatchSyncResult, GitHubClient, type GitHubClientOptions, type GitHubLabel, GitHubLabelSync, type GitHubSyncOptions };
|
package/dist/github/index.d.ts
CHANGED
|
@@ -110,4 +110,52 @@ declare class GitHubLabelSync {
|
|
|
110
110
|
updateLabel(name: string, updates: Partial<LabelConfig>): Promise<void>;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
|
|
113
|
+
interface BatchSyncOptions {
|
|
114
|
+
repositories?: string[];
|
|
115
|
+
organization?: string;
|
|
116
|
+
user?: string;
|
|
117
|
+
template?: string;
|
|
118
|
+
mode?: 'append' | 'replace';
|
|
119
|
+
dryRun?: boolean;
|
|
120
|
+
parallel?: number;
|
|
121
|
+
filter?: {
|
|
122
|
+
visibility?: 'public' | 'private' | 'all';
|
|
123
|
+
language?: string;
|
|
124
|
+
archived?: boolean;
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
interface BatchSyncResult {
|
|
128
|
+
repository: string;
|
|
129
|
+
status: 'success' | 'failed' | 'skipped';
|
|
130
|
+
result?: any;
|
|
131
|
+
error?: string;
|
|
132
|
+
}
|
|
133
|
+
declare class BatchLabelSync {
|
|
134
|
+
private static readonly DEFAULT_PARALLEL;
|
|
135
|
+
/**
|
|
136
|
+
* 複数リポジトリへのラベル一括同期
|
|
137
|
+
*/
|
|
138
|
+
syncMultiple(labels: LabelConfig[], options: BatchSyncOptions): Promise<BatchSyncResult[]>;
|
|
139
|
+
/**
|
|
140
|
+
* 単一リポジトリへの同期
|
|
141
|
+
*/
|
|
142
|
+
private syncSingleRepo;
|
|
143
|
+
/**
|
|
144
|
+
* 対象リポジトリリストの取得
|
|
145
|
+
*/
|
|
146
|
+
private getTargetRepositories;
|
|
147
|
+
/**
|
|
148
|
+
* 組織のリポジトリ一覧を取得
|
|
149
|
+
*/
|
|
150
|
+
private getOrganizationRepos;
|
|
151
|
+
/**
|
|
152
|
+
* ユーザーのリポジトリ一覧を取得
|
|
153
|
+
*/
|
|
154
|
+
private getUserRepos;
|
|
155
|
+
/**
|
|
156
|
+
* 結果サマリーの生成
|
|
157
|
+
*/
|
|
158
|
+
generateSummary(results: BatchSyncResult[]): string;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
export { BatchLabelSync, type BatchSyncOptions, type BatchSyncResult, GitHubClient, type GitHubClientOptions, type GitHubLabel, GitHubLabelSync, type GitHubSyncOptions };
|