@s-hirano-ist/s-scripts 4.1.0 → 4.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +8 -0
  2. package/dist/{chunk-7XX57D7G.js → chunk-3INTMHPH.js} +1 -1
  3. package/dist/chunk-4CXH2QIX.js +445 -0
  4. package/dist/chunk-67LIMNXH.js +36 -0
  5. package/dist/{chunk-OCEV2QX3.js → chunk-BYEEIQ7O.js} +1 -1
  6. package/dist/{chunk-2PZXXOYG.js → chunk-GBQOCN2C.js} +24 -25
  7. package/dist/chunk-MJYGMGH5.js +382 -0
  8. package/dist/chunk-MVYAZJB2.js +160 -0
  9. package/dist/{chunk-DIG75T3J.js → chunk-RLAYINCA.js} +10 -13
  10. package/dist/{chunk-MNBEFEFR.js → chunk-RO5QUZFR.js} +1 -1
  11. package/dist/chunk-SFKQ2RAP.js +87 -0
  12. package/dist/{chunk-FVK44UTM.js → chunk-ZMQUO6OA.js} +1 -1
  13. package/dist/cleanup-minio-images.js +62 -91
  14. package/dist/enrich-books.js +6 -4
  15. package/dist/fetch-articles.js +6 -24
  16. package/dist/fetch-books.js +12 -35
  17. package/dist/fetch-images.js +12 -35
  18. package/dist/fetch-notes.js +6 -24
  19. package/dist/find-duplicate-json-articles.js +11 -13
  20. package/dist/fix-book-frontmatter.js +6 -4
  21. package/dist/fix-image-formats.js +7 -5
  22. package/dist/ingest-articles.js +7 -5
  23. package/dist/ingest-books.js +10 -8
  24. package/dist/ingest-images.js +7 -5
  25. package/dist/ingest-notes.js +10 -8
  26. package/dist/rag/delete-collection.js +5 -30
  27. package/dist/rag/ingest.js +5 -379
  28. package/dist/rag/search.js +5 -84
  29. package/dist/reset-articles.js +8 -23
  30. package/dist/reset-books.js +8 -23
  31. package/dist/reset-images.js +8 -23
  32. package/dist/reset-notes.js +8 -23
  33. package/dist/revert-articles.js +8 -23
  34. package/dist/revert-books.js +8 -23
  35. package/dist/revert-images.js +8 -23
  36. package/dist/revert-notes.js +8 -23
  37. package/dist/s-content-format.js +9 -11
  38. package/dist/update-json-articles.js +19 -41
  39. package/dist/update-raw-articles.js +14 -37
  40. package/dist/validate-json-articles.js +8 -5
  41. package/package.json +13 -11
  42. package/dist/chunk-7PVU2Z32.js +0 -71
  43. package/dist/chunk-F4J6JBR4.js +0 -115
@@ -2,7 +2,7 @@ import { createRequire as __cliCreateRequire } from "node:module"; const require
2
2
  import {
3
3
  makeExportedAt,
4
4
  withTransactionRetry
5
- } from "./chunk-DIG75T3J.js";
5
+ } from "./chunk-RLAYINCA.js";
6
6
 
7
7
  // ../application/dist/batch/books-batch-service.js
