@karakeep/cli 0.27.0 → 0.27.1
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/dist/index.mjs +381 -299
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -15926,6 +15926,9 @@ async function createTarGz(srcDir, outFile) {
|
|
|
15926
15926
|
});
|
|
15927
15927
|
}
|
|
15928
15928
|
const dumpCmd = new Command().name("dump").description("dump all account data and assets into an archive").option("--output <file>", "output archive path (.tar.gz)").option(
|
|
15929
|
+
"--exclude-assets",
|
|
15930
|
+
"exclude binary assets (skip assets index and files)"
|
|
15931
|
+
).option("--exclude-bookmarks", "exclude bookmarks (metadata/content)").option("--exclude-lists", "exclude lists and list membership").option("--exclude-tags", "exclude tags").option("--exclude-ai-prompts", "exclude AI prompts").option("--exclude-rules", "exclude rule engine rules").option("--exclude-feeds", "exclude RSS feeds").option("--exclude-webhooks", "exclude webhooks").option("--exclude-user-settings", "exclude user settings").option("--exclude-link-content", "exclude link content").option(
|
|
15929
15932
|
"--batch-size <n>",
|
|
15930
15933
|
`number of bookmarks per page (max ${MAX_NUM_BOOKMARKS_PER_PAGE})`,
|
|
15931
15934
|
(v) => Math.min(Number(v || 50), MAX_NUM_BOOKMARKS_PER_PAGE),
|
|
@@ -15966,126 +15969,154 @@ const dumpCmd = new Command().name("dump").description("dump all account data an
|
|
|
15966
15969
|
prompts: 0
|
|
15967
15970
|
}
|
|
15968
15971
|
};
|
|
15969
|
-
|
|
15970
|
-
|
|
15971
|
-
|
|
15972
|
-
|
|
15973
|
-
|
|
15974
|
-
|
|
15975
|
-
|
|
15976
|
-
|
|
15977
|
-
|
|
15978
|
-
|
|
15979
|
-
|
|
15980
|
-
|
|
15981
|
-
|
|
15982
|
-
|
|
15983
|
-
|
|
15984
|
-
|
|
15985
|
-
|
|
15986
|
-
|
|
15987
|
-
|
|
15988
|
-
|
|
15989
|
-
|
|
15990
|
-
|
|
15991
|
-
|
|
15992
|
-
|
|
15993
|
-
|
|
15994
|
-
|
|
15995
|
-
|
|
15996
|
-
|
|
15997
|
-
|
|
15998
|
-
|
|
15999
|
-
|
|
16000
|
-
|
|
16001
|
-
|
|
16002
|
-
|
|
16003
|
-
|
|
16004
|
-
|
|
16005
|
-
|
|
16006
|
-
|
|
16007
|
-
|
|
16008
|
-
|
|
16009
|
-
|
|
16010
|
-
|
|
15972
|
+
if (!opts.excludeUserSettings) {
|
|
15973
|
+
stepStart$2("Exporting user settings");
|
|
15974
|
+
const settings = await api2.users.settings.query();
|
|
15975
|
+
await writeJson(
|
|
15976
|
+
path.join(workRoot, "users", "settings.json"),
|
|
15977
|
+
settings
|
|
15978
|
+
);
|
|
15979
|
+
stepEndSuccess$2();
|
|
15980
|
+
}
|
|
15981
|
+
let lists;
|
|
15982
|
+
if (!opts.excludeLists) {
|
|
15983
|
+
stepStart$2("Exporting lists");
|
|
15984
|
+
const resp = await api2.lists.list.query();
|
|
15985
|
+
lists = resp.lists;
|
|
15986
|
+
await writeJson(path.join(workRoot, "lists", "index.json"), lists);
|
|
15987
|
+
manifest.counts.lists = lists.length;
|
|
15988
|
+
stepEndSuccess$2();
|
|
15989
|
+
}
|
|
15990
|
+
if (!opts.excludeTags) {
|
|
15991
|
+
stepStart$2("Exporting tags");
|
|
15992
|
+
const { tags } = await api2.tags.list.query();
|
|
15993
|
+
await writeJson(path.join(workRoot, "tags", "index.json"), tags);
|
|
15994
|
+
manifest.counts.tags = tags.length;
|
|
15995
|
+
stepEndSuccess$2();
|
|
15996
|
+
}
|
|
15997
|
+
if (!opts.excludeRules) {
|
|
15998
|
+
stepStart$2("Exporting rules");
|
|
15999
|
+
const { rules } = await api2.rules.list.query();
|
|
16000
|
+
await writeJson(path.join(workRoot, "rules", "index.json"), rules);
|
|
16001
|
+
manifest.counts.rules = rules.length;
|
|
16002
|
+
stepEndSuccess$2();
|
|
16003
|
+
}
|
|
16004
|
+
if (!opts.excludeFeeds) {
|
|
16005
|
+
stepStart$2("Exporting feeds");
|
|
16006
|
+
const { feeds } = await api2.feeds.list.query();
|
|
16007
|
+
await writeJson(path.join(workRoot, "feeds", "index.json"), feeds);
|
|
16008
|
+
manifest.counts.feeds = feeds.length;
|
|
16009
|
+
stepEndSuccess$2();
|
|
16010
|
+
}
|
|
16011
|
+
if (!opts.excludeAiPrompts) {
|
|
16012
|
+
stepStart$2("Exporting AI prompts");
|
|
16013
|
+
const prompts = await api2.prompts.list.query();
|
|
16014
|
+
await writeJson(path.join(workRoot, "prompts", "index.json"), prompts);
|
|
16015
|
+
manifest.counts.prompts = prompts.length;
|
|
16016
|
+
stepEndSuccess$2();
|
|
16017
|
+
}
|
|
16018
|
+
if (!opts.excludeWebhooks) {
|
|
16019
|
+
stepStart$2("Exporting webhooks");
|
|
16020
|
+
const webhooks = await api2.webhooks.list.query();
|
|
16021
|
+
await writeJson(
|
|
16022
|
+
path.join(workRoot, "webhooks", "index.json"),
|
|
16023
|
+
webhooks.webhooks
|
|
16024
|
+
);
|
|
16025
|
+
manifest.counts.webhooks = webhooks.webhooks.length;
|
|
16026
|
+
stepEndSuccess$2();
|
|
16027
|
+
}
|
|
16028
|
+
if (!opts.excludeBookmarks) {
|
|
16029
|
+
stepStart$2("Exporting bookmarks (metadata/content)");
|
|
16030
|
+
const bookmarkJsonl = path.join(workRoot, "bookmarks", "index.jsonl");
|
|
16031
|
+
let bookmarksExported = 0;
|
|
16032
|
+
const bookmarkIterator = async function* () {
|
|
16033
|
+
let cursor = null;
|
|
16034
|
+
do {
|
|
16035
|
+
const resp = await api2.bookmarks.getBookmarks.query({
|
|
16036
|
+
includeContent: !opts.excludeLinkContent,
|
|
16037
|
+
limit: Number(opts.batchSize) || 50,
|
|
16038
|
+
cursor,
|
|
16039
|
+
useCursorV2: true
|
|
16040
|
+
});
|
|
16041
|
+
for (const b of resp.bookmarks) {
|
|
16042
|
+
yield b;
|
|
16043
|
+
bookmarksExported++;
|
|
16044
|
+
progressUpdate$2("Bookmarks", bookmarksExported);
|
|
16045
|
+
}
|
|
16046
|
+
cursor = resp.nextCursor;
|
|
16047
|
+
} while (cursor);
|
|
16048
|
+
};
|
|
16049
|
+
await writeJsonl(bookmarkJsonl, bookmarkIterator());
|
|
16050
|
+
progressDone$2();
|
|
16051
|
+
manifest.counts.bookmarks = bookmarksExported;
|
|
16052
|
+
stepEndSuccess$2();
|
|
16053
|
+
}
|
|
16054
|
+
if (!opts.excludeLists && !opts.excludeBookmarks && lists) {
|
|
16055
|
+
stepStart$2("Exporting list membership");
|
|
16056
|
+
const membership = await buildListMembership(
|
|
16057
|
+
api2,
|
|
16058
|
+
lists,
|
|
16059
|
+
(p, t) => progressUpdate$2("Lists scanned", p, t)
|
|
16060
|
+
);
|
|
16061
|
+
progressDone$2();
|
|
16062
|
+
await writeJson(
|
|
16063
|
+
path.join(workRoot, "lists", "membership.json"),
|
|
16064
|
+
Object.fromEntries(membership.entries())
|
|
16065
|
+
);
|
|
16066
|
+
stepEndSuccess$2();
|
|
16067
|
+
}
|
|
16068
|
+
if (!opts.excludeAssets) {
|
|
16069
|
+
stepStart$2("Exporting assets (binary files)");
|
|
16070
|
+
const assetsDir = path.join(workRoot, "assets", "files");
|
|
16071
|
+
await ensureDir(assetsDir);
|
|
16072
|
+
const assetsIndex = [];
|
|
16073
|
+
let assetPageCursor = null;
|
|
16074
|
+
let downloaded = 0;
|
|
16075
|
+
let totalAssets = void 0;
|
|
16011
16076
|
do {
|
|
16012
|
-
const resp = await api2.
|
|
16013
|
-
|
|
16014
|
-
|
|
16015
|
-
cursor,
|
|
16016
|
-
useCursorV2: true
|
|
16077
|
+
const resp = await api2.assets.list.query({
|
|
16078
|
+
limit: 50,
|
|
16079
|
+
cursor: assetPageCursor ?? void 0
|
|
16017
16080
|
});
|
|
16018
|
-
|
|
16019
|
-
|
|
16020
|
-
|
|
16021
|
-
|
|
16022
|
-
|
|
16023
|
-
|
|
16024
|
-
|
|
16025
|
-
|
|
16026
|
-
|
|
16027
|
-
|
|
16028
|
-
|
|
16029
|
-
|
|
16030
|
-
|
|
16031
|
-
|
|
16032
|
-
|
|
16033
|
-
|
|
16034
|
-
|
|
16035
|
-
|
|
16036
|
-
|
|
16037
|
-
|
|
16038
|
-
|
|
16039
|
-
|
|
16040
|
-
|
|
16041
|
-
|
|
16042
|
-
|
|
16043
|
-
|
|
16044
|
-
|
|
16045
|
-
|
|
16046
|
-
let assetPageCursor = null;
|
|
16047
|
-
let downloaded = 0;
|
|
16048
|
-
let totalAssets = void 0;
|
|
16049
|
-
do {
|
|
16050
|
-
const resp = await api2.assets.list.query({
|
|
16051
|
-
limit: 50,
|
|
16052
|
-
cursor: assetPageCursor ?? void 0
|
|
16053
|
-
});
|
|
16054
|
-
if (totalAssets == null) totalAssets = resp.totalCount;
|
|
16055
|
-
for (const a of resp.assets) {
|
|
16056
|
-
const relPath = path.join("assets", "files", a.id);
|
|
16057
|
-
const absPath = path.join(workRoot, relPath);
|
|
16058
|
-
try {
|
|
16059
|
-
await downloadAsset(
|
|
16060
|
-
globals.serverAddr,
|
|
16061
|
-
globals.apiKey,
|
|
16062
|
-
a.id,
|
|
16063
|
-
absPath
|
|
16064
|
-
);
|
|
16065
|
-
assetsIndex.push({
|
|
16066
|
-
id: a.id,
|
|
16067
|
-
assetType: a.assetType,
|
|
16068
|
-
size: a.size,
|
|
16069
|
-
contentType: a.contentType,
|
|
16070
|
-
fileName: a.fileName,
|
|
16071
|
-
bookmarkId: a.bookmarkId,
|
|
16072
|
-
filePath: relPath.replace(/\\/g, "/")
|
|
16073
|
-
});
|
|
16074
|
-
downloaded++;
|
|
16075
|
-
progressUpdate$2("Assets", downloaded, totalAssets);
|
|
16076
|
-
} catch (e) {
|
|
16077
|
-
printErrorMessageWithReason(
|
|
16078
|
-
`Failed to download asset "${a.id}"`,
|
|
16079
|
-
e
|
|
16080
|
-
);
|
|
16081
|
+
if (totalAssets == null) totalAssets = resp.totalCount;
|
|
16082
|
+
for (const a of resp.assets) {
|
|
16083
|
+
const relPath = path.join("assets", "files", a.id);
|
|
16084
|
+
const absPath = path.join(workRoot, relPath);
|
|
16085
|
+
try {
|
|
16086
|
+
await downloadAsset(
|
|
16087
|
+
globals.serverAddr,
|
|
16088
|
+
globals.apiKey,
|
|
16089
|
+
a.id,
|
|
16090
|
+
absPath
|
|
16091
|
+
);
|
|
16092
|
+
assetsIndex.push({
|
|
16093
|
+
id: a.id,
|
|
16094
|
+
assetType: a.assetType,
|
|
16095
|
+
size: a.size,
|
|
16096
|
+
contentType: a.contentType,
|
|
16097
|
+
fileName: a.fileName,
|
|
16098
|
+
bookmarkId: a.bookmarkId,
|
|
16099
|
+
filePath: relPath.replace(/\\/g, "/")
|
|
16100
|
+
});
|
|
16101
|
+
downloaded++;
|
|
16102
|
+
progressUpdate$2("Assets", downloaded, totalAssets);
|
|
16103
|
+
} catch (e) {
|
|
16104
|
+
printErrorMessageWithReason(
|
|
16105
|
+
`Failed to download asset "${a.id}"`,
|
|
16106
|
+
e
|
|
16107
|
+
);
|
|
16108
|
+
}
|
|
16081
16109
|
}
|
|
16082
|
-
|
|
16083
|
-
|
|
16084
|
-
|
|
16085
|
-
|
|
16086
|
-
|
|
16087
|
-
|
|
16088
|
-
|
|
16110
|
+
assetPageCursor = resp.nextCursor;
|
|
16111
|
+
} while (assetPageCursor);
|
|
16112
|
+
progressDone$2();
|
|
16113
|
+
manifest.counts.assets = downloaded;
|
|
16114
|
+
await writeJson(
|
|
16115
|
+
path.join(workRoot, "assets", "index.json"),
|
|
16116
|
+
assetsIndex
|
|
16117
|
+
);
|
|
16118
|
+
stepEndSuccess$2();
|
|
16119
|
+
}
|
|
16089
16120
|
stepStart$2("Writing manifest");
|
|
16090
16121
|
await writeJson(path.join(workRoot, "manifest.json"), manifest);
|
|
16091
16122
|
stepEndSuccess$2();
|
|
@@ -16181,7 +16212,7 @@ function progressDone$1() {
|
|
|
16181
16212
|
const migrateCmd = new Command().name("migrate").description("migrate data from a source server to a destination server").requiredOption(
|
|
16182
16213
|
"--dest-server <url>",
|
|
16183
16214
|
"destination server base URL, e.g. https://dest.example.com"
|
|
16184
|
-
).requiredOption("--dest-api-key <key>", "API key for the destination server").option("-y, --yes", "skip confirmation prompt").option(
|
|
16215
|
+
).requiredOption("--dest-api-key <key>", "API key for the destination server").option("-y, --yes", "skip confirmation prompt").option("--exclude-assets", "exclude assets (skip asset bookmarks)").option("--exclude-lists", "exclude lists and list membership").option("--exclude-ai-prompts", "exclude AI prompts").option("--exclude-rules", "exclude rule engine rules").option("--exclude-feeds", "exclude RSS feeds").option("--exclude-webhooks", "exclude webhooks").option("--exclude-bookmarks", "exclude bookmarks migration").option("--exclude-tags", "exclude tags migration").option("--exclude-user-settings", "exclude user settings migration").option(
|
|
16185
16216
|
"--batch-size <n>",
|
|
16186
16217
|
`number of bookmarks per page (max ${MAX_NUM_BOOKMARKS_PER_PAGE})`,
|
|
16187
16218
|
(v) => Math.min(Number(v || 50), MAX_NUM_BOOKMARKS_PER_PAGE),
|
|
@@ -16216,113 +16247,143 @@ const migrateCmd = new Command().name("migrate").description("migrate data from
|
|
|
16216
16247
|
totalBookmarks = stats.numBookmarks;
|
|
16217
16248
|
} catch {
|
|
16218
16249
|
}
|
|
16219
|
-
|
|
16220
|
-
|
|
16221
|
-
|
|
16222
|
-
|
|
16223
|
-
|
|
16224
|
-
|
|
16225
|
-
|
|
16226
|
-
|
|
16227
|
-
|
|
16228
|
-
|
|
16229
|
-
|
|
16230
|
-
|
|
16231
|
-
|
|
16232
|
-
|
|
16233
|
-
|
|
16234
|
-
|
|
16235
|
-
|
|
16236
|
-
|
|
16237
|
-
|
|
16238
|
-
|
|
16239
|
-
|
|
16240
|
-
|
|
16250
|
+
if (!opts.excludeUserSettings) {
|
|
16251
|
+
stepStart$1("Migrating user settings");
|
|
16252
|
+
await migrateUserSettings(src2, dest);
|
|
16253
|
+
stepEndSuccess$1();
|
|
16254
|
+
}
|
|
16255
|
+
let lists = [];
|
|
16256
|
+
let listIdMap = /* @__PURE__ */ new Map();
|
|
16257
|
+
if (!opts.excludeLists) {
|
|
16258
|
+
stepStart$1("Migrating lists");
|
|
16259
|
+
const listsStart = Date.now();
|
|
16260
|
+
const listsRes = await migrateLists(
|
|
16261
|
+
src2,
|
|
16262
|
+
dest,
|
|
16263
|
+
(created, alreadyExists, total) => {
|
|
16264
|
+
progressUpdate$1("Lists (created)", created + alreadyExists, total);
|
|
16265
|
+
}
|
|
16266
|
+
);
|
|
16267
|
+
lists = listsRes.lists;
|
|
16268
|
+
listIdMap = listsRes.listIdMap;
|
|
16269
|
+
progressDone$1();
|
|
16270
|
+
stepEndSuccess$1(
|
|
16271
|
+
`${listsRes.createdCount} created in ${Math.round((Date.now() - listsStart) / 1e3)}s`
|
|
16272
|
+
);
|
|
16273
|
+
}
|
|
16274
|
+
let feedIdMap = /* @__PURE__ */ new Map();
|
|
16275
|
+
if (!opts.excludeFeeds) {
|
|
16276
|
+
stepStart$1("Migrating feeds");
|
|
16277
|
+
const feedsStart = Date.now();
|
|
16278
|
+
const res = await migrateFeeds(src2, dest, (created, total) => {
|
|
16241
16279
|
progressUpdate$1("Feeds", created, total);
|
|
16242
|
-
}
|
|
16243
|
-
|
|
16244
|
-
|
|
16245
|
-
|
|
16246
|
-
|
|
16247
|
-
|
|
16248
|
-
|
|
16249
|
-
|
|
16250
|
-
|
|
16251
|
-
|
|
16252
|
-
|
|
16253
|
-
|
|
16254
|
-
|
|
16255
|
-
|
|
16256
|
-
|
|
16257
|
-
|
|
16258
|
-
|
|
16259
|
-
|
|
16260
|
-
|
|
16261
|
-
|
|
16262
|
-
|
|
16263
|
-
|
|
16264
|
-
|
|
16265
|
-
|
|
16266
|
-
|
|
16267
|
-
|
|
16268
|
-
|
|
16269
|
-
|
|
16270
|
-
|
|
16271
|
-
|
|
16272
|
-
|
|
16273
|
-
|
|
16274
|
-
|
|
16275
|
-
(
|
|
16280
|
+
});
|
|
16281
|
+
feedIdMap = res.idMap;
|
|
16282
|
+
progressDone$1();
|
|
16283
|
+
stepEndSuccess$1(
|
|
16284
|
+
`${res.count} migrated in ${Math.round((Date.now() - feedsStart) / 1e3)}s`
|
|
16285
|
+
);
|
|
16286
|
+
}
|
|
16287
|
+
if (!opts.excludeAiPrompts) {
|
|
16288
|
+
stepStart$1("Migrating AI prompts");
|
|
16289
|
+
const promptsStart = Date.now();
|
|
16290
|
+
const promptsCount = await migratePrompts(
|
|
16291
|
+
src2,
|
|
16292
|
+
dest,
|
|
16293
|
+
(created, total) => {
|
|
16294
|
+
progressUpdate$1("Prompts", created, total);
|
|
16295
|
+
}
|
|
16296
|
+
);
|
|
16297
|
+
progressDone$1();
|
|
16298
|
+
stepEndSuccess$1(
|
|
16299
|
+
`${promptsCount} migrated in ${Math.round((Date.now() - promptsStart) / 1e3)}s`
|
|
16300
|
+
);
|
|
16301
|
+
}
|
|
16302
|
+
if (!opts.excludeWebhooks) {
|
|
16303
|
+
stepStart$1("Migrating webhooks");
|
|
16304
|
+
const webhooksStart = Date.now();
|
|
16305
|
+
const webhooksCount = await migrateWebhooks(
|
|
16306
|
+
src2,
|
|
16307
|
+
dest,
|
|
16308
|
+
(created, total) => {
|
|
16309
|
+
progressUpdate$1("Webhooks", created, total);
|
|
16310
|
+
}
|
|
16311
|
+
);
|
|
16312
|
+
progressDone$1();
|
|
16313
|
+
stepEndSuccess$1(
|
|
16314
|
+
`${webhooksCount} migrated in ${Math.round((Date.now() - webhooksStart) / 1e3)}s`
|
|
16315
|
+
);
|
|
16316
|
+
}
|
|
16317
|
+
let tagIdMap = /* @__PURE__ */ new Map();
|
|
16318
|
+
if (!opts.excludeTags) {
|
|
16319
|
+
stepStart$1("Ensuring tags on destination");
|
|
16320
|
+
const tagsStart = Date.now();
|
|
16321
|
+
const res = await migrateTags(src2, dest, (ensured, total) => {
|
|
16276
16322
|
progressUpdate$1("Tags", ensured, total);
|
|
16277
|
-
}
|
|
16278
|
-
|
|
16279
|
-
|
|
16280
|
-
|
|
16281
|
-
|
|
16282
|
-
|
|
16283
|
-
|
|
16284
|
-
|
|
16285
|
-
|
|
16286
|
-
|
|
16287
|
-
|
|
16288
|
-
|
|
16289
|
-
|
|
16290
|
-
|
|
16291
|
-
|
|
16292
|
-
|
|
16293
|
-
|
|
16294
|
-
|
|
16295
|
-
|
|
16296
|
-
|
|
16297
|
-
|
|
16298
|
-
|
|
16299
|
-
|
|
16300
|
-
|
|
16301
|
-
|
|
16302
|
-
|
|
16303
|
-
|
|
16304
|
-
|
|
16305
|
-
|
|
16306
|
-
|
|
16307
|
-
|
|
16308
|
-
|
|
16309
|
-
|
|
16310
|
-
|
|
16311
|
-
bookmarkListsMap
|
|
16312
|
-
|
|
16313
|
-
|
|
16314
|
-
|
|
16315
|
-
|
|
16316
|
-
|
|
16317
|
-
|
|
16318
|
-
|
|
16319
|
-
|
|
16320
|
-
|
|
16321
|
-
|
|
16322
|
-
|
|
16323
|
-
|
|
16324
|
-
|
|
16325
|
-
|
|
16323
|
+
});
|
|
16324
|
+
tagIdMap = res.idMap;
|
|
16325
|
+
progressDone$1();
|
|
16326
|
+
stepEndSuccess$1(
|
|
16327
|
+
`${res.count} ensured in ${Math.round((Date.now() - tagsStart) / 1e3)}s`
|
|
16328
|
+
);
|
|
16329
|
+
}
|
|
16330
|
+
if (!opts.excludeRules && !opts.excludeLists && !opts.excludeFeeds && !opts.excludeTags) {
|
|
16331
|
+
stepStart$1("Migrating rule engine rules");
|
|
16332
|
+
const rulesStart = Date.now();
|
|
16333
|
+
const rulesCount = await migrateRules(
|
|
16334
|
+
src2,
|
|
16335
|
+
dest,
|
|
16336
|
+
{ tagIdMap, listIdMap, feedIdMap },
|
|
16337
|
+
(created, total) => {
|
|
16338
|
+
progressUpdate$1("Rules", created, total);
|
|
16339
|
+
}
|
|
16340
|
+
);
|
|
16341
|
+
progressDone$1();
|
|
16342
|
+
stepEndSuccess$1(
|
|
16343
|
+
`${rulesCount} migrated in ${Math.round((Date.now() - rulesStart) / 1e3)}s`
|
|
16344
|
+
);
|
|
16345
|
+
}
|
|
16346
|
+
let bookmarkListsMap = /* @__PURE__ */ new Map();
|
|
16347
|
+
if (!opts.excludeLists && !opts.excludeBookmarks) {
|
|
16348
|
+
stepStart$1("Building list membership for bookmarks");
|
|
16349
|
+
const blmStart = Date.now();
|
|
16350
|
+
const res = await buildBookmarkListMembership(
|
|
16351
|
+
src2,
|
|
16352
|
+
lists,
|
|
16353
|
+
(processed, total) => {
|
|
16354
|
+
progressUpdate$1("Scanning lists", processed, total);
|
|
16355
|
+
}
|
|
16356
|
+
);
|
|
16357
|
+
bookmarkListsMap = res.bookmarkListsMap;
|
|
16358
|
+
progressDone$1();
|
|
16359
|
+
stepEndSuccess$1(
|
|
16360
|
+
`${res.scannedLists} lists scanned in ${Math.round((Date.now() - blmStart) / 1e3)}s`
|
|
16361
|
+
);
|
|
16362
|
+
}
|
|
16363
|
+
if (!opts.excludeBookmarks) {
|
|
16364
|
+
stepStart$1("Migrating bookmarks");
|
|
16365
|
+
const bmStart = Date.now();
|
|
16366
|
+
const res = await migrateBookmarks(src2, dest, {
|
|
16367
|
+
pageSize: Number(opts.batchSize) || 50,
|
|
16368
|
+
listIdMap,
|
|
16369
|
+
bookmarkListsMap,
|
|
16370
|
+
total: totalBookmarks,
|
|
16371
|
+
onProgress: (migrated, skipped, total) => {
|
|
16372
|
+
const suffix = skipped > 0 ? `(skipped ${skipped} assets)` : void 0;
|
|
16373
|
+
progressUpdate$1("Bookmarks", migrated, total, suffix);
|
|
16374
|
+
},
|
|
16375
|
+
srcServer: globals.serverAddr,
|
|
16376
|
+
srcApiKey: globals.apiKey,
|
|
16377
|
+
destServer: opts.destServer,
|
|
16378
|
+
destApiKey: opts.destApiKey,
|
|
16379
|
+
excludeAssets: !!opts.excludeAssets,
|
|
16380
|
+
excludeLists: !!opts.excludeLists
|
|
16381
|
+
});
|
|
16382
|
+
progressDone$1();
|
|
16383
|
+
stepEndSuccess$1(
|
|
16384
|
+
`${res.migrated} migrated${res.skippedAssets ? `, ${res.skippedAssets} skipped` : ""} in ${Math.round((Date.now() - bmStart) / 1e3)}s`
|
|
16385
|
+
);
|
|
16386
|
+
}
|
|
16326
16387
|
printStatusMessage(true, "Migration completed successfully");
|
|
16327
16388
|
} catch (error2) {
|
|
16328
16389
|
stepEndFail$1();
|
|
@@ -16651,6 +16712,10 @@ async function migrateBookmarks(src2, dest, opts) {
|
|
|
16651
16712
|
break;
|
|
16652
16713
|
}
|
|
16653
16714
|
case BookmarkTypes.ASSET: {
|
|
16715
|
+
if (opts.excludeAssets) {
|
|
16716
|
+
skippedAssets++;
|
|
16717
|
+
continue;
|
|
16718
|
+
}
|
|
16654
16719
|
try {
|
|
16655
16720
|
const downloadResp = await fetch(
|
|
16656
16721
|
`${opts.srcServer}/api/assets/${b.content.assetId}`,
|
|
@@ -16706,14 +16771,16 @@ async function migrateBookmarks(src2, dest, opts) {
|
|
|
16706
16771
|
detach: []
|
|
16707
16772
|
});
|
|
16708
16773
|
}
|
|
16709
|
-
|
|
16710
|
-
|
|
16711
|
-
const
|
|
16712
|
-
|
|
16713
|
-
|
|
16714
|
-
|
|
16715
|
-
|
|
16716
|
-
|
|
16774
|
+
if (!opts.excludeLists) {
|
|
16775
|
+
const srcListIds = opts.bookmarkListsMap.get(b.id) ?? [];
|
|
16776
|
+
for (const srcListId of srcListIds) {
|
|
16777
|
+
const destListId = opts.listIdMap.get(srcListId);
|
|
16778
|
+
if (destListId) {
|
|
16779
|
+
await dest.lists.addToList.mutate({
|
|
16780
|
+
listId: destListId,
|
|
16781
|
+
bookmarkId: createdId
|
|
16782
|
+
});
|
|
16783
|
+
}
|
|
16717
16784
|
}
|
|
16718
16785
|
}
|
|
16719
16786
|
migrated++;
|
|
@@ -16802,7 +16869,7 @@ function progressUpdate(prefix, current, total, suffix) {
|
|
|
16802
16869
|
function progressDone() {
|
|
16803
16870
|
process.stdout.write("\n");
|
|
16804
16871
|
}
|
|
16805
|
-
const wipeCmd = new Command().name("wipe").description("wipe all data for the current user from the server").option("-y, --yes", "skip confirmation prompt").option(
|
|
16872
|
+
const wipeCmd = new Command().name("wipe").description("wipe all data for the current user from the server").option("-y, --yes", "skip confirmation prompt").option("--exclude-lists", "exclude lists from deletion").option("--exclude-ai-prompts", "exclude AI prompts from deletion").option("--exclude-rules", "exclude rules from deletion").option("--exclude-feeds", "exclude RSS feeds from deletion").option("--exclude-webhooks", "exclude webhooks from deletion").option("--exclude-bookmarks", "exclude bookmarks from deletion").option("--exclude-tags", "exclude tags cleanup from deletion").option("--exclude-user-settings", "exclude user settings (no-op)").option(
|
|
16806
16873
|
"--batch-size <n>",
|
|
16807
16874
|
`number of bookmarks per page (max ${MAX_NUM_BOOKMARKS_PER_PAGE})`,
|
|
16808
16875
|
(v) => Math.min(Number(v || 50), MAX_NUM_BOOKMARKS_PER_PAGE),
|
|
@@ -16832,70 +16899,84 @@ const wipeCmd = new Command().name("wipe").description("wipe all data for the cu
|
|
|
16832
16899
|
totalBookmarks = stats.numBookmarks;
|
|
16833
16900
|
} catch {
|
|
16834
16901
|
}
|
|
16835
|
-
|
|
16836
|
-
|
|
16837
|
-
|
|
16838
|
-
|
|
16839
|
-
|
|
16840
|
-
|
|
16841
|
-
|
|
16842
|
-
|
|
16843
|
-
|
|
16844
|
-
|
|
16845
|
-
|
|
16846
|
-
|
|
16847
|
-
|
|
16848
|
-
|
|
16849
|
-
|
|
16850
|
-
|
|
16851
|
-
|
|
16852
|
-
|
|
16853
|
-
|
|
16854
|
-
|
|
16855
|
-
|
|
16856
|
-
|
|
16857
|
-
|
|
16858
|
-
|
|
16859
|
-
|
|
16860
|
-
|
|
16861
|
-
|
|
16862
|
-
|
|
16863
|
-
|
|
16864
|
-
|
|
16865
|
-
|
|
16866
|
-
|
|
16867
|
-
|
|
16868
|
-
|
|
16869
|
-
|
|
16870
|
-
|
|
16871
|
-
|
|
16872
|
-
|
|
16873
|
-
|
|
16874
|
-
|
|
16875
|
-
|
|
16876
|
-
|
|
16877
|
-
|
|
16878
|
-
|
|
16879
|
-
|
|
16880
|
-
|
|
16881
|
-
|
|
16882
|
-
|
|
16883
|
-
|
|
16884
|
-
|
|
16885
|
-
|
|
16886
|
-
|
|
16887
|
-
|
|
16888
|
-
|
|
16889
|
-
|
|
16890
|
-
|
|
16891
|
-
|
|
16892
|
-
|
|
16893
|
-
|
|
16894
|
-
|
|
16895
|
-
|
|
16896
|
-
|
|
16897
|
-
|
|
16898
|
-
|
|
16902
|
+
if (!opts.excludeRules) {
|
|
16903
|
+
stepStart("Deleting rule engine rules");
|
|
16904
|
+
const rulesStart = Date.now();
|
|
16905
|
+
const rulesDeleted = await wipeRules(api2, (deleted, total) => {
|
|
16906
|
+
progressUpdate("Rules", deleted, total);
|
|
16907
|
+
});
|
|
16908
|
+
progressDone();
|
|
16909
|
+
stepEndSuccess(
|
|
16910
|
+
`${rulesDeleted} deleted in ${Math.round((Date.now() - rulesStart) / 1e3)}s`
|
|
16911
|
+
);
|
|
16912
|
+
}
|
|
16913
|
+
if (!opts.excludeFeeds) {
|
|
16914
|
+
stepStart("Deleting feeds");
|
|
16915
|
+
const feedsStart = Date.now();
|
|
16916
|
+
const feedsDeleted = await wipeFeeds(api2, (deleted, total) => {
|
|
16917
|
+
progressUpdate("Feeds", deleted, total);
|
|
16918
|
+
});
|
|
16919
|
+
progressDone();
|
|
16920
|
+
stepEndSuccess(
|
|
16921
|
+
`${feedsDeleted} deleted in ${Math.round((Date.now() - feedsStart) / 1e3)}s`
|
|
16922
|
+
);
|
|
16923
|
+
}
|
|
16924
|
+
if (!opts.excludeWebhooks) {
|
|
16925
|
+
stepStart("Deleting webhooks");
|
|
16926
|
+
const webhooksStart = Date.now();
|
|
16927
|
+
const webhooksDeleted = await wipeWebhooks(api2, (deleted, total) => {
|
|
16928
|
+
progressUpdate("Webhooks", deleted, total);
|
|
16929
|
+
});
|
|
16930
|
+
progressDone();
|
|
16931
|
+
stepEndSuccess(
|
|
16932
|
+
`${webhooksDeleted} deleted in ${Math.round((Date.now() - webhooksStart) / 1e3)}s`
|
|
16933
|
+
);
|
|
16934
|
+
}
|
|
16935
|
+
if (!opts.excludeAiPrompts) {
|
|
16936
|
+
stepStart("Deleting AI prompts");
|
|
16937
|
+
const promptsStart = Date.now();
|
|
16938
|
+
const promptsDeleted = await wipePrompts(api2, (deleted, total) => {
|
|
16939
|
+
progressUpdate("Prompts", deleted, total);
|
|
16940
|
+
});
|
|
16941
|
+
progressDone();
|
|
16942
|
+
stepEndSuccess(
|
|
16943
|
+
`${promptsDeleted} deleted in ${Math.round((Date.now() - promptsStart) / 1e3)}s`
|
|
16944
|
+
);
|
|
16945
|
+
}
|
|
16946
|
+
if (!opts.excludeBookmarks) {
|
|
16947
|
+
stepStart("Deleting bookmarks");
|
|
16948
|
+
const bmStart = Date.now();
|
|
16949
|
+
const bookmarksDeleted = await wipeBookmarks(api2, {
|
|
16950
|
+
pageSize: Number(opts.batchSize) || 50,
|
|
16951
|
+
total: totalBookmarks,
|
|
16952
|
+
onProgress: (deleted, total) => {
|
|
16953
|
+
progressUpdate("Bookmarks", deleted, total);
|
|
16954
|
+
}
|
|
16955
|
+
});
|
|
16956
|
+
progressDone();
|
|
16957
|
+
stepEndSuccess(
|
|
16958
|
+
`${bookmarksDeleted} deleted in ${Math.round((Date.now() - bmStart) / 1e3)}s`
|
|
16959
|
+
);
|
|
16960
|
+
}
|
|
16961
|
+
if (!opts.excludeLists) {
|
|
16962
|
+
stepStart("Deleting lists");
|
|
16963
|
+
const listsStart = Date.now();
|
|
16964
|
+
const listsDeleted = await wipeLists(api2, (deleted, total) => {
|
|
16965
|
+
progressUpdate("Lists", deleted, total);
|
|
16966
|
+
});
|
|
16967
|
+
progressDone();
|
|
16968
|
+
stepEndSuccess(
|
|
16969
|
+
`${listsDeleted} deleted in ${Math.round((Date.now() - listsStart) / 1e3)}s`
|
|
16970
|
+
);
|
|
16971
|
+
}
|
|
16972
|
+
if (!opts.excludeTags) {
|
|
16973
|
+
stepStart("Deleting unused tags");
|
|
16974
|
+
const tagsStart = Date.now();
|
|
16975
|
+
const deletedTags = await wipeTags(api2);
|
|
16976
|
+
stepEndSuccess(
|
|
16977
|
+
`${deletedTags} deleted in ${Math.round((Date.now() - tagsStart) / 1e3)}s`
|
|
16978
|
+
);
|
|
16979
|
+
}
|
|
16899
16980
|
printStatusMessage(true, "Wipe completed successfully");
|
|
16900
16981
|
} catch (error2) {
|
|
16901
16982
|
stepEndFail();
|
|
@@ -16998,7 +17079,8 @@ async function wipeBookmarks(api2, opts) {
|
|
|
16998
17079
|
const resp = await api2.bookmarks.getBookmarks.query({
|
|
16999
17080
|
limit: opts.pageSize,
|
|
17000
17081
|
cursor,
|
|
17001
|
-
useCursorV2: true
|
|
17082
|
+
useCursorV2: true,
|
|
17083
|
+
includeContent: false
|
|
17002
17084
|
});
|
|
17003
17085
|
for (const b of resp.bookmarks) {
|
|
17004
17086
|
try {
|
|
@@ -17071,7 +17153,7 @@ async function wipeTags(api2) {
|
|
|
17071
17153
|
throw error2;
|
|
17072
17154
|
}
|
|
17073
17155
|
}
|
|
17074
|
-
const __vite_import_meta_env__ = { "BASE_URL": "/", "CLI_VERSION": "0.27.
|
|
17156
|
+
const __vite_import_meta_env__ = { "BASE_URL": "/", "CLI_VERSION": "0.27.1", "DEV": false, "MODE": "production", "PROD": true, "SSR": true };
|
|
17075
17157
|
const program = new Command().name("karakeep").description("A CLI interface to interact with the karakeep api").addOption(
|
|
17076
17158
|
new Option("--api-key <key>", "the API key to interact with the API").makeOptionMandatory(true).env("KARAKEEP_API_KEY")
|
|
17077
17159
|
).addOption(
|
|
@@ -17080,7 +17162,7 @@ const program = new Command().name("karakeep").description("A CLI interface to i
|
|
|
17080
17162
|
"the address of the server to connect to"
|
|
17081
17163
|
).makeOptionMandatory(true).env("KARAKEEP_SERVER_ADDR")
|
|
17082
17164
|
).addOption(new Option("--json", "to output the result as JSON")).version(
|
|
17083
|
-
__vite_import_meta_env__ && "CLI_VERSION" in __vite_import_meta_env__ ? "0.27.
|
|
17165
|
+
__vite_import_meta_env__ && "CLI_VERSION" in __vite_import_meta_env__ ? "0.27.1" : "0.0.0"
|
|
17084
17166
|
);
|
|
17085
17167
|
program.addCommand(bookmarkCmd);
|
|
17086
17168
|
program.addCommand(listsCmd);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://json.schemastore.org/package.json",
|
|
3
3
|
"name": "@karakeep/cli",
|
|
4
|
-
"version": "0.27.
|
|
4
|
+
"version": "0.27.1",
|
|
5
5
|
"description": "Command Line Interface (CLI) for Karakeep",
|
|
6
6
|
"license": "GNU Affero General Public License version 3",
|
|
7
7
|
"type": "module",
|