@s-hirano-ist/s-scripts 1.26.7 → 4.0.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 (180) hide show
  1. package/README.md +2 -0
  2. package/dist/chunk-5OXUZW2Q.js +590 -0
  3. package/dist/chunk-7PVU2Z32.js +71 -0
  4. package/dist/chunk-AJMTRCPJ.js +15 -0
  5. package/dist/chunk-AZF2R2BF.js +85 -0
  6. package/dist/chunk-F4J6JBR4.js +115 -0
  7. package/dist/chunk-HDYQV2Y2.js +58 -0
  8. package/dist/chunk-HIK7SX34.js +85 -0
  9. package/dist/chunk-IWNZQXDG.js +7660 -0
  10. package/dist/chunk-J4VLH4VA.js +267 -0
  11. package/dist/chunk-JZOR5GA2.js +42 -0
  12. package/dist/chunk-KKZP7ZF3.js +77 -0
  13. package/dist/chunk-N6TZF755.js +102 -0
  14. package/dist/chunk-S5WJ5VXW.js +85 -0
  15. package/dist/chunk-UXGLXHQ6.js +40 -0
  16. package/dist/cleanup-minio-images.js +115 -92
  17. package/dist/enrich-books.js +87 -78
  18. package/dist/fetch-articles.js +101 -90
  19. package/dist/fetch-books.js +147 -128
  20. package/dist/fetch-images.js +88 -72
  21. package/dist/fetch-notes.js +66 -54
  22. package/dist/find-duplicate-json-articles.js +100 -97
  23. package/dist/fix-book-frontmatter.js +111 -99
  24. package/dist/fix-image-formats.js +81 -65
  25. package/dist/ingest-articles.js +30 -249
  26. package/dist/ingest-books.js +61 -318
  27. package/dist/ingest-images.js +33 -184
  28. package/dist/ingest-notes.js +41 -171
  29. package/dist/rag/delete-collection.js +32 -22
  30. package/dist/rag/ingest.js +371 -92
  31. package/dist/rag/search.js +80 -76
  32. package/dist/reset-articles.js +57 -60
  33. package/dist/reset-books.js +57 -59
  34. package/dist/reset-images.js +57 -59
  35. package/dist/reset-notes.js +57 -59
  36. package/dist/revert-articles.js +53 -55
  37. package/dist/revert-books.js +53 -53
  38. package/dist/revert-images.js +53 -53
  39. package/dist/revert-notes.js +53 -53
  40. package/dist/s-content-format.js +103 -13
  41. package/dist/update-json-articles.js +101 -97
  42. package/dist/update-raw-articles.js +130 -130
  43. package/dist/validate-json-articles.js +129 -130
  44. package/package.json +14 -51
  45. package/dist/cleanup-minio-images.d.ts +0 -3
  46. package/dist/cleanup-minio-images.d.ts.map +0 -1
  47. package/dist/cleanup-minio-images.js.map +0 -1
  48. package/dist/enrich-books.d.ts +0 -3
  49. package/dist/enrich-books.d.ts.map +0 -1
  50. package/dist/enrich-books.js.map +0 -1
  51. package/dist/fetch-articles.d.ts +0 -3
  52. package/dist/fetch-articles.d.ts.map +0 -1
  53. package/dist/fetch-articles.js.map +0 -1
  54. package/dist/fetch-books.d.ts +0 -3
  55. package/dist/fetch-books.d.ts.map +0 -1
  56. package/dist/fetch-books.js.map +0 -1
  57. package/dist/fetch-images.d.ts +0 -3
  58. package/dist/fetch-images.d.ts.map +0 -1
  59. package/dist/fetch-images.js.map +0 -1
  60. package/dist/fetch-notes.d.ts +0 -3
  61. package/dist/fetch-notes.d.ts.map +0 -1
  62. package/dist/fetch-notes.js.map +0 -1
  63. package/dist/find-duplicate-json-articles.d.ts +0 -3
  64. package/dist/find-duplicate-json-articles.d.ts.map +0 -1
  65. package/dist/find-duplicate-json-articles.js.map +0 -1
  66. package/dist/fix-book-frontmatter.d.ts +0 -3
  67. package/dist/fix-book-frontmatter.d.ts.map +0 -1
  68. package/dist/fix-book-frontmatter.js.map +0 -1
  69. package/dist/fix-image-formats.d.ts +0 -3
  70. package/dist/fix-image-formats.d.ts.map +0 -1
  71. package/dist/fix-image-formats.js.map +0 -1
  72. package/dist/infrastructures/articles-command-repository.d.ts +0 -57
  73. package/dist/infrastructures/articles-command-repository.d.ts.map +0 -1
  74. package/dist/infrastructures/articles-command-repository.js +0 -68
  75. package/dist/infrastructures/articles-command-repository.js.map +0 -1
  76. package/dist/infrastructures/books-command-repository.d.ts +0 -34
  77. package/dist/infrastructures/books-command-repository.d.ts.map +0 -1
  78. package/dist/infrastructures/books-command-repository.js +0 -53
  79. package/dist/infrastructures/books-command-repository.js.map +0 -1
  80. package/dist/infrastructures/cache-invalidation-client.d.ts +0 -9
  81. package/dist/infrastructures/cache-invalidation-client.d.ts.map +0 -1
  82. package/dist/infrastructures/cache-invalidation-client.js +0 -21
  83. package/dist/infrastructures/cache-invalidation-client.js.map +0 -1
  84. package/dist/infrastructures/cache-invalidation-client.test.d.ts +0 -2
  85. package/dist/infrastructures/cache-invalidation-client.test.d.ts.map +0 -1
  86. package/dist/infrastructures/cache-invalidation-client.test.js +0 -25
  87. package/dist/infrastructures/cache-invalidation-client.test.js.map +0 -1
  88. package/dist/infrastructures/images-command-repository.d.ts +0 -34
  89. package/dist/infrastructures/images-command-repository.d.ts.map +0 -1
  90. package/dist/infrastructures/images-command-repository.js +0 -53
  91. package/dist/infrastructures/images-command-repository.js.map +0 -1
  92. package/dist/infrastructures/notes-command-repository.d.ts +0 -34
  93. package/dist/infrastructures/notes-command-repository.d.ts.map +0 -1
  94. package/dist/infrastructures/notes-command-repository.js +0 -53
  95. package/dist/infrastructures/notes-command-repository.js.map +0 -1
  96. package/dist/ingest-articles.d.ts +0 -3
  97. package/dist/ingest-articles.d.ts.map +0 -1
  98. package/dist/ingest-articles.js.map +0 -1
  99. package/dist/ingest-books.d.ts +0 -3
  100. package/dist/ingest-books.d.ts.map +0 -1
  101. package/dist/ingest-books.js.map +0 -1
  102. package/dist/ingest-images.d.ts +0 -3
  103. package/dist/ingest-images.d.ts.map +0 -1
  104. package/dist/ingest-images.js.map +0 -1
  105. package/dist/ingest-notes.d.ts +0 -3
  106. package/dist/ingest-notes.d.ts.map +0 -1
  107. package/dist/ingest-notes.js.map +0 -1
  108. package/dist/lib/glob-paths.d.ts +0 -6
  109. package/dist/lib/glob-paths.d.ts.map +0 -1
  110. package/dist/lib/glob-paths.js +0 -9
  111. package/dist/lib/glob-paths.js.map +0 -1
  112. package/dist/lib/glob-paths.test.d.ts +0 -2
  113. package/dist/lib/glob-paths.test.d.ts.map +0 -1
  114. package/dist/lib/glob-paths.test.js +0 -30
  115. package/dist/lib/glob-paths.test.js.map +0 -1
  116. package/dist/lib/html-charset.d.ts +0 -4
  117. package/dist/lib/html-charset.d.ts.map +0 -1
  118. package/dist/lib/html-charset.js +0 -33
  119. package/dist/lib/html-charset.js.map +0 -1
  120. package/dist/lib/html-charset.test.d.ts +0 -2
  121. package/dist/lib/html-charset.test.d.ts.map +0 -1
  122. package/dist/lib/html-charset.test.js +0 -27
  123. package/dist/lib/html-charset.test.js.map +0 -1
  124. package/dist/rag/delete-collection.d.ts +0 -3
  125. package/dist/rag/delete-collection.d.ts.map +0 -1
  126. package/dist/rag/delete-collection.js.map +0 -1
  127. package/dist/rag/ingest-config.d.ts +0 -8
  128. package/dist/rag/ingest-config.d.ts.map +0 -1
  129. package/dist/rag/ingest-config.js +0 -8
  130. package/dist/rag/ingest-config.js.map +0 -1
  131. package/dist/rag/ingest.d.ts +0 -3
  132. package/dist/rag/ingest.d.ts.map +0 -1
  133. package/dist/rag/ingest.js.map +0 -1
  134. package/dist/rag/search.d.ts +0 -3
  135. package/dist/rag/search.d.ts.map +0 -1
  136. package/dist/rag/search.js.map +0 -1
  137. package/dist/reset-articles.d.ts +0 -3
  138. package/dist/reset-articles.d.ts.map +0 -1
  139. package/dist/reset-articles.js.map +0 -1
  140. package/dist/reset-books.d.ts +0 -3
  141. package/dist/reset-books.d.ts.map +0 -1
  142. package/dist/reset-books.js.map +0 -1
  143. package/dist/reset-images.d.ts +0 -3
  144. package/dist/reset-images.d.ts.map +0 -1
  145. package/dist/reset-images.js.map +0 -1
  146. package/dist/reset-notes.d.ts +0 -3
  147. package/dist/reset-notes.d.ts.map +0 -1
  148. package/dist/reset-notes.js.map +0 -1
  149. package/dist/revert-articles.d.ts +0 -3
  150. package/dist/revert-articles.d.ts.map +0 -1
  151. package/dist/revert-articles.js.map +0 -1
  152. package/dist/revert-books.d.ts +0 -3
  153. package/dist/revert-books.d.ts.map +0 -1
  154. package/dist/revert-books.js.map +0 -1
  155. package/dist/revert-images.d.ts +0 -3
  156. package/dist/revert-images.d.ts.map +0 -1
  157. package/dist/revert-images.js.map +0 -1
  158. package/dist/revert-notes.d.ts +0 -3
  159. package/dist/revert-notes.d.ts.map +0 -1
  160. package/dist/revert-notes.js.map +0 -1
  161. package/dist/s-content-format-runner.d.ts +0 -10
  162. package/dist/s-content-format-runner.d.ts.map +0 -1
  163. package/dist/s-content-format-runner.js +0 -76
  164. package/dist/s-content-format-runner.js.map +0 -1
  165. package/dist/s-content-format.d.ts +0 -3
  166. package/dist/s-content-format.d.ts.map +0 -1
  167. package/dist/s-content-format.js.map +0 -1
  168. package/dist/s-content-format.test.d.ts +0 -2
  169. package/dist/s-content-format.test.d.ts.map +0 -1
  170. package/dist/s-content-format.test.js +0 -99
  171. package/dist/s-content-format.test.js.map +0 -1
  172. package/dist/update-json-articles.d.ts +0 -3
  173. package/dist/update-json-articles.d.ts.map +0 -1
  174. package/dist/update-json-articles.js.map +0 -1
  175. package/dist/update-raw-articles.d.ts +0 -3
  176. package/dist/update-raw-articles.d.ts.map +0 -1
  177. package/dist/update-raw-articles.js.map +0 -1
  178. package/dist/validate-json-articles.d.ts +0 -3
  179. package/dist/validate-json-articles.d.ts.map +0 -1
  180. package/dist/validate-json-articles.js.map +0 -1