8
8
  var BooksBatchApplicationService = class {
@@ -0,0 +1,87 @@
1
+ import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
2
+ import {
3
+ ensureCollection,
4
+ search
5
+ } from "./chunk-J4VLH4VA.js";
6
+ import "./chunk-JZOR5GA2.js";
7
+
8
+ // src/rag/search-command.ts
9
+ function parseArgs() {
10
+ const args = process.argv.slice(2);
11
+ const options = {};
12
+ const positional = [];
13
+ for (let i = 0; i < args.length; i++) {
14
+ const arg = args[i];
15
+ if (arg === "--top-k" && i + 1 < args.length) {
16
+ options.topK = Number(args[++i]);
17
+ } else if (arg === "--type" && i + 1 < args.length) {
18
+ options.type = args[++i];
19
+ } else if (arg === "--heading" && i + 1 < args.length) {
20
+ options.heading = args[++i];
21
+ } else if (arg === "--content-type" && i + 1 < args.length) {
22
+ const value = args[++i];
23
+ const types = value.split(",");
24
+ options.contentType = types.length === 1 ? types[0] : types;
25
+ } else {
26
+ positional.push(arg);
27
+ }
28
+ }
29
+ const query = positional.join(" ");
30
+ if (!query) {
31
+ console.error(
32
+ "Usage: rag-search <query> [--top-k N] [--type markdown_note|bookmark_json] [--heading HEADING] [--content-type articles|books|notes]"
33
+ );
34
+ process.exitCode = 1;
35
+ return void 0;
36
+ }
37
+ return { query, options };
38
+ }
39
+ async function searchContent(query, options = {}) {
40
+ const results = await search(query, {
41
+ topK: options.topK,
42
+ filter: {
43
+ type: options.type,
44
+ top_heading: options.heading,
45
+ content_type: options.contentType
46
+ }
47
+ });
48
+ return { results, query, totalResults: results.length };
49
+ }
50
+ async function search2() {
51
+ const args = parseArgs();
52
+ if (!args) return;
53
+ const { query, options } = args;
54
+ console.log(`Searching for: "${query}"`);
55
+ if (options.topK) console.log(` top-k: ${options.topK}`);
56
+ if (options.type) console.log(` type: ${options.type}`);
57
+ if (options.heading) console.log(` heading: ${options.heading}`);
58
+ if (options.contentType)
59
+ console.log(
60
+ ` content-type: ${Array.isArray(options.contentType) ? options.contentType.join(",") : options.contentType}`
61
+ );
62
+ console.log();
63
+ await ensureCollection();
64
+ const response = await searchContent(query, options);
65
+ console.log(`Found ${response.totalResults} results:
66
+ `);
67
+ for (const [i, result] of response.results.entries()) {
68
+ console.log(`--- Result ${i + 1} (score: ${result.score.toFixed(4)}) ---`);
69
+ console.log(`Title: ${result.title}`);
70
+ if (result.url) console.log(`URL: ${result.url}`);
71
+ console.log(`Type: ${result.type}`);
72
+ console.log(`Content-Type: ${result.content_type}`);
73
+ console.log(`Heading: ${result.heading_path.join(" > ")}`);
74
+ console.log(`
75
+ ${result.text}
76
+ `);
77
+ }
78
+ }
79
+ async function main() {
80
+ if (!process.env.QDRANT_URL) {
81
+ throw new Error("QDRANT_URL environment variable is required.");
82
+ }
83
+ await search2();
84
+ }
85
+ export {
86
+ main
87
+ };
@@ -2,7 +2,7 @@ import { createRequire as __cliCreateRequire } from "node:module"; const require
2
2
  import {
3
3
  makeExportedAt,
4
4
  withTransactionRetry
5
- } from "./chunk-DIG75T3J.js";
5
+ } from "./chunk-RLAYINCA.js";
6
6
 
7
7
  // ../application/dist/batch/images-batch-service.js
