@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.
- package/README.md +2 -0
- package/dist/chunk-5OXUZW2Q.js +590 -0
- package/dist/chunk-7PVU2Z32.js +71 -0
- package/dist/chunk-AJMTRCPJ.js +15 -0
- package/dist/chunk-AZF2R2BF.js +85 -0
- package/dist/chunk-F4J6JBR4.js +115 -0
- package/dist/chunk-HDYQV2Y2.js +58 -0
- package/dist/chunk-HIK7SX34.js +85 -0
- package/dist/chunk-IWNZQXDG.js +7660 -0
- package/dist/chunk-J4VLH4VA.js +267 -0
- package/dist/chunk-JZOR5GA2.js +42 -0
- package/dist/chunk-KKZP7ZF3.js +77 -0
- package/dist/chunk-N6TZF755.js +102 -0
- package/dist/chunk-S5WJ5VXW.js +85 -0
- package/dist/chunk-UXGLXHQ6.js +40 -0
- package/dist/cleanup-minio-images.js +115 -92
- package/dist/enrich-books.js +87 -78
- package/dist/fetch-articles.js +101 -90
- package/dist/fetch-books.js +147 -128
- package/dist/fetch-images.js +88 -72
- package/dist/fetch-notes.js +66 -54
- package/dist/find-duplicate-json-articles.js +100 -97
- package/dist/fix-book-frontmatter.js +111 -99
- package/dist/fix-image-formats.js +81 -65
- package/dist/ingest-articles.js +30 -249
- package/dist/ingest-books.js +61 -318
- package/dist/ingest-images.js +33 -184
- package/dist/ingest-notes.js +41 -171
- package/dist/rag/delete-collection.js +32 -22
- package/dist/rag/ingest.js +371 -92
- package/dist/rag/search.js +80 -76
- package/dist/reset-articles.js +57 -60
- package/dist/reset-books.js +57 -59
- package/dist/reset-images.js +57 -59
- package/dist/reset-notes.js +57 -59
- package/dist/revert-articles.js +53 -55
- package/dist/revert-books.js +53 -53
- package/dist/revert-images.js +53 -53
- package/dist/revert-notes.js +53 -53
- package/dist/s-content-format.js +103 -13
- package/dist/update-json-articles.js +101 -97
- package/dist/update-raw-articles.js +130 -130
- package/dist/validate-json-articles.js +129 -130
- package/package.json +14 -51
- package/dist/cleanup-minio-images.d.ts +0 -3
- package/dist/cleanup-minio-images.d.ts.map +0 -1
- package/dist/cleanup-minio-images.js.map +0 -1
- package/dist/enrich-books.d.ts +0 -3
- package/dist/enrich-books.d.ts.map +0 -1
- package/dist/enrich-books.js.map +0 -1
- package/dist/fetch-articles.d.ts +0 -3
- package/dist/fetch-articles.d.ts.map +0 -1
- package/dist/fetch-articles.js.map +0 -1
- package/dist/fetch-books.d.ts +0 -3
- package/dist/fetch-books.d.ts.map +0 -1
- package/dist/fetch-books.js.map +0 -1
- package/dist/fetch-images.d.ts +0 -3
- package/dist/fetch-images.d.ts.map +0 -1
- package/dist/fetch-images.js.map +0 -1
- package/dist/fetch-notes.d.ts +0 -3
- package/dist/fetch-notes.d.ts.map +0 -1
- package/dist/fetch-notes.js.map +0 -1
- package/dist/find-duplicate-json-articles.d.ts +0 -3
- package/dist/find-duplicate-json-articles.d.ts.map +0 -1
- package/dist/find-duplicate-json-articles.js.map +0 -1
- package/dist/fix-book-frontmatter.d.ts +0 -3
- package/dist/fix-book-frontmatter.d.ts.map +0 -1
- package/dist/fix-book-frontmatter.js.map +0 -1
- package/dist/fix-image-formats.d.ts +0 -3
- package/dist/fix-image-formats.d.ts.map +0 -1
- package/dist/fix-image-formats.js.map +0 -1
- package/dist/infrastructures/articles-command-repository.d.ts +0 -57
- package/dist/infrastructures/articles-command-repository.d.ts.map +0 -1
- package/dist/infrastructures/articles-command-repository.js +0 -68
- package/dist/infrastructures/articles-command-repository.js.map +0 -1
- package/dist/infrastructures/books-command-repository.d.ts +0 -34
- package/dist/infrastructures/books-command-repository.d.ts.map +0 -1
- package/dist/infrastructures/books-command-repository.js +0 -53
- package/dist/infrastructures/books-command-repository.js.map +0 -1
- package/dist/infrastructures/cache-invalidation-client.d.ts +0 -9
- package/dist/infrastructures/cache-invalidation-client.d.ts.map +0 -1
- package/dist/infrastructures/cache-invalidation-client.js +0 -21
- package/dist/infrastructures/cache-invalidation-client.js.map +0 -1
- package/dist/infrastructures/cache-invalidation-client.test.d.ts +0 -2
- package/dist/infrastructures/cache-invalidation-client.test.d.ts.map +0 -1
- package/dist/infrastructures/cache-invalidation-client.test.js +0 -25
- package/dist/infrastructures/cache-invalidation-client.test.js.map +0 -1
- package/dist/infrastructures/images-command-repository.d.ts +0 -34
- package/dist/infrastructures/images-command-repository.d.ts.map +0 -1
- package/dist/infrastructures/images-command-repository.js +0 -53
- package/dist/infrastructures/images-command-repository.js.map +0 -1
- package/dist/infrastructures/notes-command-repository.d.ts +0 -34
- package/dist/infrastructures/notes-command-repository.d.ts.map +0 -1
- package/dist/infrastructures/notes-command-repository.js +0 -53
- package/dist/infrastructures/notes-command-repository.js.map +0 -1
- package/dist/ingest-articles.d.ts +0 -3
- package/dist/ingest-articles.d.ts.map +0 -1
- package/dist/ingest-articles.js.map +0 -1
- package/dist/ingest-books.d.ts +0 -3
- package/dist/ingest-books.d.ts.map +0 -1
- package/dist/ingest-books.js.map +0 -1
- package/dist/ingest-images.d.ts +0 -3
- package/dist/ingest-images.d.ts.map +0 -1
- package/dist/ingest-images.js.map +0 -1
- package/dist/ingest-notes.d.ts +0 -3
- package/dist/ingest-notes.d.ts.map +0 -1
- package/dist/ingest-notes.js.map +0 -1
- package/dist/lib/glob-paths.d.ts +0 -6
- package/dist/lib/glob-paths.d.ts.map +0 -1
- package/dist/lib/glob-paths.js +0 -9
- package/dist/lib/glob-paths.js.map +0 -1
- package/dist/lib/glob-paths.test.d.ts +0 -2
- package/dist/lib/glob-paths.test.d.ts.map +0 -1
- package/dist/lib/glob-paths.test.js +0 -30
- package/dist/lib/glob-paths.test.js.map +0 -1
- package/dist/lib/html-charset.d.ts +0 -4
- package/dist/lib/html-charset.d.ts.map +0 -1
- package/dist/lib/html-charset.js +0 -33
- package/dist/lib/html-charset.js.map +0 -1
- package/dist/lib/html-charset.test.d.ts +0 -2
- package/dist/lib/html-charset.test.d.ts.map +0 -1
- package/dist/lib/html-charset.test.js +0 -27
- package/dist/lib/html-charset.test.js.map +0 -1
- package/dist/rag/delete-collection.d.ts +0 -3
- package/dist/rag/delete-collection.d.ts.map +0 -1
- package/dist/rag/delete-collection.js.map +0 -1
- package/dist/rag/ingest-config.d.ts +0 -8
- package/dist/rag/ingest-config.d.ts.map +0 -1
- package/dist/rag/ingest-config.js +0 -8
- package/dist/rag/ingest-config.js.map +0 -1
- package/dist/rag/ingest.d.ts +0 -3
- package/dist/rag/ingest.d.ts.map +0 -1
- package/dist/rag/ingest.js.map +0 -1
- package/dist/rag/search.d.ts +0 -3
- package/dist/rag/search.d.ts.map +0 -1
- package/dist/rag/search.js.map +0 -1
- package/dist/reset-articles.d.ts +0 -3
- package/dist/reset-articles.d.ts.map +0 -1
- package/dist/reset-articles.js.map +0 -1
- package/dist/reset-books.d.ts +0 -3
- package/dist/reset-books.d.ts.map +0 -1
- package/dist/reset-books.js.map +0 -1
- package/dist/reset-images.d.ts +0 -3
- package/dist/reset-images.d.ts.map +0 -1
- package/dist/reset-images.js.map +0 -1
- package/dist/reset-notes.d.ts +0 -3
- package/dist/reset-notes.d.ts.map +0 -1
- package/dist/reset-notes.js.map +0 -1
- package/dist/revert-articles.d.ts +0 -3
- package/dist/revert-articles.d.ts.map +0 -1
- package/dist/revert-articles.js.map +0 -1
- package/dist/revert-books.d.ts +0 -3
- package/dist/revert-books.d.ts.map +0 -1
- package/dist/revert-books.js.map +0 -1
- package/dist/revert-images.d.ts +0 -3
- package/dist/revert-images.d.ts.map +0 -1
- package/dist/revert-images.js.map +0 -1
- package/dist/revert-notes.d.ts +0 -3
- package/dist/revert-notes.d.ts.map +0 -1
- package/dist/revert-notes.js.map +0 -1
- package/dist/s-content-format-runner.d.ts +0 -10
- package/dist/s-content-format-runner.d.ts.map +0 -1
- package/dist/s-content-format-runner.js +0 -76
- package/dist/s-content-format-runner.js.map +0 -1
- package/dist/s-content-format.d.ts +0 -3
- package/dist/s-content-format.d.ts.map +0 -1
- package/dist/s-content-format.js.map +0 -1
- package/dist/s-content-format.test.d.ts +0 -2
- package/dist/s-content-format.test.d.ts.map +0 -1
- package/dist/s-content-format.test.js +0 -99
- package/dist/s-content-format.test.js.map +0 -1
- package/dist/update-json-articles.d.ts +0 -3
- package/dist/update-json-articles.d.ts.map +0 -1
- package/dist/update-json-articles.js.map +0 -1
- package/dist/update-raw-articles.d.ts +0 -3
- package/dist/update-raw-articles.d.ts.map +0 -1
- package/dist/update-raw-articles.js.map +0 -1
- package/dist/validate-json-articles.d.ts +0 -3
- package/dist/validate-json-articles.d.ts.map +0 -1
- package/dist/validate-json-articles.js.map +0 -1
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
makeExportedAt,
|
|
4
|
+
withTransactionRetry
|
|
5
|
+
} from "./chunk-IWNZQXDG.js";
|
|
6
|
+
|
|
7
|
+
// ../application/dist/batch/books-batch-service.js
|
|
8
|
+
var BooksBatchApplicationService = class {
|
|
9
|
+
commandRepository;
|
|
10
|
+
constructor(commandRepository) {
|
|
11
|
+
this.commandRepository = commandRepository;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resets books for a new batch export.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Delegates to repository's resetStatus which performs two operations
|
|
18
|
+
* atomically within a single transaction.
|
|
19
|
+
*/
|
|
20
|
+
async resetBooks(userId) {
|
|
21
|
+
return this.commandRepository.resetStatus(userId, makeExportedAt());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reverts books from LAST_UPDATED back to UNEXPORTED.
|
|
25
|
+
*/
|
|
26
|
+
async revertBooks(userId) {
|
|
27
|
+
return this.commandRepository.bulkUpdateStatus({
|
|
28
|
+
userId,
|
|
29
|
+
fromStatus: "LAST_UPDATED",
|
|
30
|
+
toStatus: "UNEXPORTED"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ../infrastructure/dist/batch/books-command-repository.js
|
|
36
|
+
function createBooksCommandRepository(prisma) {
|
|
37
|
+
return {
|
|
38
|
+
async bulkUpdateStatus(params) {
|
|
39
|
+
const { userId, fromStatus, toStatus, exportedAt } = params;
|
|
40
|
+
const result = await prisma.book.updateMany({
|
|
41
|
+
where: {
|
|
42
|
+
userId,
|
|
43
|
+
status: fromStatus
|
|
44
|
+
},
|
|
45
|
+
data: {
|
|
46
|
+
status: toStatus,
|
|
47
|
+
...exportedAt && { exportedAt }
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return { count: result.count };
|
|
51
|
+
},
|
|
52
|
+
async resetStatus(userId, exportedAt) {
|
|
53
|
+
const [finalized, marked] = await withTransactionRetry(() => prisma.$transaction([
|
|
54
|
+
prisma.book.updateMany({
|
|
55
|
+
where: {
|
|
56
|
+
userId,
|
|
57
|
+
status: "LAST_UPDATED"
|
|
58
|
+
},
|
|
59
|
+
data: {
|
|
60
|
+
status: "EXPORTED",
|
|
61
|
+
exportedAt
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
prisma.book.updateMany({
|
|
65
|
+
where: {
|
|
66
|
+
userId,
|
|
67
|
+
status: "UNEXPORTED"
|
|
68
|
+
},
|
|
69
|
+
data: {
|
|
70
|
+
status: "LAST_UPDATED"
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
]));
|
|
74
|
+
return {
|
|
75
|
+
finalized: { count: finalized.count },
|
|
76
|
+
marked: { count: marked.count }
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export {
|
|
83
|
+
BooksBatchApplicationService,
|
|
84
|
+
createBooksCommandRepository
|
|
85
|
+
};
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// ../storage/dist/src/client.js
|
|
4
|
+
import { Client } from "minio";
|
|
5
|
+
|
|
6
|
+
// ../storage/dist/src/cf-access-transport.js
|
|
7
|
+
import * as https from "node:https";
|
|
8
|
+
function createCfAccessTransport(config) {
|
|
9
|
+
if (!config?.clientId || !config.clientSecret) {
|
|
10
|
+
return void 0;
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
request(options, ...rest) {
|
|
14
|
+
if (typeof options === "object" && !(options instanceof URL)) {
|
|
15
|
+
const headers = options.headers ?? {};
|
|
16
|
+
headers["CF-Access-Client-Id"] = config.clientId;
|
|
17
|
+
headers["CF-Access-Client-Secret"] = config.clientSecret;
|
|
18
|
+
options.headers = headers;
|
|
19
|
+
}
|
|
20
|
+
const request2 = https.request;
|
|
21
|
+
return request2(options, ...rest);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ../storage/dist/src/client.js
|
|
27
|
+
function createMinioClient(config, cfAccess) {
|
|
28
|
+
const resolved = config ?? {
|
|
29
|
+
endPoint: process.env.MINIO_HOST ?? "",
|
|
30
|
+
port: Number(process.env.MINIO_PORT),
|
|
31
|
+
useSSL: process.env.MINIO_USE_SSL === void 0 ? !["localhost", "127.0.0.1"].includes(process.env.MINIO_HOST ?? "") : process.env.MINIO_USE_SSL === "true",
|
|
32
|
+
accessKey: process.env.MINIO_ACCESS_KEY ?? "",
|
|
33
|
+
secretKey: process.env.MINIO_SECRET_KEY ?? ""
|
|
34
|
+
};
|
|
35
|
+
const resolvedCfAccess = cfAccess ?? {
|
|
36
|
+
clientId: process.env.CF_ACCESS_CLIENT_ID ?? "",
|
|
37
|
+
clientSecret: process.env.CF_ACCESS_CLIENT_SECRET ?? ""
|
|
38
|
+
};
|
|
39
|
+
const transport = resolved.useSSL ? createCfAccessTransport(resolvedCfAccess) : void 0;
|
|
40
|
+
if (resolved.useSSL && !transport) {
|
|
41
|
+
throw new Error("CF_ACCESS_CLIENT_ID and CF_ACCESS_CLIENT_SECRET are required when useSSL is true.");
|
|
42
|
+
}
|
|
43
|
+
return new Client({
|
|
44
|
+
endPoint: resolved.endPoint,
|
|
45
|
+
port: resolved.port,
|
|
46
|
+
useSSL: resolved.useSSL,
|
|
47
|
+
accessKey: resolved.accessKey,
|
|
48
|
+
secretKey: resolved.secretKey,
|
|
49
|
+
...transport && { transport }
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
// ../storage/dist/index.js
|
|
54
|
+
import { S3Error } from "minio";
|
|
55
|
+
|
|
56
|
+
// ../storage/dist/src/errors.js
|
|
57
|
+
var StorageOperationError = class extends Error {
|
|
58
|
+
context;
|
|
59
|
+
constructor(context, cause) {
|
|
60
|
+
super(`Storage ${context.operation} failed for ${context.objectKey}`, {
|
|
61
|
+
cause
|
|
62
|
+
});
|
|
63
|
+
this.name = "StorageOperationError";
|
|
64
|
+
this.context = context;
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// ../storage/dist/src/storage-service.js
|
|
69
|
+
function createStorageService(client, bucketName, pathConfig) {
|
|
70
|
+
function buildObjectKey(path, isThumbnail) {
|
|
71
|
+
return `${isThumbnail ? pathConfig.thumbnailPrefix : pathConfig.originalPrefix}/${path}`;
|
|
72
|
+
}
|
|
73
|
+
function wrapStorageError(operation, objectKey, isThumbnail, error) {
|
|
74
|
+
throw new StorageOperationError({ operation, objectKey, bucketName, isThumbnail }, error);
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
async uploadImage(path, bytes, isThumbnail) {
|
|
78
|
+
const objKey = buildObjectKey(path, isThumbnail);
|
|
79
|
+
try {
|
|
80
|
+
await client.putObject(bucketName, objKey, Buffer.from(bytes));
|
|
81
|
+
} catch (error) {
|
|
82
|
+
wrapStorageError("uploadImage", objKey, isThumbnail, error);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
async getImage(path, isThumbnail) {
|
|
86
|
+
const objKey = buildObjectKey(path, isThumbnail);
|
|
87
|
+
try {
|
|
88
|
+
return await client.getObject(bucketName, objKey);
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return wrapStorageError("getImage", objKey, isThumbnail, error);
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
async getImageOrThrow(path, isThumbnail) {
|
|
94
|
+
const objKey = buildObjectKey(path, isThumbnail);
|
|
95
|
+
try {
|
|
96
|
+
await client.statObject(bucketName, objKey);
|
|
97
|
+
} catch (error) {
|
|
98
|
+
wrapStorageError("getImageOrThrow", objKey, isThumbnail, error);
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
async deleteImage(path, isThumbnail) {
|
|
102
|
+
const objKey = buildObjectKey(path, isThumbnail);
|
|
103
|
+
try {
|
|
104
|
+
await client.removeObject(bucketName, objKey);
|
|
105
|
+
} catch (error) {
|
|
106
|
+
wrapStorageError("deleteImage", objKey, isThumbnail, error);
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export {
|
|
113
|
+
createMinioClient,
|
|
114
|
+
createStorageService
|
|
115
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// ../search/dist/frontmatter.js
|
|
4
|
+
import { load } from "js-yaml";
|
|
5
|
+
var BYTE_ORDER_MARK = "\uFEFF";
|
|
6
|
+
var OPENING_DELIMITER_REGEX = /^---[\t ]*\r?\n/u;
|
|
7
|
+
var CLOSING_DELIMITER_REGEX = /^---[\t ]*\r?$/gmu;
|
|
8
|
+
function stripByteOrderMark(source) {
|
|
9
|
+
return source.startsWith(BYTE_ORDER_MARK) ? source.slice(1) : source;
|
|
10
|
+
}
|
|
11
|
+
function getContentStart(source, delimiterEnd) {
|
|
12
|
+
if (source.startsWith("\r\n", delimiterEnd)) {
|
|
13
|
+
return delimiterEnd + 2;
|
|
14
|
+
}
|
|
15
|
+
if (source.startsWith("\n", delimiterEnd)) {
|
|
16
|
+
return delimiterEnd + 1;
|
|
17
|
+
}
|
|
18
|
+
return delimiterEnd;
|
|
19
|
+
}
|
|
20
|
+
function parseYamlObject(source) {
|
|
21
|
+
if (source.trim() === "") {
|
|
22
|
+
return {};
|
|
23
|
+
}
|
|
24
|
+
const parsed = load(source);
|
|
25
|
+
if (parsed === void 0) {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed)) {
|
|
29
|
+
throw new Error("Markdown frontmatter must be a YAML object.");
|
|
30
|
+
}
|
|
31
|
+
return parsed;
|
|
32
|
+
}
|
|
33
|
+
function parseMarkdownFrontmatter(source) {
|
|
34
|
+
const normalizedSource = stripByteOrderMark(source);
|
|
35
|
+
const openingDelimiter = OPENING_DELIMITER_REGEX.exec(normalizedSource);
|
|
36
|
+
if (!openingDelimiter) {
|
|
37
|
+
if (/^---[\t ]*$/u.test(normalizedSource)) {
|
|
38
|
+
throw new Error("Markdown frontmatter is missing a closing delimiter.");
|
|
39
|
+
}
|
|
40
|
+
return { content: normalizedSource, data: {} };
|
|
41
|
+
}
|
|
42
|
+
CLOSING_DELIMITER_REGEX.lastIndex = openingDelimiter[0].length;
|
|
43
|
+
const closingDelimiter = CLOSING_DELIMITER_REGEX.exec(normalizedSource);
|
|
44
|
+
CLOSING_DELIMITER_REGEX.lastIndex = 0;
|
|
45
|
+
if (!closingDelimiter) {
|
|
46
|
+
throw new Error("Markdown frontmatter is missing a closing delimiter.");
|
|
47
|
+
}
|
|
48
|
+
const yamlSource = normalizedSource.slice(openingDelimiter[0].length, closingDelimiter.index);
|
|
49
|
+
const contentStart = getContentStart(normalizedSource, closingDelimiter.index + closingDelimiter[0].length);
|
|
50
|
+
return {
|
|
51
|
+
content: normalizedSource.slice(contentStart),
|
|
52
|
+
data: parseYamlObject(yamlSource)
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export {
|
|
57
|
+
parseMarkdownFrontmatter
|
|
58
|
+
};
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { createRequire as __cliCreateRequire } from "node:module"; const require = __cliCreateRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
makeExportedAt,
|
|
4
|
+
withTransactionRetry
|
|
5
|
+
} from "./chunk-IWNZQXDG.js";
|
|
6
|
+
|
|
7
|
+
// ../application/dist/batch/images-batch-service.js
|
|
8
|
+
var ImagesBatchApplicationService = class {
|
|
9
|
+
commandRepository;
|
|
10
|
+
constructor(commandRepository) {
|
|
11
|
+
this.commandRepository = commandRepository;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Resets images for a new batch export.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Delegates to repository's resetStatus which performs two operations
|
|
18
|
+
* atomically within a single transaction.
|
|
19
|
+
*/
|
|
20
|
+
async resetImages(userId) {
|
|
21
|
+
return this.commandRepository.resetStatus(userId, makeExportedAt());
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Reverts images from LAST_UPDATED back to UNEXPORTED.
|
|
25
|
+
*/
|
|
26
|
+
async revertImages(userId) {
|
|
27
|
+
return this.commandRepository.bulkUpdateStatus({
|
|
28
|
+
userId,
|
|
29
|
+
fromStatus: "LAST_UPDATED",
|
|
30
|
+
toStatus: "UNEXPORTED"
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
// ../infrastructure/dist/batch/images-command-repository.js
|
|
36
|
+
function createImagesCommandRepository(prisma) {
|
|
37
|
+
return {
|
|
38
|
+
async bulkUpdateStatus(params) {
|
|
39
|
+
const { userId, fromStatus, toStatus, exportedAt } = params;
|
|
40
|
+
const result = await prisma.image.updateMany({
|
|
41
|
+
where: {
|
|
42
|
+
userId,
|
|
43
|
+
status: fromStatus
|
|
44
|
+
},
|
|
45
|
+
data: {
|
|
46
|
+
status: toStatus,
|
|
47
|
+
...exportedAt && { exportedAt }
|
|
48
|
+
}
|
|
49
|
+
});
|
|
50
|
+
return { count: result.count };
|
|
51
|
+
},
|
|
52
|
+
async resetStatus(userId, exportedAt) {
|
|
53
|
+
const [finalized, marked] = await withTransactionRetry(() => prisma.$transaction([
|
|
54
|
+
prisma.image.updateMany({
|
|
55
|
+
where: {
|
|
56
|
+
userId,
|
|
57
|
+
status: "LAST_UPDATED"
|
|
58
|
+
},
|
|
59
|
+
data: {
|
|
60
|
+
status: "EXPORTED",
|
|
61
|
+
exportedAt
|
|
62
|
+
}
|
|
63
|
+
}),
|
|
64
|
+
prisma.image.updateMany({
|
|
65
|
+
where: {
|
|
66
|
+
userId,
|
|
67
|
+
status: "UNEXPORTED"
|
|
68
|
+
},
|
|
69
|
+
data: {
|
|
70
|
+
status: "LAST_UPDATED"
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
]));
|
|
74
|
+
return {
|
|
75
|
+
finalized: { count: finalized.count },
|
|
76
|
+
marked: { count: marked.count }
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export {
|
|
83
|
+
ImagesBatchApplicationService,
|
|
84
|
+
createImagesCommandRepository
|
|
85
|
+
};
|