@@ -1,188 +1,37 @@
1
1
  #!/usr/bin/env node
2
- import { makeExportedStatus, makeId, makeUserId, } from "@s-hirano-ist/s-core/shared-kernel/entities/common-entity";
3
- import { createPrismaClient } from "@s-hirano-ist/s-database";
4
- import { createWebpThumbnail, readImageMetadata, } from "@s-hirano-ist/s-image-processing/node";
5
- import { createPushoverService } from "@s-hirano-ist/s-notification";
6
- import { createMinioClient } from "@s-hirano-ist/s-storage";
2
+ import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
+ import {
4
+ runContentImport,
5
+ sharpImageProcessor
6
+ } from "./chunk-5OXUZW2Q.js";
7
+ import "./chunk-KKZP7ZF3.js";
8
+ import "./chunk-F4J6JBR4.js";
9
+ import "./chunk-IWNZQXDG.js";
10
+ import "./chunk-7PVU2Z32.js";
11
+ import {
12
+ globPaths
13
+ } from "./chunk-AJMTRCPJ.js";
14
+ import "./chunk-JZOR5GA2.js";
15
+
16
+ // src/ingest-images.ts
7
17
  import { readFile, stat } from "node:fs/promises";
8
- import { basename, extname } from "node:path";
9
- import { globPaths } from "./lib/glob-paths.js";
10
- const SCRIPT_NAME = "ingest-images";
11
- const ORIGINAL_IMAGE_PATH = "images/original";
12
- const THUMBNAIL_IMAGE_PATH = "images/thumbnail";
13
- const THUMBNAIL_SIZE = 192;
14
- function getContentType(filePath) {
15
- const ext = extname(filePath).toLowerCase();
16
- switch (ext) {
17
- case ".jpg":
18
- case ".jpeg":
19
- return "image/jpeg";
20
- case ".png":
21
- return "image/png";
22
- case ".webp":
23
- return "image/webp";
24
- default:
25
- return null;
26
- }
27
- }
28
- async function main() {
29
- const dryRun = process.argv.includes("--dry-run");
30
- const env = {
31
- DATABASE_URL: process.env.DATABASE_URL,
32
- PUSHOVER_URL: process.env.PUSHOVER_URL,
33
- PUSHOVER_USER_KEY: process.env.PUSHOVER_USER_KEY,
34
- PUSHOVER_APP_TOKEN: process.env.PUSHOVER_APP_TOKEN,
35
- USERNAME_TO_EXPORT: process.env.USERNAME_TO_EXPORT,
36
- MINIO_BUCKET_NAME: process.env.MINIO_BUCKET_NAME,
18
+ import { basename } from "node:path";
19
+ async function* source(root) {
20
+ for (const path of await globPaths(`${root}/image/dump/*`)) {
21
+ const format = /\.(jpg|jpeg|png|webp)$/iu.exec(path)?.[1]?.toLowerCase();
22
+ if (!format) continue;
23
+ const bytes = await readFile(path);
24
+ const metadata = await sharpImageProcessor.getMetadata(bytes);
25
+ yield {
26
+ values: {
27
+ path: basename(path),
28
+ fileSize: (await stat(path)).size,
29
+ contentType: `image/${format === "jpg" ? "jpeg" : format}`,
30
+ width: metadata.width ?? null,
31
+ height: metadata.height ?? null
32
+ },
33
+ media: { path: basename(path), bytes }
37
34
  };
38
- if (Object.values(env).some((v) => !v)) {
39
- throw new Error("Required environment variables are not set.");
40
- }
41
- if (process.env.MINIO_USE_SSL === "true" &&
42
- (!process.env.CF_ACCESS_CLIENT_ID || !process.env.CF_ACCESS_CLIENT_SECRET)) {
43
- throw new Error("CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when MINIO_USE_SSL is true.");
44
- }
45
- const contentsPath = process.env.S_CONTENTS_PATH ?? process.cwd();
46
- const prisma = createPrismaClient(env.DATABASE_URL ?? "");
47
- const notificationService = createPushoverService({
48
- url: env.PUSHOVER_URL ?? "",
49
- userKey: env.PUSHOVER_USER_KEY ?? "",
50
- appToken: env.PUSHOVER_APP_TOKEN ?? "",
51
- });
52
- const minioClient = createMinioClient();
53
- const bucketName = env.MINIO_BUCKET_NAME ?? "";
54
- const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
55
- const exported = makeExportedStatus();
56
- const filePaths = new Set();
57
- async function ingestImages() {
58
- const files = await globPaths(`${contentsPath}/image/dump/*`);
59
- const imageFiles = files.filter((f) => getContentType(f) !== null);
60
- console.log(`📁 ${imageFiles.length} 件の画像ファイルを検出しました。`);
61
- const existingImages = await prisma.image.findMany({
62
- where: { userId },
63
- select: { id: true, path: true },
64
- });
65
- const existingImagesMap = new Map(existingImages.map((i) => [i.path, i]));
66
- console.log(`📊 DB に ${existingImagesMap.size} 件の既存画像があります。`);
67
- let insertedCount = 0;
68
- let skippedCount = 0;
69
- let errorCount = 0;
70
- for (const filePath of imageFiles) {
71
- const imagePath = basename(filePath);
72
- filePaths.add(imagePath);
73
- try {
74
- if (existingImagesMap.has(imagePath)) {
75
- skippedCount++;
76
- continue;
77
- }
78
- const buffer = await readFile(filePath);
79
- const fileStat = await stat(filePath);
80
- const metadata = await readImageMetadata(buffer);
81
- const contentType = getContentType(filePath);
82
- if (!contentType) {
83
- console.log(`⏭️ スキップ(未対応形式): ${imagePath}`);
84
- skippedCount++;
85
- continue;
86
- }
87
- if (dryRun) {
88
- console.log(`🔍 [dry-run] 挿入予定: ${imagePath}`);
89
- insertedCount++;
90
- continue;
91
- }
92
- // Upload original to MinIO if not exists
93
- const originalKey = `${ORIGINAL_IMAGE_PATH}/${imagePath}`;
94
- try {
95
- await minioClient.statObject(bucketName, originalKey);
96
- console.log(`📦 MinIO に既存(original): ${imagePath}`);
97
- }
98
- catch {
99
- await minioClient.putObject(bucketName, originalKey, buffer);
100
- console.log(`📤 MinIO アップロード(original): ${imagePath}`);
101
- }
102
- // Generate and upload thumbnail
103
- const thumbnailBuffer = await createWebpThumbnail(buffer, {
104
- width: THUMBNAIL_SIZE,
105
- height: THUMBNAIL_SIZE,
106
- });
107
- const thumbnailKey = `${THUMBNAIL_IMAGE_PATH}/${imagePath}`;
108
- await minioClient.putObject(bucketName, thumbnailKey, Buffer.from(thumbnailBuffer));
109
- console.log(`📤 MinIO アップロード(thumbnail): ${imagePath}`);
110
- // Create DB record
111
- await prisma.image.create({
112
- data: {
113
- id: String(makeId()),
114
- path: imagePath,
115
- contentType,
116
- fileSize: fileStat.size,
117
- width: metadata.width,
118
- height: metadata.height,
119
- status: exported.status,
120
- exportedAt: exported.exportedAt,
121
- userId,
122
- createdAt: new Date(),
123
- },
124
- });
125
- insertedCount++;
126
- console.log(`✅ 挿入: ${imagePath}`);
127
- }
128
- catch (error) {
129
- console.error(`❌ エラー(${imagePath}):`, error);
130
- errorCount++;
131
- }
132
- }
133
- return { insertedCount, skippedCount, errorCount };
134
- }
135
- async function purgeImages() {
136
- const exportedImages = await prisma.image.findMany({
137
- where: { userId, status: exported.status },
138
- select: { id: true, path: true },
139
- });
140
- const toDelete = exportedImages.filter((i) => !filePaths.has(i.path));
141
- if (toDelete.length === 0) {
142
- console.log("🗑️ 削除対象なし");
143
- return 0;
144
- }
145
- let deletedCount = 0;
146
- for (const image of toDelete) {
147
- try {
148
- if (dryRun) {
149
- console.log(`🗑️ [dry-run] 削除予定: ${image.path}`);
150
- }
151
- else {
152
- await prisma.image.delete({ where: { id: image.id } });
153
- await minioClient.removeObject(bucketName, `${ORIGINAL_IMAGE_PATH}/${image.path}`);
154
- await minioClient.removeObject(bucketName, `${THUMBNAIL_IMAGE_PATH}/${image.path}`);
155
- console.log(`🗑️ 削除: ${image.path}`);
156
- }
157
- deletedCount++;
158
- }
159
- catch (error) {
160
- console.error(`❌ 削除エラー(${image.path}):`, error);
161
- }
162
- }
163
- return deletedCount;
164
- }
165
- try {
166
- const { insertedCount, skippedCount, errorCount } = await ingestImages();
167
- const deletedCount = await purgeImages();
168
- console.log(`\n📊 結果: 挿入 ${insertedCount} 件, スキップ ${skippedCount} 件, 削除 ${deletedCount} 件, エラー ${errorCount} 件${dryRun ? " (dry-run)" : ""}`);
169
- await notificationService.notifyInfo(`${SCRIPT_NAME} completed`, {
170
- caller: SCRIPT_NAME,
171
- });
172
- }
173
- catch (error) {
174
- console.error("❌ エラーが発生しました:", error);
175
- await notificationService.notifyError(`${SCRIPT_NAME} failed: ${String(error)}`, {
176
- caller: SCRIPT_NAME,
177
- });
178
- process.exit(1);
179
- }
180
- finally {
181
- await prisma.$disconnect();
182
- }
35
+ }
183
36
  }
184
- main().catch((error) => {
185
- console.error(error);
186
- process.exit(1);
187
- });
188
- //# sourceMappingURL=ingest-images.js.map
37
+ await runContentImport("images", source);
@@ -1,179 +1,49 @@
1
1
  #!/usr/bin/env node
2
- import { makeExportedStatus, makeId, makeUserId, } from "@s-hirano-ist/s-core/shared-kernel/entities/common-entity";
3
- import { createPrismaClient } from "@s-hirano-ist/s-database";
4
- import { createPushoverService } from "@s-hirano-ist/s-notification";
5
- import { parseMarkdownFrontmatter } from "@s-hirano-ist/s-search/frontmatter";
2
+ import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
+ import {
4
+ runContentImport
5
+ } from "./chunk-5OXUZW2Q.js";
6
+ import "./chunk-KKZP7ZF3.js";
7
+ import "./chunk-F4J6JBR4.js";
8
+ import "./chunk-IWNZQXDG.js";
9
+ import "./chunk-7PVU2Z32.js";
10
+ import {
11
+ parseMarkdownFrontmatter
12
+ } from "./chunk-HDYQV2Y2.js";
13
+ import {
14
+ globPaths
15
+ } from "./chunk-AJMTRCPJ.js";
16
+ import "./chunk-JZOR5GA2.js";
17
+
18
+ // src/ingest-notes.ts
6
19
  import { readFile } from "node:fs/promises";
7
20
  import { basename } from "node:path";
8
- import { globPaths } from "./lib/glob-paths.js";
9
- const SCRIPT_NAME = "ingest-notes";
10
21
  function parseFrontmatter(content) {
11
- const parsed = parseMarkdownFrontmatter(content);
12
- return {
13
- body: parsed.content.trim(),
14
- draft: typeof parsed.data.draft === "boolean" ? parsed.data.draft : undefined,
15
- heading: typeof parsed.data.heading === "string" ? parsed.data.heading : undefined,
16
- };
22
+ const parsed = parseMarkdownFrontmatter(content);
23
+ return {
24
+ body: parsed.content.trim(),
25
+ draft: typeof parsed.data.draft === "boolean" ? parsed.data.draft : void 0,
26
+ heading: typeof parsed.data.heading === "string" ? parsed.data.heading : void 0
27
+ };
17
28
  }
18
29
  function parseNoteFile(filePath, content) {
19
- const { heading, draft, body } = parseFrontmatter(content);
20
- if (draft)
21
- return null;
22
- if (heading) {
23
- return { title: heading, markdown: body };
24
- }
25
- const title = basename(filePath, ".md");
26
- const titleLine = `# ${title}`;
27
- let markdown = body;
28
- if (markdown.startsWith(titleLine)) {
29
- markdown = markdown.slice(titleLine.length).replace(/^\n+/u, "");
30
- }
31
- return { title, markdown };
30
+ const { heading, draft, body } = parseFrontmatter(content);
31
+ if (draft) return null;
32
+ if (heading) {
33
+ return { title: heading, markdown: body };
34
+ }
35
+ const title = basename(filePath, ".md");
36
+ const titleLine = `# ${title}`;
37
+ let markdown = body;
38
+ if (markdown.startsWith(titleLine)) {
39
+ markdown = markdown.slice(titleLine.length).replace(/^\n+/u, "");
40
+ }
41
+ return { title, markdown };
32
42
  }
33
- async function main() {
34
- const dryRun = process.argv.includes("--dry-run");
35
- const env = {
36
- DATABASE_URL: process.env.DATABASE_URL,
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
- USERNAME_TO_EXPORT: process.env.USERNAME_TO_EXPORT,
41
- };
42
- if (Object.values(env).some((v) => !v)) {
43
- throw new Error("Required environment variables are not set.");
44
- }
45
- const contentsPath = process.env.S_CONTENTS_PATH ?? process.cwd();
46
- const prisma = createPrismaClient(env.DATABASE_URL ?? "");
47
- const notificationService = createPushoverService({
48
- url: env.PUSHOVER_URL ?? "",
49
- userKey: env.PUSHOVER_USER_KEY ?? "",
50
- appToken: env.PUSHOVER_APP_TOKEN ?? "",
51
- });
52
- const userId = makeUserId(env.USERNAME_TO_EXPORT ?? "");
53
- const exported = makeExportedStatus();
54
- const fileTitles = new Set();
55
- async function ingestNotes() {
56
- const files = await globPaths(`${contentsPath}/markdown/note/*.md`);
57
- console.log(`📁 ${files.length} 件のファイルを検出しました。`);
58
- const existingNotes = await prisma.note.findMany({
59
- where: { userId },
60
- select: { id: true, title: true, markdown: true },
61
- });
62
- const existingNotesMap = new Map(existingNotes.map((n) => [n.title, n]));
63
- console.log(`📊 DB に ${existingNotesMap.size} 件の既存ノートがあります。`);
64
- async function upsertNote(parsed) {
65
- fileTitles.add(parsed.title);
66
- const existing = existingNotesMap.get(parsed.title);
67
- if (existing) {
68
- if (existing.markdown === parsed.markdown) {
69
- // console.log(`⏭️ スキップ(変更なし): ${parsed.title}`);
70
- return "skipped";
71
- }
72
- if (dryRun) {
73
- console.log(`🔄 [dry-run] 更新予定: ${parsed.title}`);
74
- }
75
- else {
76
- await prisma.note.update({
77
- where: { id: existing.id },
78
- data: { markdown: parsed.markdown },
79
- });
80
- console.log(`🔄 更新: ${parsed.title}`);
81
- }
82
- return "updated";
83
- }
84
- if (dryRun) {
85
- console.log(`🔍 [dry-run] 挿入予定: ${parsed.title}`);
86
- return "inserted";
87
- }
88
- await prisma.note.create({
89
- data: {
90
- id: String(makeId()),
91
- title: parsed.title,
92
- markdown: parsed.markdown,
93
- status: exported.status,
94
- exportedAt: exported.exportedAt,
95
- userId,
96
- createdAt: new Date(),
97
- },
98
- });
99
- console.log(`✅ 挿入: ${parsed.title}`);
100
- return "inserted";
101
- }
102
- let insertedCount = 0;
103
- let updatedCount = 0;
104
- let skippedCount = 0;
105
- let errorCount = 0;
106
- for (const filePath of files) {
107
- let parsed = null;
108
- try {
109
- const content = await readFile(filePath, "utf-8");
110
- parsed = parseNoteFile(filePath, content);
111
- if (!parsed) {
112
- console.log(`⏭️ スキップ(draft): ${basename(filePath)}`);
113
- skippedCount++;
114
- continue;
115
- }
116
- const result = await upsertNote(parsed);
117
- if (result === "inserted")
118
- insertedCount++;
119
- else if (result === "updated")
120
- updatedCount++;
121
- else
122
- skippedCount++;
123
- }
124
- catch (error) {
125
- console.error(`❌ エラー(${basename(filePath)}):`, parsed
126
- ? `title(${parsed.title.length}文字) markdown(${parsed.markdown.length}文字)`
127
- : "parse前", error);
128
- errorCount++;
129
- }
130
- }
131
- return { insertedCount, updatedCount, skippedCount, errorCount };
132
- }
133
- async function purgeNotes() {
134
- const exportedNotes = await prisma.note.findMany({
135
- where: { userId, status: exported.status },
136
- select: { id: true, title: true },
137
- });
138
- const toDelete = exportedNotes.filter((n) => !fileTitles.has(n.title));
139
- if (toDelete.length === 0) {
140
- console.log("🗑️ 削除対象なし");
141
- return 0;
142
- }
143
- let deletedCount = 0;
144
- for (const note of toDelete) {
145
- if (dryRun) {
146
- console.log(`🗑️ [dry-run] 削除予定: ${note.title}`);
147
- }
148
- else {
149
- await prisma.note.delete({ where: { id: note.id } });
150
- console.log(`🗑️ 削除: ${note.title}`);
151
- }
152
- deletedCount++;
153
- }
154
- return deletedCount;
155
- }
156
- try {
157
- const { insertedCount, updatedCount, skippedCount, errorCount } = await ingestNotes();
158
- const deletedCount = await purgeNotes();
159
- console.log(`\n📊 結果: 挿入 ${insertedCount} 件, 更新 ${updatedCount} 件, スキップ ${skippedCount} 件, 削除 ${deletedCount} 件, エラー ${errorCount} 件${dryRun ? " (dry-run)" : ""}`);
160
- await notificationService.notifyInfo(`${SCRIPT_NAME} completed`, {
161
- caller: SCRIPT_NAME,
162
- });
163
- }
164
- catch (error) {
165
- console.error("❌ エラーが発生しました:", error);
166
- await notificationService.notifyError(`${SCRIPT_NAME} failed: ${String(error)}`, {
167
- caller: SCRIPT_NAME,
168
- });
169
- process.exit(1);
170
- }
171
- finally {
172
- await prisma.$disconnect();
173
- }
43
+ async function* source(root) {
44
+ for (const path of await globPaths(`${root}/markdown/note/*.md`)) {
45
+ const values = parseNoteFile(path, await readFile(path, "utf-8"));
46
+ if (values) yield { values };
47
+ }
174
48
  }
175
- main().catch((error) => {
176
- console.error(error);
177
- process.exit(1);
178
- });
179
- //# sourceMappingURL=ingest-notes.js.map
49
+ await runContentImport("notes", source);
@@ -1,27 +1,37 @@
1
1
  #!/usr/bin/env node
2
- import { deleteCollection, getQdrantClient, } from "@s-hirano-ist/s-search/qdrant-client";
2
+ import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
3
+ import {
4
+ deleteCollection,
5
+ getQdrantClient
6
+ } from "../chunk-J4VLH4VA.js";
7
+ import "../chunk-JZOR5GA2.js";
8
+
9
+ // src/rag/delete-collection.ts
3
10
  async function main() {
4
- const collectionName = process.argv[2];
5
- if (!collectionName) {
6
- console.error("Usage: rag-delete-collection <collection-name>\nExample: rag-delete-collection knowledge_v1");
7
- process.exit(1);
8
- }
9
- if (!process.env.QDRANT_URL) {
10
- throw new Error("QDRANT_URL environment variable is required.");
11
- }
12
- const qdrant = getQdrantClient();
13
- const collections = await qdrant.getCollections();
14
- const exists = collections.collections.some((c) => c.name === collectionName);
15
- if (!exists) {
16
- console.log(`Collection "${collectionName}" does not exist. Nothing to delete.`);
17
- return;
18
- }
19
- console.log(`Deleting collection "${collectionName}"...`);
20
- await deleteCollection(collectionName);
21
- console.log(`Collection "${collectionName}" deleted successfully.`);
11
+ const collectionName = process.argv[2];
12
+ if (!collectionName) {
13
+ console.error(
14
+ "Usage: rag-delete-collection <collection-name>\nExample: rag-delete-collection knowledge_v1"
15
+ );
16
+ process.exit(1);
17
+ }
18
+ if (!process.env.QDRANT_URL) {
19
+ throw new Error("QDRANT_URL environment variable is required.");
20
+ }
21
+ const qdrant = getQdrantClient();
22
+ const collections = await qdrant.getCollections();
23
+ const exists = collections.collections.some((c) => c.name === collectionName);
24
+ if (!exists) {
25
+ console.log(
26
+ `Collection "${collectionName}" does not exist. Nothing to delete.`
27
+ );
28
+ return;
29
+ }
30
+ console.log(`Deleting collection "${collectionName}"...`);
31
+ await deleteCollection(collectionName);
32
+ console.log(`Collection "${collectionName}" deleted successfully.`);
22
33
  }
23
34
  main().catch((error) => {
24
- console.error("Failed to delete collection:", error);
25
- process.exit(1);
35
+ console.error("Failed to delete collection:", error);
36
+ process.exit(1);
26
37
  });
27
- //# sourceMappingURL=delete-collection.js.map