8
8
  var ImagesBatchApplicationService = class {
@@ -1,14 +1,16 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
- import {
4
- createMinioClient
5
- } from "./chunk-F4J6JBR4.js";
6
- import {
7
- createPushoverService
8
- } from "./chunk-7PVU2Z32.js";
9
3
  import {
10
4
  globPaths
11
5
  } from "./chunk-AJMTRCPJ.js";
6
+ import {
7
+ createObjectStorageClient
8
+ } from "./chunk-MVYAZJB2.js";
9
+ import {
10
+ cliNotifications,
11
+ reportCliError,
12
+ runCli
13
+ } from "./chunk-4CXH2QIX.js";
12
14
  import "./chunk-JZOR5GA2.js";
13
15
 
14
16
  // src/cleanup-minio-images.ts
@@ -21,108 +23,77 @@ function isImageFile(filePath) {
21
23
  return [".jpg", ".jpeg", ".png", ".webp"].includes(ext);
22
24
  }
23
25
  function listObjects(client, bucket, prefix) {
24
- const { promise, resolve, reject } = Promise.withResolvers();
25
- const keys = [];
26
- const stream = client.listObjectsV2(bucket, prefix, true);
27
- stream.on("data", (obj) => {
28
- if (obj.name) keys.push(obj.name);
29
- });
30
- stream.on("end", () => resolve(keys));
31
- stream.on("error", reject);
32
- return promise;
26
+ return client.listObjects(bucket, prefix);
33
27
  }
34
28
  async function main() {
35
29
  const dryRun = process.argv.includes("--dry-run");
36
30
  const env = {
37
- PUSHOVER_URL: process.env.PUSHOVER_URL,
38
- PUSHOVER_USER_KEY: process.env.PUSHOVER_USER_KEY,
39
- PUSHOVER_APP_TOKEN: process.env.PUSHOVER_APP_TOKEN,
40
- MINIO_BUCKET_NAME: process.env.MINIO_BUCKET_NAME
31
+ S3_BUCKET_NAME: process.env.S3_BUCKET_NAME
41
32
  };
42
33
  if (Object.values(env).some((v) => !v)) {
43
34
  throw new Error("Required environment variables are not set.");
44
35
  }
45
- if (process.env.MINIO_USE_SSL === "true" && (!process.env.CF_ACCESS_CLIENT_ID || !process.env.CF_ACCESS_CLIENT_SECRET)) {
46
- throw new Error(
47
- "CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when MINIO_USE_SSL is true."
48
- );
49
- }
50
36
  const contentsPath = process.env.S_CONTENTS_PATH ?? process.cwd();
51
- const notificationService = createPushoverService({
52
- url: env.PUSHOVER_URL ?? "",
53
- userKey: env.PUSHOVER_USER_KEY ?? "",
54
- appToken: env.PUSHOVER_APP_TOKEN ?? ""
55
- });
56
- const minioClient = createMinioClient();
57
- const bucketName = env.MINIO_BUCKET_NAME ?? "";
58
- try {
59
- const localFiles = await globPaths(`${contentsPath}/image/dump/*`);
60
- const localFileNames = new Set(
61
- localFiles.filter((f) => isImageFile(f)).map((f) => basename(f))
62
- );
63
- console.log(
64
- `\u{1F4C1} \u30ED\u30FC\u30AB\u30EB\u306B ${localFileNames.size} \u4EF6\u306E\u753B\u50CF\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\u3002`
65
- );
66
- const [originalKeys, thumbnailKeys] = await Promise.all([
67
- listObjects(minioClient, bucketName, `${ORIGINAL_IMAGE_PATH}/`),
68
- listObjects(minioClient, bucketName, `${THUMBNAIL_IMAGE_PATH}/`)
69
- ]);
70
- console.log(
71
- `\u{1F4E6} MinIO: original ${originalKeys.length} \u4EF6, thumbnail ${thumbnailKeys.length} \u4EF6`
72
- );
73
- const orphanedOriginals = originalKeys.filter(
74
- (key) => !localFileNames.has(basename(key))
75
- );
76
- const orphanedThumbnails = thumbnailKeys.filter(
77
- (key) => !localFileNames.has(basename(key))
78
- );
79
- const totalOrphaned = orphanedOriginals.length + orphanedThumbnails.length;
80
- if (totalOrphaned === 0) {
81
- console.log("\u2705 \u5B64\u7ACB\u30D5\u30A1\u30A4\u30EB\u306A\u3057");
37
+ const notificationService = cliNotifications;
38
+ const storageClient = createObjectStorageClient();
39
+ const bucketName = env.S3_BUCKET_NAME ?? "";
40
+ const localFiles = await globPaths(`${contentsPath}/image/dump/*`);
41
+ const localFileNames = new Set(
42
+ localFiles.filter((f) => isImageFile(f)).map((f) => basename(f))
43
+ );
44
+ console.log(
45
+ `\u{1F4C1} \u30ED\u30FC\u30AB\u30EB\u306B ${localFileNames.size} \u4EF6\u306E\u753B\u50CF\u30D5\u30A1\u30A4\u30EB\u3092\u691C\u51FA\u3057\u307E\u3057\u305F\u3002`
46
+ );
47
+ const [originalKeys, thumbnailKeys] = await Promise.all([
48
+ listObjects(storageClient, bucketName, `${ORIGINAL_IMAGE_PATH}/`),
49
+ listObjects(storageClient, bucketName, `${THUMBNAIL_IMAGE_PATH}/`)
50
+ ]);
51
+ console.log(
52
+ `\u{1F4E6} S3: original ${originalKeys.length} \u4EF6, thumbnail ${thumbnailKeys.length} \u4EF6`
53
+ );
54
+ const orphanedOriginals = originalKeys.filter(
55
+ (key) => !localFileNames.has(basename(key))
56
+ );
57
+ const orphanedThumbnails = thumbnailKeys.filter(
58
+ (key) => !localFileNames.has(basename(key))
59
+ );
60
+ const totalOrphaned = orphanedOriginals.length + orphanedThumbnails.length;
61
+ if (totalOrphaned === 0) {
62
+ console.log("\u2705 \u5B64\u7ACB\u30D5\u30A1\u30A4\u30EB\u306A\u3057");
63
+ if (!dryRun)
82
64
  await notificationService.notifyInfo(
83
65
  `${SCRIPT_NAME} completed: no orphaned files`,
84
66
  { caller: SCRIPT_NAME }
85
67
  );
86
- return;
87
- }
88
- console.log(
89
- `\u{1F5D1}\uFE0F \u5B64\u7ACB\u30D5\u30A1\u30A4\u30EB\u691C\u51FA: original ${orphanedOriginals.length} \u4EF6, thumbnail ${orphanedThumbnails.length} \u4EF6`
90
- );
91
- let deletedCount = 0;
92
- let errorCount = 0;
93
- for (const key of [...orphanedOriginals, ...orphanedThumbnails]) {
94
- try {
95
- if (dryRun) {
96
- console.log(`\u{1F50D} [dry-run] \u524A\u9664\u4E88\u5B9A: ${key}`);
97
- } else {
98
- await minioClient.removeObject(bucketName, key);
99
- console.log(`\u{1F5D1}\uFE0F \u524A\u9664: ${key}`);
100
- }
101
- deletedCount++;
102
- } catch (error) {
103
- console.error(`\u274C \u524A\u9664\u30A8\u30E9\u30FC\uFF08${key}\uFF09:`, error);
104
- errorCount++;
68
+ return;
69
+ }
70
+ console.log(
71
+ `\u{1F5D1}\uFE0F \u5B64\u7ACB\u30D5\u30A1\u30A4\u30EB\u691C\u51FA: original ${orphanedOriginals.length} \u4EF6, thumbnail ${orphanedThumbnails.length} \u4EF6`
72
+ );
73
+ let deletedCount = 0;
74
+ let errorCount = 0;
75
+ for (const key of [...orphanedOriginals, ...orphanedThumbnails]) {
76
+ try {
77
+ if (dryRun) {
78
+ console.log(`\u{1F50D} [dry-run] \u524A\u9664\u4E88\u5B9A: ${key}`);
79
+ } else {
80
+ await storageClient.removeObject(bucketName, key);
81
+ console.log(`\u{1F5D1}\uFE0F \u524A\u9664: ${key}`);
105
82
  }
83
+ deletedCount++;
84
+ } catch (error) {
85
+ reportCliError(error, "cleanup-minio-images");
86
+ console.error(`\u274C \u524A\u9664\u30A8\u30E9\u30FC\uFF08${key}\uFF09:`, error);
87
+ errorCount++;
106
88
  }
107
- console.log(
108
- `
89
+ }
90
+ console.log(
91
+ `
109
92
  \u{1F4CA} \u7D50\u679C: \u524A\u9664 ${deletedCount} \u4EF6, \u30A8\u30E9\u30FC ${errorCount} \u4EF6${dryRun ? " (dry-run)" : ""}`
110
- );
93
+ );
94
+ if (!dryRun)
111
95
  await notificationService.notifyInfo(`${SCRIPT_NAME} completed`, {
112
96
  caller: SCRIPT_NAME
113
97
  });
114
- } catch (error) {
115
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
116
- await notificationService.notifyError(
117
- `${SCRIPT_NAME} failed: ${String(error)}`,
118
- {
119
- caller: SCRIPT_NAME
120
- }
121
- );
122
- process.exit(1);
123
- }
124
98
  }
125
- main().catch((error) => {
126
- console.error(error);
127
- process.exit(1);
128
- });
99
+ await runCli("cleanup-minio-images", main);
@@ -6,6 +6,10 @@ import {
6
6
  import {
7
7
  globPaths
8
8
  } from "./chunk-AJMTRCPJ.js";
9
+ import {
10
+ reportCliError,
11
+ runCli
12
+ } from "./chunk-4CXH2QIX.js";
9
13
  import "./chunk-JZOR5GA2.js";
10
14
 
11
15
  // src/enrich-books.ts
@@ -85,6 +89,7 @@ ${body}`;
85
89
  }
86
90
  enrichedCount++;
87
91
  } catch (error) {
92
+ reportCliError(error, "enrich-books");
88
93
  console.error(`\u274C ${fileName}:`, error);
89
94
  errorCount++;
90
95
  }
@@ -94,7 +99,4 @@ ${body}`;
94
99
  \u{1F4CA} \u7D50\u679C: \u66F4\u65B0 ${enrichedCount} \u4EF6, \u30A8\u30E9\u30FC ${errorCount} \u4EF6${dryRun ? " (dry-run)" : ""}`
95
100
  );
96
101
  }
97
- main().catch((error) => {
98
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
99
- process.exit(1);
100
- });
102
+ await runCli("enrich-books", main);
@@ -4,10 +4,11 @@ import {
4
4
  createPrismaClient,
5
5
  makeUnexportedStatus,
6
6
  makeUserId
7
- } from "./chunk-DIG75T3J.js";
7
+ } from "./chunk-RLAYINCA.js";
8
8
  import {
9
- createPushoverService
10
- } from "./chunk-7PVU2Z32.js";
9
+ cliNotifications,
10
+ runCli
11
+ } from "./chunk-4CXH2QIX.js";
11
12
  import "./chunk-JZOR5GA2.js";
12
13
 
13
14
  // src/fetch-articles.ts
@@ -50,20 +51,13 @@ async function exportData(data) {
50
51
  async function main() {
51
52
  const env = {
52
53
  DATABASE_URL: process.env.DATABASE_URL,
53
- PUSHOVER_URL: process.env.PUSHOVER_URL,
54
- PUSHOVER_USER_KEY: process.env.PUSHOVER_USER_KEY,
55
- PUSHOVER_APP_TOKEN: process.env.PUSHOVER_APP_TOKEN,
56
54
  USERNAME_TO_EXPORT: process.env.USERNAME_TO_EXPORT
57
55
  };
58
56
  if (Object.values(env).some((v) => !v)) {
59
57
  throw new Error("Required environment variables are not set.");
60
58
  }
61
59
  const prisma = createPrismaClient(env.DATABASE_URL ?? "");
62
- const notificationService = createPushoverService({
63
- url: env.PUSHOVER_URL ?? "",
64
- userKey: env.PUSHOVER_USER_KEY ?? "",
65
- appToken: env.PUSHOVER_APP_TOKEN ?? ""
66
- });
60
+ const notificationService = cliNotifications;
67
61
  const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
68
62
  const UNEXPORTED = makeUnexportedStatus();
69
63
  async function fetchArticles() {
@@ -96,20 +90,8 @@ async function main() {
96
90
  await notificationService.notifyInfo("fetch-articles completed", {
97
91
  caller: "fetch-articles"
98
92
  });
99
- } catch (error) {
100
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
101
- await notificationService.notifyError(
102
- `fetch-articles failed: ${String(error)}`,
103
- {
104
- caller: "fetch-articles"
105
- }
106
- );
107
- process.exit(1);
108
93
  } finally {
109
94
  await prisma.$disconnect();
110
95
  }
111
96
  }
112
- main().catch((error) => {
113
- console.error(error);
114
- process.exit(1);
115
- });
97
+ await runCli("fetch-articles", main);
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
3
  import {
4
- createMinioClient
5
- } from "./chunk-F4J6JBR4.js";
4
+ createObjectStorageClient
5
+ } from "./chunk-MVYAZJB2.js";
6
6
  import {
7
7
  createPrismaClient,
8
8
  makeUnexportedStatus,
9
9
  makeUserId
10
- } from "./chunk-DIG75T3J.js";
10
+ } from "./chunk-RLAYINCA.js";
11
11
  import {
12
- createPushoverService
13
- } from "./chunk-7PVU2Z32.js";
12
+ cliNotifications,
13
+ runCli
14
+ } from "./chunk-4CXH2QIX.js";
14
15
  import "./chunk-JZOR5GA2.js";
