hyouji 0.0.5 → 0.0.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +2 -1
  2. package/dist/index.js +117 -71
  3. package/package.json +6 -1
package/README.md CHANGED
@@ -16,7 +16,8 @@ https://levelup.gitconnected.com/create-github-labels-from-terminal-158d4868fab
16
16
 
17
17
  ![hyouji_terminal](./hyouji.png)
18
18
 
19
- https://user-images.githubusercontent.com/474225/130368605-b5c6410f-53f6-4ef0-b321-8950edeebf7d.mov
19
+ https://github.com/user-attachments/assets/739f185a-1bd0-411b-8947-dd4600c452c8
20
+
20
21
 
21
22
  ### Labels API
22
23
 
package/dist/index.js CHANGED
@@ -280,17 +280,34 @@ const createLabels = async (configs2) => {
280
280
  log$2("Created all labels");
281
281
  log$2(chalk.bgBlueBright(extraGuideText));
282
282
  };
283
- const deleteLabel = (configs2, labelNames) => {
284
- labelNames.forEach(async (labelName) => {
285
- await configs2.octokit.request(
286
- "DELETE /repos/{owner}/{repo}/labels/{name}",
287
- {
288
- owner: configs2.owner,
289
- repo: configs2.repo,
290
- name: labelName
283
+ const deleteLabel = async (configs2, labelNames) => {
284
+ for (const labelName of labelNames) {
285
+ try {
286
+ const resp = await configs2.octokit.request(
287
+ "DELETE /repos/{owner}/{repo}/labels/{name}",
288
+ {
289
+ owner: configs2.owner,
290
+ repo: configs2.repo,
291
+ name: labelName
292
+ }
293
+ );
294
+ if (resp.status === 204) {
295
+ log$2(chalk.green(`${resp.status}: Deleted ${labelName}`));
296
+ } else {
297
+ log$2(chalk.yellow(`${resp.status}: Something wrong with ${labelName}`));
291
298
  }
292
- );
293
- });
299
+ } catch (error) {
300
+ if (error && typeof error === "object" && "status" in error && error.status === 404) {
301
+ log$2(chalk.red(`404: Label "${labelName}" not found`));
302
+ } else {
303
+ log$2(
304
+ chalk.red(
305
+ `Error deleting label "${labelName}": ${error instanceof Error ? error.message : "Unknown error"}`
306
+ )
307
+ );
308
+ }
309
+ }
310
+ }
294
311
  };
295
312
  const getLabels = async (configs2) => {
296
313
  const resp = await configs2.octokit.request(
@@ -310,18 +327,39 @@ const getLabels = async (configs2) => {
310
327
  };
311
328
  const deleteLabels = async (configs2) => {
312
329
  const names = await getLabels(configs2);
313
- names.forEach(async (name) => {
314
- await configs2.octokit.request(
315
- "DELETE /repos/{owner}/{repo}/labels/{name}",
316
- {
317
- owner: configs2.owner,
318
- repo: configs2.repo,
319
- name
330
+ if (names.length === 0) {
331
+ log$2(chalk.yellow("No labels found to delete"));
332
+ return;
333
+ }
334
+ log$2(chalk.blue(`Deleting ${names.length} labels...`));
335
+ for (const name of names) {
336
+ try {
337
+ const resp = await configs2.octokit.request(
338
+ "DELETE /repos/{owner}/{repo}/labels/{name}",
339
+ {
340
+ owner: configs2.owner,
341
+ repo: configs2.repo,
342
+ name
343
+ }
344
+ );
345
+ if (resp.status === 204) {
346
+ log$2(chalk.green(`${resp.status}: Deleted ${name}`));
347
+ } else {
348
+ log$2(chalk.yellow(`${resp.status}: Something wrong with ${name}`));
320
349
  }
321
- );
322
- });
323
- log$2("");
324
- names.forEach((label) => log$2(chalk.bgGreen(`deleted ${label}`)));
350
+ } catch (error) {
351
+ if (error && typeof error === "object" && "status" in error && error.status === 404) {
352
+ log$2(chalk.red(`404: Label "${name}" not found`));
353
+ } else {
354
+ log$2(
355
+ chalk.red(
356
+ `Error deleting label "${name}": ${error instanceof Error ? error.message : "Unknown error"}`
357
+ )
358
+ );
359
+ }
360
+ }
361
+ }
362
+ log$2(chalk.blue("Finished deleting labels"));
325
363
  log$2(chalk.bgBlueBright(extraGuideText));
326
364
  };
327
365
  const _CryptoUtils = class _CryptoUtils {
@@ -1247,9 +1285,9 @@ const displaySettings = async () => {
1247
1285
  log(chalk.cyan("========================\n"));
1248
1286
  };
1249
1287
  let configs;
1250
- const main = async () => {
1288
+ const initializeConfigs = async () => {
1251
1289
  let hasValidConfig = false;
1252
- if (firstStart && configManager.configExists()) {
1290
+ if (configManager.configExists()) {
1253
1291
  try {
1254
1292
  const existingConfig = await configManager.loadValidatedConfig();
1255
1293
  if (existingConfig && existingConfig.config && !existingConfig.shouldPromptForCredentials) {
@@ -1268,58 +1306,66 @@ const main = async () => {
1268
1306
  `Please go to ${linkToPersonalToken} and generate a personal token!`
1269
1307
  )
1270
1308
  );
1271
- return;
1309
+ return null;
1272
1310
  }
1273
1311
  }
1274
- if (firstStart) {
1312
+ try {
1313
+ const asciiText = await getAsciiText();
1314
+ if (asciiText != null) {
1315
+ log(asciiText);
1316
+ }
1317
+ } catch (error) {
1318
+ console.warn("Failed to display ASCII art, continuing...");
1319
+ console.error("Error:", error);
1320
+ }
1321
+ if (hasValidConfig) {
1275
1322
  try {
1276
- const asciiText = await getAsciiText();
1277
- if (asciiText != null) {
1278
- log(asciiText);
1323
+ const existingConfig = await configManager.loadValidatedConfig();
1324
+ if (existingConfig && existingConfig.config) {
1325
+ const repoResponse = await prompts([
1326
+ {
1327
+ type: "text",
1328
+ name: "repo",
1329
+ message: "Please type your target repo name"
1330
+ }
1331
+ ]);
1332
+ const config = {
1333
+ octokit: new Octokit({ auth: existingConfig.config.token }),
1334
+ owner: existingConfig.config.owner,
1335
+ repo: repoResponse.repo,
1336
+ fromSavedConfig: true
1337
+ };
1338
+ log(chalk.green(`Using saved configuration for ${config.owner}`));
1339
+ return config;
1340
+ } else {
1341
+ return await setupConfigs();
1279
1342
  }
1280
1343
  } catch (error) {
1281
- console.warn("Failed to display ASCII art, continuing...");
1282
1344
  console.error("Error:", error);
1345
+ return await setupConfigs();
1283
1346
  }
1284
- if (hasValidConfig) {
1285
- try {
1286
- const existingConfig = await configManager.loadValidatedConfig();
1287
- if (existingConfig && existingConfig.config) {
1288
- const repoResponse = await prompts([
1289
- {
1290
- type: "text",
1291
- name: "repo",
1292
- message: "Please type your target repo name"
1293
- }
1294
- ]);
1295
- configs = {
1296
- octokit: new Octokit({ auth: existingConfig.config.token }),
1297
- owner: existingConfig.config.owner,
1298
- repo: repoResponse.repo,
1299
- fromSavedConfig: true
1300
- };
1301
- log(chalk.green(`Using saved configuration for ${configs.owner}`));
1302
- } else {
1303
- configs = await setupConfigs();
1304
- }
1305
- } catch (error) {
1306
- console.error("Error:", error);
1307
- configs = await setupConfigs();
1308
- }
1309
- } else {
1310
- try {
1311
- configs = await setupConfigs();
1312
- if (configs.fromSavedConfig) {
1313
- log(chalk.green(`Using saved configuration for ${configs.owner}`));
1314
- }
1315
- } catch (error) {
1316
- log(
1317
- chalk.red(
1318
- `Configuration error: ${error instanceof Error ? error.message : "Unknown error"}`
1319
- )
1320
- );
1321
- return;
1347
+ } else {
1348
+ try {
1349
+ const config = await setupConfigs();
1350
+ if (config.fromSavedConfig) {
1351
+ log(chalk.green(`Using saved configuration for ${config.owner}`));
1322
1352
  }
1353
+ return config;
1354
+ } catch (error) {
1355
+ log(
1356
+ chalk.red(
1357
+ `Configuration error: ${error instanceof Error ? error.message : "Unknown error"}`
1358
+ )
1359
+ );
1360
+ return null;
1361
+ }
1362
+ }
1363
+ };
1364
+ const main = async () => {
1365
+ if (firstStart) {
1366
+ configs = await initializeConfigs();
1367
+ if (!configs) {
1368
+ return;
1323
1369
  }
1324
1370
  }
1325
1371
  let selectedIndex = await selectAction();
@@ -1329,23 +1375,23 @@ const main = async () => {
1329
1375
  switch (selectedIndex) {
1330
1376
  case 0: {
1331
1377
  const newLabel2 = await getNewLabel();
1332
- createLabel(configs, newLabel2);
1378
+ await createLabel(configs, newLabel2);
1333
1379
  firstStart = firstStart && false;
1334
1380
  break;
1335
1381
  }
1336
1382
  case 1: {
1337
- createLabels(configs);
1383
+ await createLabels(configs);
1338
1384
  firstStart = firstStart && false;
1339
1385
  break;
1340
1386
  }
1341
1387
  case 2: {
1342
1388
  const targetLabel = await getTargetLabel();
1343
- deleteLabel(configs, targetLabel);
1389
+ await deleteLabel(configs, targetLabel);
1344
1390
  firstStart = firstStart && false;
1345
1391
  break;
1346
1392
  }
1347
1393
  case 3: {
1348
- deleteLabels(configs);
1394
+ await deleteLabels(configs);
1349
1395
  firstStart = firstStart && false;
1350
1396
  break;
1351
1397
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hyouji",
3
- "version": "0.0.5",
3
+ "version": "0.0.6",
4
4
  "description": "Hyouji (表示) — A command-line tool for organizing and displaying GitHub labels with clarity and harmony.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -35,6 +35,11 @@
35
35
  "test:coverage": "vitest run --coverage",
36
36
  "test:lint": "eslint src --ext .ts",
37
37
  "test:prettier": "prettier \"src/**/*.ts\" --list-different",
38
+ "test:error-handling": "node tests/scripts/error-handling/run-all.cjs",
39
+ "test:config": "node tests/scripts/config/run-all.cjs",
40
+ "test:integration": "node tests/scripts/run-integration.cjs",
41
+ "test:verification": "node tests/scripts/verification/run-all.cjs",
42
+ "test:all-custom": "npm run test:error-handling && npm run test:config && npm run test:integration && npm run test:verification",
38
43
  "check-cli": "run-s test diff-integration-tests check-integration-tests",
39
44
  "check-integration-tests": "run-s check-integration-test:*",
40
45
  "diff-integration-tests": "mkdir -p diff && rm -rf diff/test && cp -r test diff/test && rm -rf diff/test/test-*/.git && cd diff && git init --quiet && git add -A && git commit --quiet --no-verify --allow-empty -m 'WIP' && echo '\\n\\nCommitted most recent integration test output in the \"diff\" directory. Review the changes with \"cd diff && git diff HEAD\" or your preferred git diff viewer.'",