@s-hirano-ist/s-scripts 1.23.4 → 1.24.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 (71) hide show
  1. package/dist/cleanup-minio-images.js +6 -8
  2. package/dist/cleanup-minio-images.js.map +1 -1
  3. package/dist/enrich-books.js +10 -8
  4. package/dist/enrich-books.js.map +1 -1
  5. package/dist/fetch-articles.js +9 -7
  6. package/dist/fetch-articles.js.map +1 -1
  7. package/dist/fetch-books.js +25 -25
  8. package/dist/fetch-books.js.map +1 -1
  9. package/dist/fetch-images.js +23 -23
  10. package/dist/fetch-images.js.map +1 -1
  11. package/dist/fetch-notes.js +3 -3
  12. package/dist/fetch-notes.js.map +1 -1
  13. package/dist/find-duplicate-json-articles.js +1 -1
  14. package/dist/find-duplicate-json-articles.js.map +1 -1
  15. package/dist/fix-book-frontmatter.js +73 -53
  16. package/dist/fix-book-frontmatter.js.map +1 -1
  17. package/dist/fix-image-formats.js +3 -3
  18. package/dist/fix-image-formats.js.map +1 -1
  19. package/dist/infrastructures/articles-command-repository.d.ts +1 -1
  20. package/dist/infrastructures/articles-command-repository.d.ts.map +1 -1
  21. package/dist/infrastructures/articles-command-repository.js +3 -2
  22. package/dist/infrastructures/articles-command-repository.js.map +1 -1
  23. package/dist/infrastructures/books-command-repository.d.ts +1 -1
  24. package/dist/infrastructures/books-command-repository.d.ts.map +1 -1
  25. package/dist/infrastructures/books-command-repository.js +3 -2
  26. package/dist/infrastructures/books-command-repository.js.map +1 -1
  27. package/dist/infrastructures/images-command-repository.d.ts +1 -1
  28. package/dist/infrastructures/images-command-repository.d.ts.map +1 -1
  29. package/dist/infrastructures/images-command-repository.js +3 -2
  30. package/dist/infrastructures/images-command-repository.js.map +1 -1
  31. package/dist/infrastructures/notes-command-repository.d.ts +1 -1
  32. package/dist/infrastructures/notes-command-repository.d.ts.map +1 -1
  33. package/dist/infrastructures/notes-command-repository.js +3 -2
  34. package/dist/infrastructures/notes-command-repository.js.map +1 -1
  35. package/dist/ingest-articles.js +129 -106
  36. package/dist/ingest-articles.js.map +1 -1
  37. package/dist/ingest-books.js +113 -102
  38. package/dist/ingest-books.js.map +1 -1
  39. package/dist/ingest-images.js +8 -8
  40. package/dist/ingest-images.js.map +1 -1
  41. package/dist/ingest-notes.js +50 -44
  42. package/dist/ingest-notes.js.map +1 -1
  43. package/dist/rag/delete-collection.js.map +1 -1
  44. package/dist/rag/ingest.js +5 -5
  45. package/dist/rag/ingest.js.map +1 -1
  46. package/dist/rag/search.js.map +1 -1
  47. package/dist/reset-articles.js +1 -1
  48. package/dist/reset-articles.js.map +1 -1
  49. package/dist/reset-books.js +1 -1
  50. package/dist/reset-books.js.map +1 -1
  51. package/dist/reset-images.js +1 -1
  52. package/dist/reset-images.js.map +1 -1
  53. package/dist/reset-notes.js +1 -1
  54. package/dist/reset-notes.js.map +1 -1
  55. package/dist/revert-articles.js +1 -1
  56. package/dist/revert-articles.js.map +1 -1
  57. package/dist/revert-books.js +1 -1
  58. package/dist/revert-books.js.map +1 -1
  59. package/dist/revert-images.js +1 -1
  60. package/dist/revert-images.js.map +1 -1
  61. package/dist/revert-notes.js +1 -1
  62. package/dist/revert-notes.js.map +1 -1
  63. package/dist/s-content-format.js +1 -1
  64. package/dist/s-content-format.js.map +1 -1
  65. package/dist/update-json-articles.js +13 -12
  66. package/dist/update-json-articles.js.map +1 -1
  67. package/dist/update-raw-articles.js +10 -9
  68. package/dist/update-raw-articles.js.map +1 -1
  69. package/dist/validate-json-articles.js +1 -1
  70. package/dist/validate-json-articles.js.map +1 -1
  71. package/package.json +9 -9