15
16
 
16
17
  // src/fetch-books.ts
@@ -77,27 +78,15 @@ ${frontmatter}---
77
78
  async function main() {
78
79
  const env = {
79
80
  DATABASE_URL: process.env.DATABASE_URL,
80
- PUSHOVER_URL: process.env.PUSHOVER_URL,
81
- PUSHOVER_USER_KEY: process.env.PUSHOVER_USER_KEY,
82
- PUSHOVER_APP_TOKEN: process.env.PUSHOVER_APP_TOKEN,
83
81
  USERNAME_TO_EXPORT: process.env.USERNAME_TO_EXPORT,
84
- MINIO_BUCKET_NAME: process.env.MINIO_BUCKET_NAME
82
+ S3_BUCKET_NAME: process.env.S3_BUCKET_NAME
85
83
  };
86
84
  if (Object.values(env).some((v) => !v)) {
87
85
  throw new Error("Required environment variables are not set.");
88
86
  }
89
- if (process.env.MINIO_USE_SSL === "true" && (!process.env.CF_ACCESS_CLIENT_ID || !process.env.CF_ACCESS_CLIENT_SECRET)) {
90
- throw new Error(
91
- "CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when MINIO_USE_SSL is true."
92
- );
93
- }
94
87
  const prisma = createPrismaClient(env.DATABASE_URL ?? "");
95
- const notificationService = createPushoverService({
96
- url: env.PUSHOVER_URL ?? "",
97
- userKey: env.PUSHOVER_USER_KEY ?? "",
98
- appToken: env.PUSHOVER_APP_TOKEN ?? ""
99
- });
100
- const minioClient = createMinioClient();
88
+ const notificationService = cliNotifications;
89
+ const storageClient = createObjectStorageClient();
101
90
  const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
102
91
  const UNEXPORTED = makeUnexportedStatus();
103
92
  async function downloadBookImages(books) {
@@ -122,8 +111,8 @@ async function main() {
122
111
  } catch {
123
112
  }
124
113
  await withRetry(
125
- () => minioClient.fGetObject(
126
- env.MINIO_BUCKET_NAME ?? "",
114
+ () => storageClient.downloadObject(
115
+ env.S3_BUCKET_NAME ?? "",
127
116
  `books/original/${imagePath}`,
128
117
  filePath
129
118
  )
@@ -147,20 +136,8 @@ async function main() {
147
136
  await notificationService.notifyInfo("fetch-books completed", {
148
137
  caller: "fetch-books"
149
138
  });
150
- } catch (error) {
151
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
152
- await notificationService.notifyError(
153
- `fetch-books failed: ${String(error)}`,
154
- {
155
- caller: "fetch-books"
156
- }
157
- );
158
- process.exit(1);
159
139
  } finally {
160
140
  await prisma.$disconnect();
161
141
  }
162
142
  }
163
- main().catch((error) => {
164
- console.error(error);
165
- process.exit(1);
166
- });
143
+ await runCli("fetch-books", main);
@@ -1,16 +1,17 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
3
  import {
4
- createMinioClient
5
- } from "./chunk-F4J6JBR4.js";
4
+ createObjectStorageClient
5
+ } from "./chunk-MVYAZJB2.js";
6
6
  import {
7
7
  createPrismaClient,
8
8
  makeUnexportedStatus,
9
9
  makeUserId
10
- } from "./chunk-DIG75T3J.js";
10
+ } from "./chunk-RLAYINCA.js";
11
11
  import {
12
- createPushoverService
13
- } from "./chunk-7PVU2Z32.js";
12
+ cliNotifications,
13
+ runCli
14
+ } from "./chunk-4CXH2QIX.js";
14
15
  import "./chunk-JZOR5GA2.js";