@@ -1,10 +1,24 @@
1
1
  #!/usr/bin/env node
2
- import { readFile } from "node:fs/promises";
3
- import { basename } from "node:path";
4
2
  import { makeExportedStatus, makeId, makeUserId, } from "@s-hirano-ist/s-core/shared-kernel/entities/common-entity";
5
3
  import { createPushoverService } from "@s-hirano-ist/s-notification";
6
4
  import { glob } from "glob";
5
+ import { readFile } from "node:fs/promises";
6
+ import { basename } from "node:path";
7
7
  const SCRIPT_NAME = "ingest-articles";
8
+ function isUnchanged(existing, item, fileQuote, fileOgImageUrl, fileOgTitle, fileOgDescription) {
9
+ return (existing.title === item.title &&
10
+ existing.quote === fileQuote &&
11
+ existing.ogImageUrl === fileOgImageUrl &&
12
+ existing.ogTitle === fileOgTitle &&
13
+ existing.ogDescription === fileOgDescription);
14
+ }
15
+ function outcomeKey(outcome) {
16
+ if (outcome === "inserted")
17
+ return "insertedCount";
18
+ if (outcome === "updated")
19
+ return "updatedCount";
20
+ return "skippedCount";
21
+ }
8
22
  async function main() {
9
23
  const dryRun = process.argv.includes("--dry-run");
10
24
  const env = {
@@ -29,6 +43,110 @@ async function main() {
29
43
  const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
30
44
  const exported = makeExportedStatus();
31
45
  const fileUrls = new Set();
46
+ async function processExisting(existing, item) {
47
+ const fileQuote = item.quote ?? null;
48
+ const fileOgImageUrl = item.ogImageUrl ?? null;
49
+ const fileOgTitle = item.ogTitle ?? null;
50
+ const fileOgDescription = item.ogDescription ?? null;
51
+ if (isUnchanged(existing, item, fileQuote, fileOgImageUrl, fileOgTitle, fileOgDescription)) {
52
+ // console.log(
53
+ // `⏭️ スキップ(変更なし): ${item.title} (${item.url})`,
54
+ // );
55
+ return "skipped";
56
+ }
57
+ if (dryRun) {
58
+ console.log(`🔄 [dry-run] 更新予定: ${item.title} (${item.url})`);
59
+ }
60
+ else {
61
+ await prisma.article.update({
62
+ where: { id: existing.id },
63
+ data: {
64
+ title: item.title,
65
+ quote: fileQuote,
66
+ ogImageUrl: fileOgImageUrl,
67
+ ogTitle: fileOgTitle,
68
+ ogDescription: fileOgDescription,
69
+ },
70
+ });
71
+ console.log(`🔄 更新: ${item.title}`);
72
+ }
73
+ return "updated";
74
+ }
75
+ async function processNew(item, categoryId, existingArticlesMap) {
76
+ if (dryRun) {
77
+ console.log(`🔍 [dry-run] 挿入予定: ${item.title} (${item.url})`);
78
+ existingArticlesMap.set(item.url, {
79
+ id: "",
80
+ url: item.url,
81
+ title: item.title,
82
+ quote: item.quote ?? null,
83
+ ogImageUrl: item.ogImageUrl ?? null,
84
+ ogTitle: item.ogTitle ?? null,
85
+ ogDescription: item.ogDescription ?? null,
86
+ });
87
+ return "inserted";
88
+ }
89
+ await prisma.article.create({
90
+ data: {
91
+ id: String(makeId()),
92
+ title: item.title,
93
+ url: item.url,
94
+ quote: item.quote ?? null,
95
+ ogImageUrl: item.ogImageUrl ?? null,
96
+ ogTitle: item.ogTitle ?? null,
97
+ ogDescription: item.ogDescription ?? null,
98
+ categoryId,
99
+ status: exported.status,
100
+ exportedAt: exported.exportedAt,
101
+ userId,
102
+ createdAt: new Date(),
103
+ },
104
+ });
105
+ existingArticlesMap.set(item.url, {
106
+ id: "",
107
+ url: item.url,
108
+ title: item.title,
109
+ quote: item.quote ?? null,
110
+ ogImageUrl: item.ogImageUrl ?? null,
111
+ ogTitle: item.ogTitle ?? null,
112
+ ogDescription: item.ogDescription ?? null,
113
+ });
114
+ console.log(`✅ 挿入: ${item.title}`);
115
+ return "inserted";
116
+ }
117
+ async function processItem(item, categoryId, existingArticlesMap) {
118
+ fileUrls.add(item.url);
119
+ const existing = existingArticlesMap.get(item.url);
120
+ if (existing) {
121
+ return processExisting(existing, item);
122
+ }
123
+ return processNew(item, categoryId, existingArticlesMap);
124
+ }
125
+ async function resolveCategoryId(categoryName, categoryMap) {
126
+ const existingId = categoryMap.get(categoryName);
127
+ if (existingId) {
128
+ return { categoryId: existingId, created: false };
129
+ }
130
+ let categoryId;
131
+ if (dryRun) {
132
+ console.log(`🔍 [dry-run] カテゴリ作成予定: ${categoryName}`);
133
+ categoryId = `dry-run-${categoryName}`;
134
+ }
135
+ else {
136
+ const category = await prisma.category.create({
137
+ data: {
138
+ id: String(makeId()),
139
+ name: categoryName,
140
+ userId,
141
+ createdAt: new Date(),
142
+ },
143
+ });
144
+ categoryId = category.id;
145
+ console.log(`📂 カテゴリ作成: ${categoryName}`);
146
+ }
147
+ categoryMap.set(categoryName, categoryId);
148
+ return { categoryId, created: true };
149
+ }
32
150
  async function ingestArticles() {
33
151
  const files = await glob(`${contentsPath}/json/article/*.json`);
34
152
  console.log(`📁 ${files.length} 件のJSONファイルを検出しました。`);
@@ -50,9 +168,7 @@ async function main() {
50
168
  where: { userId },
51
169
  });
52
170
  const categoryMap = new Map(existingCategories.map((c) => [c.name, c.id]));
53
- let insertedCount = 0;
54
- let updatedCount = 0;
55
- let skippedCount = 0;
171
+ const counts = { insertedCount: 0, updatedCount: 0, skippedCount: 0 };
56
172
  let errorCount = 0;
57
173
  let categoryCreatedCount = 0;
58
174
  for (const filePath of files) {
@@ -60,107 +176,14 @@ async function main() {
60
176
  const content = await readFile(filePath, "utf-8");
61
177
  const json = JSON.parse(content);
62
178
  const categoryName = json.heading;
63
- let categoryId = categoryMap.get(categoryName);
64
- if (!categoryId) {
65
- if (dryRun) {
66
- console.log(`🔍 [dry-run] カテゴリ作成予定: ${categoryName}`);
67
- categoryId = `dry-run-${categoryName}`;
68
- }
69
- else {
70
- const category = await prisma.category.create({
71
- data: {
72
- id: String(makeId()),
73
- name: categoryName,
74
- userId,
75
- createdAt: new Date(),
76
- },
77
- });
78
- categoryId = category.id;
79
- console.log(`📂 カテゴリ作成: ${categoryName}`);
80
- }
81
- categoryMap.set(categoryName, categoryId);
179
+ const { categoryId, created } = await resolveCategoryId(categoryName, categoryMap);
180
+ if (created) {
82
181
  categoryCreatedCount++;
83
182
  }
84
183
  for (const item of json.body) {
85
184
  try {
86
- fileUrls.add(item.url);
87
- const existing = existingArticlesMap.get(item.url);
88
- if (existing) {
89
- const fileQuote = item.quote ?? null;
90
- const fileOgImageUrl = item.ogImageUrl ?? null;
91
- const fileOgTitle = item.ogTitle ?? null;
92
- const fileOgDescription = item.ogDescription ?? null;
93
- if (existing.title === item.title &&
94
- existing.quote === fileQuote &&
95
- existing.ogImageUrl === fileOgImageUrl &&
96
- existing.ogTitle === fileOgTitle &&
97
- existing.ogDescription === fileOgDescription) {
98
- // console.log(
99
- // `⏭️ スキップ(変更なし): ${item.title} (${item.url})`,
100
- // );
101
- skippedCount++;
102
- continue;
103
- }
104
- if (dryRun) {
105
- console.log(`🔄 [dry-run] 更新予定: ${item.title} (${item.url})`);
106
- }
107
- else {
108
- await prisma.article.update({
109
- where: { id: existing.id },
110
- data: {
111
- title: item.title,
112
- quote: fileQuote,
113
- ogImageUrl: fileOgImageUrl,
114
- ogTitle: fileOgTitle,
115
- ogDescription: fileOgDescription,
116
- },
117
- });
118
- console.log(`🔄 更新: ${item.title}`);
119
- }
120
- updatedCount++;
121
- continue;
122
- }
123
- if (dryRun) {
124
- console.log(`🔍 [dry-run] 挿入予定: ${item.title} (${item.url})`);
125
- insertedCount++;
126
- existingArticlesMap.set(item.url, {
127
- id: "",
128
- url: item.url,
129
- title: item.title,
130
- quote: item.quote ?? null,
131
- ogImageUrl: item.ogImageUrl ?? null,
132
- ogTitle: item.ogTitle ?? null,
133
- ogDescription: item.ogDescription ?? null,
134
- });
135
- continue;
136
- }
137
- await prisma.article.create({
138
- data: {
139
- id: String(makeId()),
140
- title: item.title,
141
- url: item.url,
142
- quote: item.quote ?? null,
143
- ogImageUrl: item.ogImageUrl ?? null,
144
- ogTitle: item.ogTitle ?? null,
145
- ogDescription: item.ogDescription ?? null,
146
- categoryId,
147
- status: exported.status,
148
- exportedAt: exported.exportedAt,
149
- userId,
150
- createdAt: new Date(),
151
- },
152
- });
153
- insertedCount++;
154
- existingArticlesMap.set(item.url, {
155
- id: "",
156
- url: item.url,
157
- title: item.title,
158
- quote: item.quote ?? null,
159
- ogImageUrl: item.ogImageUrl ?? null,
160
- ogTitle: item.ogTitle ?? null,
161
- ogDescription: item.ogDescription ?? null,
162
- });
163
- console.log(`✅ 挿入: ${item.title}`);
185
+ const outcome = await processItem(item, categoryId, existingArticlesMap);
186
+ counts[outcomeKey(outcome)]++;
164
187
  }
165
188
  catch (itemError) {
166
189
  console.error(`❌ エラー(${basename(filePath)} > ${item.title}):`, `url(${item.url.length}文字)=${item.url}`, `title(${item.title.length}文字)`, `quote(${(item.quote ?? "").length}文字)`, `ogImageUrl(${(item.ogImageUrl ?? "").length}文字)`, `ogTitle(${(item.ogTitle ?? "").length}文字)`, `ogDescription(${(item.ogDescription ?? "").length}文字)`, itemError);
@@ -174,9 +197,9 @@ async function main() {
174
197
  }
175
198
  }
176
199
  return {
177
- insertedCount,
178
- updatedCount,
179
- skippedCount,
200
+ insertedCount: counts.insertedCount,
201
+ updatedCount: counts.updatedCount,
202
+ skippedCount: counts.skippedCount,
180
203
  errorCount,
181
204
  categoryCreatedCount,
182
205
  };
@@ -214,7 +237,7 @@ async function main() {
214
237
  }
215
238
  catch (error) {
216
239
  console.error("❌ エラーが発生しました:", error);
217
- await notificationService.notifyError(`${SCRIPT_NAME} failed: ${error}`, {
240
+ await notificationService.notifyError(`${SCRIPT_NAME} failed: ${String(error)}`, {
218
241
  caller: SCRIPT_NAME,
219
242
  });
220
243
  process.exit(1);
@@ -1 +1 @@
1
- {"version":3,"file":"ingest-articles.js","sourceRoot":"","sources":["../src/ingest-articles.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ingest-articles.js","sourceRoot":"","sources":["../src/ingest-articles.ts"],"names":[],"mappings":"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"}
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
- import { readFile } from "node:fs/promises";
3
- import { basename, extname } from "node:path";
4
2
  import { makeISBN } from "@s-hirano-ist/s-core/books/entities/book-entity";
5
3
  import { makeExportedStatus, makeId, makeUserId, } from "@s-hirano-ist/s-core/shared-kernel/entities/common-entity";
6
4
  import { createPushoverService } from "@s-hirano-ist/s-notification";
7
5
  import { createMinioClient } from "@s-hirano-ist/s-storage";
8
6
  import { glob } from "glob";
9
7
  import matter from "gray-matter";
8
+ import { readFile } from "node:fs/promises";
9
+ import { basename, extname } from "node:path";
10
10
  import sharp from "sharp";
11
11
  const SCRIPT_NAME = "ingest-books";
12
12
  const ORIGINAL_BOOK_IMAGE_PATH = "books/original";
@@ -28,16 +28,26 @@ function getContentType(filePath) {
28
28
  return null;
29
29
  }
30
30
  }
31
+ function arrayEquals(a, b) {
32
+ if (a.length !== b.length)
33
+ return false;
34
+ for (const [i, element] of a.entries()) {
35
+ if (element !== b[i])
36
+ return false;
37
+ }
38
+ return true;
39
+ }
31
40
  function parseBookFile(content) {
32
41
  const parsed = matter(content);
33
42
  const data = parsed.data;
34
43
  // title: frontmatter.title を優先、無ければ本文の H1 からフォールバック
35
44
  let title = data.title?.trim() ?? "";
36
45
  if (!title) {
37
- const h1Match = parsed.content.match(/^# (.+)$/m);
46
+ const h1Match = /^# (.+)$/mu.exec(parsed.content);
38
47
  title = h1Match ? h1Match[1].trim() : "";
39
48
  }
40
49
  const body = parsed.content.trim();
50
+ // oxlint-disable-next-line typescript/no-unnecessary-condition -- gray-matter parses arbitrary YAML; rating can be null at runtime despite the declared type
41
51
  if (data.rating === undefined || data.rating === null) {
42
52
  throw new Error("rating は必須です (frontmatter に rating フィールドがありません)");
43
53
  }
@@ -53,6 +63,18 @@ function parseBookFile(content) {
53
63
  googleHref: data.googleHref ?? null,
54
64
  };
55
65
  }
66
+ function bookMatchesExisting(existing, parsed, expectedImagePath) {
67
+ return (existing.title === parsed.title &&
68
+ existing.markdown === parsed.markdown &&
69
+ existing.imagePath === expectedImagePath &&
70
+ existing.rating === parsed.rating &&
71
+ arrayEquals(existing.tags, parsed.tags) &&
72
+ existing.googleSubTitle === parsed.googleSubTitle &&
73
+ arrayEquals(existing.googleAuthors, parsed.googleAuthors) &&
74
+ existing.googleDescription === parsed.googleDescription &&
75
+ existing.googleImgSrc === parsed.googleImgSrc &&
76
+ existing.googleHref === parsed.googleHref);
77
+ }
56
78
  async function main() {
57
79
  const dryRun = process.argv.includes("--dry-run");
58
80
  const env = {
@@ -66,11 +88,9 @@ async function main() {
66
88
  if (Object.values(env).some((v) => !v)) {
67
89
  throw new Error("Required environment variables are not set.");
68
90
  }
69
- if (process.env.MINIO_USE_SSL === "true") {
70
- if (!process.env.CF_ACCESS_CLIENT_ID ||
71
- !process.env.CF_ACCESS_CLIENT_SECRET) {
72
- throw new Error("CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when MINIO_USE_SSL is true.");
73
- }
91
+ if (process.env.MINIO_USE_SSL === "true" &&
92
+ (!process.env.CF_ACCESS_CLIENT_ID || !process.env.CF_ACCESS_CLIENT_SECRET)) {
93
+ throw new Error("CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when MINIO_USE_SSL is true.");
74
94
  }
75
95
  const contentsPath = process.env.S_CONTENTS_PATH ?? process.cwd();
76
96
  // Dynamic import for Prisma ESM compatibility
@@ -140,21 +160,70 @@ async function main() {
140
160
  },
141
161
  });
142
162
  const existingBooksMap = new Map(existingBooks.map((b) => [b.isbn, b]));
143
- function arrayEquals(a, b) {
144
- if (a.length !== b.length)
145
- return false;
146
- for (let i = 0; i < a.length; i++) {
147
- if (a[i] !== b[i])
148
- return false;
149
- }
150
- return true;
151
- }
152
163
  console.log(`📊 DB に ${existingBooksMap.size} 件の既存書籍があります。`);
153
164
  let insertedCount = 0;
154
165
  let updatedCount = 0;
155
166
  let skippedCount = 0;
156
167
  let errorCount = 0;
157
- for (const filePath of files) {
168
+ async function resolveNewImagePath(localImagePath, fallback) {
169
+ if (!localImagePath)
170
+ return fallback;
171
+ if (dryRun)
172
+ return basename(localImagePath);
173
+ return uploadBookImage(localImagePath);
174
+ }
175
+ async function updateExistingBook(existing, parsed, localImagePath, isbn, title, markdown) {
176
+ const newImagePath = await resolveNewImagePath(localImagePath, existing.imagePath);
177
+ if (dryRun) {
178
+ console.log(`🔄 [dry-run] 更新予定: ${isbn} (${title})`);
179
+ return;
180
+ }
181
+ await prisma.book.update({
182
+ where: { id: existing.id },
183
+ data: {
184
+ title,
185
+ markdown,
186
+ imagePath: newImagePath,
187
+ rating: parsed.rating,
188
+ tags: parsed.tags,
189
+ googleSubTitle: parsed.googleSubTitle,
190
+ googleAuthors: parsed.googleAuthors,
191
+ googleDescription: parsed.googleDescription,
192
+ googleImgSrc: parsed.googleImgSrc,
193
+ googleHref: parsed.googleHref,
194
+ },
195
+ });
196
+ console.log(`🔄 更新: ${isbn} (${title})`);
197
+ }
198
+ async function createNewBook(parsed, localImagePath, isbn, title, markdown) {
199
+ const newImagePath = await resolveNewImagePath(localImagePath, null);
200
+ if (dryRun) {
201
+ console.log(`🔍 [dry-run] 挿入予定: ${isbn} (${title})`);
202
+ return;
203
+ }
204
+ await prisma.book.create({
205
+ data: {
206
+ id: String(makeId()),
207
+ isbn,
208
+ title,
209
+ markdown,
210
+ imagePath: newImagePath,
211
+ status: exported.status,
212
+ exportedAt: exported.exportedAt,
213
+ userId,
214
+ createdAt: new Date(),
215
+ rating: parsed.rating,
216
+ tags: parsed.tags,
217
+ googleSubTitle: parsed.googleSubTitle,
218
+ googleAuthors: parsed.googleAuthors,
219
+ googleDescription: parsed.googleDescription,
220
+ googleImgSrc: parsed.googleImgSrc,
221
+ googleHref: parsed.googleHref,
222
+ },
223
+ });
224
+ console.log(`✅ 挿入: ${isbn} (${title})`);
225
+ }
226
+ async function processBookFile(filePath) {
158
227
  const rawIsbn = basename(filePath, ".md");
159
228
  let isbn = rawIsbn;
160
229
  let title = "";
@@ -168,8 +237,7 @@ async function main() {
168
237
  markdown = parsed.markdown;
169
238
  if (!title) {
170
239
  console.error(`⚠️ タイトルなし: ${basename(filePath)}`);
171
- errorCount++;
172
- continue;
240
+ return "error";
173
241
  }
174
242
  const localImagePath = bookImageMap.get(isbn);
175
243
  const existing = existingBooksMap.get(isbn);
@@ -177,92 +245,35 @@ async function main() {
177
245
  const expectedImagePath = localImagePath
178
246
  ? basename(localImagePath)
179
247
  : existing.imagePath;
180
- if (existing.title === title &&
181
- existing.markdown === markdown &&
182
- existing.imagePath === expectedImagePath &&
183
- existing.rating === parsed.rating &&
184
- arrayEquals(existing.tags, parsed.tags) &&
185
- existing.googleSubTitle === parsed.googleSubTitle &&
186
- arrayEquals(existing.googleAuthors, parsed.googleAuthors) &&
187
- existing.googleDescription === parsed.googleDescription &&
188
- existing.googleImgSrc === parsed.googleImgSrc &&
189
- existing.googleHref === parsed.googleHref) {
190
- skippedCount++;
191
- continue;
192
- }
193
- let newImagePath = existing.imagePath;
194
- if (localImagePath) {
195
- if (dryRun) {
196
- newImagePath = basename(localImagePath);
197
- }
198
- else {
199
- newImagePath = await uploadBookImage(localImagePath);
200
- }
201
- }
202
- if (dryRun) {
203
- console.log(`🔄 [dry-run] 更新予定: ${isbn} (${title})`);
204
- }
205
- else {
206
- await prisma.book.update({
207
- where: { id: existing.id },
208
- data: {
209
- title,
210
- markdown,
211
- imagePath: newImagePath,
212
- rating: parsed.rating,
213
- tags: parsed.tags,
214
- googleSubTitle: parsed.googleSubTitle,
215
- googleAuthors: parsed.googleAuthors,
216
- googleDescription: parsed.googleDescription,
217
- googleImgSrc: parsed.googleImgSrc,
218
- googleHref: parsed.googleHref,
219
- },
220
- });
221
- console.log(`🔄 更新: ${isbn} (${title})`);
222
- }
223
- updatedCount++;
224
- continue;
225
- }
226
- let newImagePath = null;
227
- if (localImagePath) {
228
- if (dryRun) {
229
- newImagePath = basename(localImagePath);
230
- }
231
- else {
232
- newImagePath = await uploadBookImage(localImagePath);
248
+ if (bookMatchesExisting(existing, parsed, expectedImagePath)) {
249
+ return "skipped";
233
250
  }
251
+ await updateExistingBook(existing, parsed, localImagePath, isbn, title, markdown);
252
+ return "updated";
234
253
  }
235
- if (dryRun) {
236
- console.log(`🔍 [dry-run] 挿入予定: ${isbn} (${title})`);
237
- insertedCount++;
238
- continue;
239
- }
240
- await prisma.book.create({
241
- data: {
242
- id: String(makeId()),
243
- isbn,
244
- title,
245
- markdown,
246
- imagePath: newImagePath,
247
- status: exported.status,
248
- exportedAt: exported.exportedAt,
249
- userId,
250
- createdAt: new Date(),
251
- rating: parsed.rating,
252
- tags: parsed.tags,
253
- googleSubTitle: parsed.googleSubTitle,
254
- googleAuthors: parsed.googleAuthors,
255
- googleDescription: parsed.googleDescription,
256
- googleImgSrc: parsed.googleImgSrc,
257
- googleHref: parsed.googleHref,
258
- },
259
- });
260
- insertedCount++;
261
- console.log(`✅ 挿入: ${isbn} (${title})`);
254
+ await createNewBook(parsed, localImagePath, isbn, title, markdown);
255
+ return "inserted";
262
256
  }
263
257
  catch (error) {
264
258
  console.error(`❌ エラー(${basename(filePath)}):`, `isbn=${isbn}`, `title(${title.length}文字)`, `markdown(${(markdown ?? "").length}文字)`, error);
265
- errorCount++;
259
+ return "error";
260
+ }
261
+ }
262
+ for (const filePath of files) {
263
+ const result = await processBookFile(filePath);
264
+ switch (result) {
265
+ case "inserted":
266
+ insertedCount++;
267
+ break;
268
+ case "updated":
269
+ updatedCount++;
270
+ break;
271
+ case "skipped":
272
+ skippedCount++;
273
+ break;
274
+ case "error":
275
+ errorCount++;
276
+ break;
266
277
  }
267
278
  }
268
279
  return { insertedCount, updatedCount, skippedCount, errorCount };
@@ -300,7 +311,7 @@ async function main() {
300
311
  }
301
312
  catch (error) {
302
313
  console.error("❌ エラーが発生しました:", error);
303
- await notificationService.notifyError(`${SCRIPT_NAME} failed: ${error}`, {
314
+ await notificationService.notifyError(`${SCRIPT_NAME} failed: ${String(error)}`, {
304
315
  caller: SCRIPT_NAME,
305
316
  });
306
317
  process.exit(1);