15
16
 
16
17
  // src/fetch-images.ts
@@ -33,27 +34,15 @@ async function withRetry(fn, retries = 3) {
33
34
  async function main() {
34
35
  const env = {
35
36
  DATABASE_URL: process.env.DATABASE_URL,
36
- PUSHOVER_URL: process.env.PUSHOVER_URL,
37
- PUSHOVER_USER_KEY: process.env.PUSHOVER_USER_KEY,
38
- PUSHOVER_APP_TOKEN: process.env.PUSHOVER_APP_TOKEN,
39
37
  USERNAME_TO_EXPORT: process.env.USERNAME_TO_EXPORT,
40
- MINIO_BUCKET_NAME: process.env.MINIO_BUCKET_NAME
38
+ S3_BUCKET_NAME: process.env.S3_BUCKET_NAME
41
39
  };
42
40
  if (Object.values(env).some((v) => !v)) {
43
41
  throw new Error("Required environment variables are not set.");
44
42
  }
45
- if (process.env.MINIO_USE_SSL === "true" && (!process.env.CF_ACCESS_CLIENT_ID || !process.env.CF_ACCESS_CLIENT_SECRET)) {
46
- throw new Error(
47
- "CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when MINIO_USE_SSL is true."
48
- );
49
- }
50
43
  const prisma = createPrismaClient(env.DATABASE_URL ?? "");
51
- const notificationService = createPushoverService({
52
- url: env.PUSHOVER_URL ?? "",
53
- userKey: env.PUSHOVER_USER_KEY ?? "",
54
- appToken: env.PUSHOVER_APP_TOKEN ?? ""
55
- });
56
- const minioClient = createMinioClient();
44
+ const notificationService = cliNotifications;
45
+ const storageClient = createObjectStorageClient();
57
46
  const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
58
47
  const UNEXPORTED = makeUnexportedStatus();
59
48
  async function fetchImages() {
@@ -68,8 +57,8 @@ async function main() {
68
57
  const filePath = path.join(outputDir, imagePath);
69
58
  await mkdir(path.dirname(filePath), { recursive: true });
70
59
  await withRetry(
71
- () => minioClient.fGetObject(
72
- env.MINIO_BUCKET_NAME ?? "",
60
+ () => storageClient.downloadObject(
61
+ env.S3_BUCKET_NAME ?? "",
73
62
  `images/original/${imagePath}`,
74
63
  filePath
75
64
  )
@@ -82,20 +71,8 @@ async function main() {
82
71
  await notificationService.notifyInfo("fetch-images completed", {
83
72
  caller: "fetch-images"
84
73
  });
85
- } catch (error) {
86
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
87
- await notificationService.notifyError(
88
- `fetch-images failed: ${String(error)}`,
89
- {
90
- caller: "fetch-images"
91
- }
92
- );
93
- process.exit(1);
94
74
  } finally {
95
75
  await prisma.$disconnect();
96
76
  }
97
77
  }
98
- main().catch((error) => {
99
- console.error(error);
100
- process.exit(1);
101
- });
78
+ await runCli("fetch-images", main);
@@ -4,10 +4,11 @@ import {
4
4
  createPrismaClient,
5
5
  makeUnexportedStatus,
6
6
  makeUserId
7
- } from "./chunk-DIG75T3J.js";
7
+ } from "./chunk-RLAYINCA.js";
8
8
  import {
9
- createPushoverService
10
- } from "./chunk-7PVU2Z32.js";
9
+ cliNotifications,
10
+ runCli
11
+ } from "./chunk-4CXH2QIX.js";
11
12
  import "./chunk-JZOR5GA2.js";
12
13
 
13
14
  // src/fetch-notes.ts
@@ -27,20 +28,13 @@ ${item.markdown}
27
28
  async function main() {
28
29
  const env = {
29
30
  DATABASE_URL: process.env.DATABASE_URL,
30
- PUSHOVER_URL: process.env.PUSHOVER_URL,
31
- PUSHOVER_USER_KEY: process.env.PUSHOVER_USER_KEY,
32
- PUSHOVER_APP_TOKEN: process.env.PUSHOVER_APP_TOKEN,
33
31
  USERNAME_TO_EXPORT: process.env.USERNAME_TO_EXPORT
34
32
  };
35
33
  if (Object.values(env).some((v) => !v)) {
36
34
  throw new Error("Required environment variables are not set.");
37
35
  }
38
36
  const prisma = createPrismaClient(env.DATABASE_URL ?? "");
39
- const notificationService = createPushoverService({
40
- url: env.PUSHOVER_URL ?? "",
41
- userKey: env.PUSHOVER_USER_KEY ?? "",
42
- appToken: env.PUSHOVER_APP_TOKEN ?? ""
43
- });
37
+ const notificationService = cliNotifications;
44
38
  const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
45
39
  const UNEXPORTED = makeUnexportedStatus();
46
40
  async function fetchNotes() {
@@ -57,20 +51,8 @@ async function main() {
57
51
  await notificationService.notifyInfo("fetch-notes completed", {
58
52
  caller: "fetch-notes"
59
53
  });
60
- } catch (error) {
61
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
62
- await notificationService.notifyError(
63
- `fetch-notes failed: ${String(error)}`,
64
- {
65
- caller: "fetch-notes"
66
- }
67
- );
68
- process.exit(1);
69
54
  } finally {
70
55
  await prisma.$disconnect();
71
56
  }
72
57
  }
73
- main().catch((error) => {
74
- console.error(error);
75
- process.exit(1);
76
- });
58
+ await runCli("fetch-notes", main);
@@ -1,5 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
+ import {
4
+ reportCliError,
5
+ runCli
6
+ } from "./chunk-4CXH2QIX.js";
7
+ import "./chunk-JZOR5GA2.js";
3
8
 
4
9
  // src/find-duplicate-json-articles.ts
5
10
  import fs from "node:fs";
@@ -42,6 +47,7 @@ function findDuplicateUrls() {
42
47
  }
43
48
  }
44
49
  } catch (error) {
50
+ reportCliError(error, "find-duplicate-json-articles");
45
51
  console.error(`\u30A8\u30E9\u30FC: ${fileName} \u306E\u8AAD\u307F\u8FBC\u307F\u306B\u5931\u6557\u3057\u307E\u3057\u305F:`, error);
46
52
  }
47
53
  }
@@ -104,17 +110,9 @@ function displayResults(duplicates) {
104
110
  });
105
111
  }
106
112
  async function main() {
107
- try {
108
- console.log("json/article\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u5185\u306EURL\u91CD\u8907\u3092\u691C\u7D22\u4E2D...\n");
109
- const duplicates = findDuplicateUrls();
110
- displayResults(duplicates);
111
- console.log("\n\u691C\u7D22\u5B8C\u4E86");
112
- } catch (error) {
113
- console.error("\u274C \u30A8\u30E9\u30FC\u304C\u767A\u751F\u3057\u307E\u3057\u305F:", error);
114
- process.exit(1);
115
- }
113
+ console.log("json/article\u30C7\u30A3\u30EC\u30AF\u30C8\u30EA\u5185\u306EURL\u91CD\u8907\u3092\u691C\u7D22\u4E2D...\n");
114
+ const duplicates = findDuplicateUrls();
115
+ displayResults(duplicates);
116
+ console.log("\n\u691C\u7D22\u5B8C\u4E86");
116
117
  }
117
- main().catch((error) => {
118
- console.error(error);
119
- process.exit(1);
120
- });
118
+ await runCli("find-duplicate-json-articles", main);