@tasklumina/cli 1.0.1 → 1.1.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/dist/index.js +133 -68
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -507,8 +507,8 @@ var listLists = (
|
|
|
507
507
|
var listListItems = (
|
|
508
508
|
/* GraphQL */
|
|
509
509
|
`
|
|
510
|
-
query ListListItems($listId: ID
|
|
511
|
-
listListItems(listId: $listId) {
|
|
510
|
+
query ListListItems($listId: ID!, $completed: Boolean) {
|
|
511
|
+
listListItems(listId: $listId, completed: $completed) {
|
|
512
512
|
id
|
|
513
513
|
listId
|
|
514
514
|
name
|
|
@@ -518,6 +518,8 @@ var listListItems = (
|
|
|
518
518
|
tags
|
|
519
519
|
link
|
|
520
520
|
customFields
|
|
521
|
+
completed
|
|
522
|
+
completedBy
|
|
521
523
|
position
|
|
522
524
|
createdAt
|
|
523
525
|
updatedAt
|
|
@@ -949,6 +951,8 @@ var createListItem = (
|
|
|
949
951
|
tags
|
|
950
952
|
link
|
|
951
953
|
customFields
|
|
954
|
+
completed
|
|
955
|
+
completedBy
|
|
952
956
|
position
|
|
953
957
|
createdAt
|
|
954
958
|
updatedAt
|
|
@@ -970,6 +974,8 @@ var updateListItem = (
|
|
|
970
974
|
tags
|
|
971
975
|
link
|
|
972
976
|
customFields
|
|
977
|
+
completed
|
|
978
|
+
completedBy
|
|
973
979
|
position
|
|
974
980
|
createdAt
|
|
975
981
|
updatedAt
|
|
@@ -1718,9 +1724,9 @@ categoriesCommand.command("create").description("Create a category").argument("<
|
|
|
1718
1724
|
try {
|
|
1719
1725
|
validateStringLength(name, "Name", 100);
|
|
1720
1726
|
if (opts.color) validateHexColor(opts.color);
|
|
1721
|
-
const
|
|
1722
|
-
if (opts.color)
|
|
1723
|
-
const data = await graphql(createCategory, { input
|
|
1727
|
+
const input = { id: randomUUID(), name, position: Date.now() };
|
|
1728
|
+
if (opts.color) input.color = opts.color;
|
|
1729
|
+
const data = await graphql(createCategory, { input });
|
|
1724
1730
|
if (isJsonMode()) {
|
|
1725
1731
|
printJson(data.createCategory);
|
|
1726
1732
|
return;
|
|
@@ -1736,10 +1742,10 @@ categoriesCommand.command("update").description("Update a category").argument("<
|
|
|
1736
1742
|
validateUuid(id, "Category ID");
|
|
1737
1743
|
if (opts.name) validateStringLength(opts.name, "Name", 100);
|
|
1738
1744
|
if (opts.color) validateHexColor(opts.color);
|
|
1739
|
-
const
|
|
1740
|
-
if (opts.name)
|
|
1741
|
-
if (opts.color)
|
|
1742
|
-
const data = await graphql(updateCategory, { input
|
|
1745
|
+
const input = { id };
|
|
1746
|
+
if (opts.name) input.name = opts.name;
|
|
1747
|
+
if (opts.color) input.color = opts.color;
|
|
1748
|
+
const data = await graphql(updateCategory, { input });
|
|
1743
1749
|
if (isJsonMode()) {
|
|
1744
1750
|
printJson(data.updateCategory);
|
|
1745
1751
|
return;
|
|
@@ -1811,9 +1817,9 @@ tagsCommand.command("update").description("Update a tag").argument("<id>", "Tag
|
|
|
1811
1817
|
try {
|
|
1812
1818
|
validateUuid(id, "Tag ID");
|
|
1813
1819
|
if (opts.name) validateStringLength(opts.name, "Tag name", 100);
|
|
1814
|
-
const
|
|
1815
|
-
if (opts.name)
|
|
1816
|
-
const data = await graphql(updateTag, { input
|
|
1820
|
+
const input = { id };
|
|
1821
|
+
if (opts.name) input.name = opts.name;
|
|
1822
|
+
const data = await graphql(updateTag, { input });
|
|
1817
1823
|
if (isJsonMode()) {
|
|
1818
1824
|
printJson(data.updateTag);
|
|
1819
1825
|
return;
|
|
@@ -1958,16 +1964,16 @@ contactsCommand.command("create").description("Create a contact").argument("<nam
|
|
|
1958
1964
|
contactsCommand.command("update").description("Update a contact").argument("<id>", "Contact ID").option("--name <name>", "New name").option("--email <email>", "New email").action(async (id, opts) => {
|
|
1959
1965
|
try {
|
|
1960
1966
|
validateUuid(id, "Contact ID");
|
|
1961
|
-
const
|
|
1967
|
+
const input = { id };
|
|
1962
1968
|
if (opts.name) {
|
|
1963
1969
|
validateStringLength(opts.name, "Name", 200);
|
|
1964
|
-
|
|
1970
|
+
input.name = opts.name;
|
|
1965
1971
|
}
|
|
1966
1972
|
if (opts.email) {
|
|
1967
1973
|
validateEmail(opts.email);
|
|
1968
|
-
|
|
1974
|
+
input.email = opts.email;
|
|
1969
1975
|
}
|
|
1970
|
-
const data = await graphql(updateContact, { input
|
|
1976
|
+
const data = await graphql(updateContact, { input });
|
|
1971
1977
|
if (isJsonMode()) {
|
|
1972
1978
|
printJson(data.updateContact);
|
|
1973
1979
|
return;
|
|
@@ -2034,9 +2040,9 @@ prefsCommand.command("set").description("Update a preference").option("--theme <
|
|
|
2034
2040
|
if (opts.defaultView) validateView(opts.defaultView);
|
|
2035
2041
|
if (opts.defaultPriority && opts.defaultPriority !== "none") validatePriority(opts.defaultPriority);
|
|
2036
2042
|
if (opts.defaultColor && opts.defaultColor !== "none") validateHexColor(opts.defaultColor);
|
|
2037
|
-
const
|
|
2038
|
-
if (opts.theme)
|
|
2039
|
-
if (opts.defaultView)
|
|
2043
|
+
const input = {};
|
|
2044
|
+
if (opts.theme) input.theme = opts.theme;
|
|
2045
|
+
if (opts.defaultView) input.defaultView = opts.defaultView;
|
|
2040
2046
|
if (opts.archiveDelay) {
|
|
2041
2047
|
const delay = parseInt(opts.archiveDelay, 10);
|
|
2042
2048
|
if (isNaN(delay) || delay < 0 || delay > 8760) {
|
|
@@ -2044,22 +2050,22 @@ prefsCommand.command("set").description("Update a preference").option("--theme <
|
|
|
2044
2050
|
process.exitCode = 1;
|
|
2045
2051
|
return;
|
|
2046
2052
|
}
|
|
2047
|
-
|
|
2053
|
+
input.archiveDelay = delay;
|
|
2048
2054
|
}
|
|
2049
|
-
if (opts.defaultPriority)
|
|
2050
|
-
if (opts.defaultCategory)
|
|
2051
|
-
if (opts.defaultColor)
|
|
2052
|
-
if (Object.keys(
|
|
2055
|
+
if (opts.defaultPriority) input.defaultPriority = opts.defaultPriority === "none" ? "" : opts.defaultPriority;
|
|
2056
|
+
if (opts.defaultCategory) input.defaultCategoryId = opts.defaultCategory === "none" ? "" : opts.defaultCategory;
|
|
2057
|
+
if (opts.defaultColor) input.defaultColor = opts.defaultColor === "none" ? "" : opts.defaultColor;
|
|
2058
|
+
if (Object.keys(input).length === 0) {
|
|
2053
2059
|
printError("Provide at least one option: --theme, --default-view, --archive-delay, --default-priority, --default-category, --default-color");
|
|
2054
2060
|
process.exitCode = 1;
|
|
2055
2061
|
return;
|
|
2056
2062
|
}
|
|
2057
|
-
const data = await graphql(updatePreferences, { input
|
|
2063
|
+
const data = await graphql(updatePreferences, { input });
|
|
2058
2064
|
if (isJsonMode()) {
|
|
2059
2065
|
printJson(data.updatePreferences);
|
|
2060
2066
|
return;
|
|
2061
2067
|
}
|
|
2062
|
-
for (const [key, value] of Object.entries(
|
|
2068
|
+
for (const [key, value] of Object.entries(input)) {
|
|
2063
2069
|
printSuccess(`Updated preference: ${key} = ${value}`);
|
|
2064
2070
|
}
|
|
2065
2071
|
} catch (err) {
|
|
@@ -2178,34 +2184,57 @@ colorRulesCommand.command("remove").description("Remove a color rule").argument(
|
|
|
2178
2184
|
|
|
2179
2185
|
// src/commands/lists.ts
|
|
2180
2186
|
import { Command as Command9 } from "commander";
|
|
2181
|
-
import { randomUUID as randomUUID6 } from "crypto";
|
|
2182
2187
|
import { confirm as confirm6 } from "@inquirer/prompts";
|
|
2183
|
-
var
|
|
2188
|
+
var SORT_FIELDS = ["name", "created", "updated", "items"];
|
|
2189
|
+
function sortLists(lists, sort, reverse) {
|
|
2190
|
+
const sorted = [...lists].sort((a, b) => {
|
|
2191
|
+
switch (sort) {
|
|
2192
|
+
case "name":
|
|
2193
|
+
return a.name.localeCompare(b.name);
|
|
2194
|
+
case "created":
|
|
2195
|
+
return b.createdAt.localeCompare(a.createdAt);
|
|
2196
|
+
case "updated":
|
|
2197
|
+
return b.updatedAt.localeCompare(a.updatedAt);
|
|
2198
|
+
case "items":
|
|
2199
|
+
return b.itemCount - a.itemCount;
|
|
2200
|
+
}
|
|
2201
|
+
});
|
|
2202
|
+
return reverse ? sorted.reverse() : sorted;
|
|
2203
|
+
}
|
|
2204
|
+
var listsCommand = new Command9("lists").description("Manage lists").option("--sort <field>", "Sort by: name, created, updated, items (default: created)").option("--reverse", "Reverse sort order").action(async (opts) => {
|
|
2184
2205
|
try {
|
|
2206
|
+
const sort = opts.sort && SORT_FIELDS.includes(opts.sort) ? opts.sort : "created";
|
|
2207
|
+
if (opts.sort && !SORT_FIELDS.includes(opts.sort)) {
|
|
2208
|
+
printError(`Invalid sort field: ${opts.sort}. Valid: ${SORT_FIELDS.join(", ")}`);
|
|
2209
|
+
process.exitCode = 1;
|
|
2210
|
+
return;
|
|
2211
|
+
}
|
|
2185
2212
|
const data = await graphql(listLists);
|
|
2213
|
+
const lists = sortLists(data.listLists, sort, !!opts.reverse);
|
|
2186
2214
|
if (isJsonMode()) {
|
|
2187
|
-
printJson(
|
|
2215
|
+
printJson(lists);
|
|
2188
2216
|
return;
|
|
2189
2217
|
}
|
|
2190
|
-
if (
|
|
2218
|
+
if (lists.length === 0) {
|
|
2191
2219
|
console.log("No lists.");
|
|
2192
2220
|
return;
|
|
2193
2221
|
}
|
|
2194
2222
|
printTable(
|
|
2195
2223
|
["ID", "Name", "Items", "Created"],
|
|
2196
|
-
|
|
2224
|
+
lists.map((l) => [truncateId(l.id), l.name, String(l.itemCount), formatDate(l.createdAt)])
|
|
2197
2225
|
);
|
|
2198
2226
|
} catch (err) {
|
|
2199
2227
|
printError(err.message);
|
|
2200
2228
|
process.exitCode = 1;
|
|
2201
2229
|
}
|
|
2202
2230
|
});
|
|
2203
|
-
listsCommand.command("show").description("Show a list with items").argument("<id>", "List ID").action(async (id) => {
|
|
2231
|
+
listsCommand.command("show").description("Show a list with items").argument("<id>", "List ID").option("--completed", "Show completed items (default: active)").action(async (id, opts) => {
|
|
2204
2232
|
try {
|
|
2205
2233
|
validateUuid(id, "List ID");
|
|
2234
|
+
const completed = opts.completed === true ? true : false;
|
|
2206
2235
|
const [listsData, itemsData] = await Promise.all([
|
|
2207
2236
|
graphql(listLists),
|
|
2208
|
-
graphql(listListItems, { listId: id })
|
|
2237
|
+
graphql(listListItems, { listId: id, completed })
|
|
2209
2238
|
]);
|
|
2210
2239
|
const list = listsData.listLists.find((l) => l.id === id || l.id.startsWith(id));
|
|
2211
2240
|
if (!list) {
|
|
@@ -2224,11 +2253,21 @@ listsCommand.command("show").description("Show a list with items").argument("<id
|
|
|
2224
2253
|
console.log(`Color: ${list.color || "\u2014"}`);
|
|
2225
2254
|
console.log(`Items: ${list.itemCount}`);
|
|
2226
2255
|
console.log(`Created: ${formatDate(list.createdAt)}`);
|
|
2227
|
-
|
|
2256
|
+
console.log(`Showing: ${completed ? "Completed" : "Active"} items`);
|
|
2257
|
+
if (itemsData.listListItems.length === 0) {
|
|
2258
|
+
console.log(`
|
|
2259
|
+
No ${completed ? "completed" : "active"} items.`);
|
|
2260
|
+
} else {
|
|
2228
2261
|
console.log("\nItems:");
|
|
2229
2262
|
printTable(
|
|
2230
|
-
["ID", "Name", "Qty", "Category"],
|
|
2231
|
-
itemsData.listListItems.map((i) => [
|
|
2263
|
+
["ID", "Name", "Qty", "Category", "Done"],
|
|
2264
|
+
itemsData.listListItems.map((i) => [
|
|
2265
|
+
truncateId(i.id),
|
|
2266
|
+
i.name,
|
|
2267
|
+
i.quantity != null ? String(i.quantity) : "\u2014",
|
|
2268
|
+
i.category || "\u2014",
|
|
2269
|
+
i.completed ? `\u2713 ${i.completedBy || ""}`.trim() : "\u2014"
|
|
2270
|
+
])
|
|
2232
2271
|
);
|
|
2233
2272
|
}
|
|
2234
2273
|
} catch (err) {
|
|
@@ -2241,11 +2280,11 @@ listsCommand.command("create").description("Create a list").argument("<name>", "
|
|
|
2241
2280
|
validateStringLength(name, "Name", 200);
|
|
2242
2281
|
if (opts.desc) validateStringLength(opts.desc, "Description", 2e3);
|
|
2243
2282
|
if (opts.color) validateHexColor(opts.color);
|
|
2244
|
-
const
|
|
2245
|
-
if (opts.desc)
|
|
2246
|
-
if (opts.icon)
|
|
2247
|
-
if (opts.color)
|
|
2248
|
-
const data = await graphql(createList, { input
|
|
2283
|
+
const input = { name };
|
|
2284
|
+
if (opts.desc) input.description = opts.desc;
|
|
2285
|
+
if (opts.icon) input.icon = opts.icon;
|
|
2286
|
+
if (opts.color) input.color = opts.color;
|
|
2287
|
+
const data = await graphql(createList, { input });
|
|
2249
2288
|
if (isJsonMode()) {
|
|
2250
2289
|
printJson(data.createList);
|
|
2251
2290
|
return;
|
|
@@ -2262,12 +2301,12 @@ listsCommand.command("update").description("Update a list").argument("<id>", "Li
|
|
|
2262
2301
|
if (opts.name) validateStringLength(opts.name, "Name", 200);
|
|
2263
2302
|
if (opts.desc) validateStringLength(opts.desc, "Description", 2e3);
|
|
2264
2303
|
if (opts.color) validateHexColor(opts.color);
|
|
2265
|
-
const
|
|
2266
|
-
if (opts.name)
|
|
2267
|
-
if (opts.desc)
|
|
2268
|
-
if (opts.icon)
|
|
2269
|
-
if (opts.color)
|
|
2270
|
-
const data = await graphql(updateList, { input
|
|
2304
|
+
const input = { id };
|
|
2305
|
+
if (opts.name) input.name = opts.name;
|
|
2306
|
+
if (opts.desc) input.description = opts.desc;
|
|
2307
|
+
if (opts.icon) input.icon = opts.icon;
|
|
2308
|
+
if (opts.color) input.color = opts.color;
|
|
2309
|
+
const data = await graphql(updateList, { input });
|
|
2271
2310
|
if (isJsonMode()) {
|
|
2272
2311
|
printJson(data.updateList);
|
|
2273
2312
|
return;
|
|
@@ -2305,11 +2344,11 @@ listsCommand.command("add-item").description("Add an item to a list").argument("
|
|
|
2305
2344
|
validateStringLength(name, "Name", 500);
|
|
2306
2345
|
if (opts.qty) validateQuantity(opts.qty);
|
|
2307
2346
|
if (opts.link) validateUrl(opts.link);
|
|
2308
|
-
const
|
|
2309
|
-
if (opts.qty)
|
|
2310
|
-
if (opts.category)
|
|
2311
|
-
if (opts.link)
|
|
2312
|
-
const data = await graphql(createListItem, { input
|
|
2347
|
+
const input = { listId, name };
|
|
2348
|
+
if (opts.qty) input.quantity = validateQuantity(opts.qty);
|
|
2349
|
+
if (opts.category) input.category = opts.category;
|
|
2350
|
+
if (opts.link) input.link = opts.link;
|
|
2351
|
+
const data = await graphql(createListItem, { input });
|
|
2313
2352
|
if (isJsonMode()) {
|
|
2314
2353
|
printJson(data.createListItem);
|
|
2315
2354
|
return;
|
|
@@ -2326,16 +2365,8 @@ listsCommand.command("bulk-add").description("Add multiple items to a list").arg
|
|
|
2326
2365
|
for (const name of items) {
|
|
2327
2366
|
validateStringLength(name, "Item name", 500);
|
|
2328
2367
|
}
|
|
2329
|
-
const itemInputs = items.map((name, i) => ({
|
|
2330
|
-
id: randomUUID6(),
|
|
2331
|
-
listId,
|
|
2332
|
-
name,
|
|
2333
|
-
tags: [],
|
|
2334
|
-
customFields: "{}",
|
|
2335
|
-
position: Date.now() + i
|
|
2336
|
-
}));
|
|
2337
2368
|
const data = await graphql(bulkCreateListItems, {
|
|
2338
|
-
input: { listId,
|
|
2369
|
+
input: { listId, names: items }
|
|
2339
2370
|
});
|
|
2340
2371
|
if (isJsonMode()) {
|
|
2341
2372
|
printJson(data.bulkCreateListItems);
|
|
@@ -2354,12 +2385,12 @@ listsCommand.command("update-item").description("Update a list item").argument("
|
|
|
2354
2385
|
if (opts.name) validateStringLength(opts.name, "Name", 500);
|
|
2355
2386
|
if (opts.qty) validateQuantity(opts.qty);
|
|
2356
2387
|
if (opts.link) validateUrl(opts.link);
|
|
2357
|
-
const
|
|
2358
|
-
if (opts.name)
|
|
2359
|
-
if (opts.qty)
|
|
2360
|
-
if (opts.category)
|
|
2361
|
-
if (opts.link)
|
|
2362
|
-
const data = await graphql(updateListItem, { input
|
|
2388
|
+
const input = { id: itemId, listId: opts.list };
|
|
2389
|
+
if (opts.name) input.name = opts.name;
|
|
2390
|
+
if (opts.qty) input.quantity = validateQuantity(opts.qty);
|
|
2391
|
+
if (opts.category) input.category = opts.category;
|
|
2392
|
+
if (opts.link) input.link = opts.link;
|
|
2393
|
+
const data = await graphql(updateListItem, { input });
|
|
2363
2394
|
if (isJsonMode()) {
|
|
2364
2395
|
printJson(data.updateListItem);
|
|
2365
2396
|
return;
|
|
@@ -2392,6 +2423,40 @@ listsCommand.command("remove-item").description("Remove a list item").argument("
|
|
|
2392
2423
|
process.exitCode = 1;
|
|
2393
2424
|
}
|
|
2394
2425
|
});
|
|
2426
|
+
listsCommand.command("check").description("Mark a list item as complete").argument("<item-id>", "Item ID").requiredOption("--list <list-id>", "List ID").action(async (itemId, opts) => {
|
|
2427
|
+
try {
|
|
2428
|
+
validateUuid(itemId, "Item ID");
|
|
2429
|
+
validateUuid(opts.list, "List ID");
|
|
2430
|
+
const data = await graphql(updateListItem, {
|
|
2431
|
+
input: { id: itemId, listId: opts.list, completed: true }
|
|
2432
|
+
});
|
|
2433
|
+
if (isJsonMode()) {
|
|
2434
|
+
printJson(data.updateListItem);
|
|
2435
|
+
return;
|
|
2436
|
+
}
|
|
2437
|
+
printSuccess(`Marked complete: ${data.updateListItem.name}`);
|
|
2438
|
+
} catch (err) {
|
|
2439
|
+
printError(err.message);
|
|
2440
|
+
process.exitCode = 1;
|
|
2441
|
+
}
|
|
2442
|
+
});
|
|
2443
|
+
listsCommand.command("uncheck").description("Mark a list item as active (not complete)").argument("<item-id>", "Item ID").requiredOption("--list <list-id>", "List ID").action(async (itemId, opts) => {
|
|
2444
|
+
try {
|
|
2445
|
+
validateUuid(itemId, "Item ID");
|
|
2446
|
+
validateUuid(opts.list, "List ID");
|
|
2447
|
+
const data = await graphql(updateListItem, {
|
|
2448
|
+
input: { id: itemId, listId: opts.list, completed: false }
|
|
2449
|
+
});
|
|
2450
|
+
if (isJsonMode()) {
|
|
2451
|
+
printJson(data.updateListItem);
|
|
2452
|
+
return;
|
|
2453
|
+
}
|
|
2454
|
+
printSuccess(`Marked active: ${data.updateListItem.name}`);
|
|
2455
|
+
} catch (err) {
|
|
2456
|
+
printError(err.message);
|
|
2457
|
+
process.exitCode = 1;
|
|
2458
|
+
}
|
|
2459
|
+
});
|
|
2395
2460
|
|
|
2396
2461
|
// src/commands/shares.ts
|
|
2397
2462
|
import { Command as Command10 } from "commander";
|
|
@@ -2846,7 +2911,7 @@ apikeysCommand.command("revoke").description("Revoke an API key").argument("<id>
|
|
|
2846
2911
|
|
|
2847
2912
|
// src/index.ts
|
|
2848
2913
|
var program = new Command13();
|
|
2849
|
-
program.name("tasklumina").version("1.0.
|
|
2914
|
+
program.name("tasklumina").version("1.0.3").description("Task Lumina CLI \u2014 manage tasks from the terminal").option("--json", "Output as JSON").option("--no-color", "Disable colored output").option("--verbose", "Show detailed request info (endpoint masked)").option("--redact", "Mask emails and sensitive data in output");
|
|
2850
2915
|
program.hook("postAction", async () => {
|
|
2851
2916
|
await maybeAutoRotate();
|
|
2852
2917
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tasklumina/cli",
|
|
3
|
-
"version": "1.0
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Task Lumina CLI — manage tasks, notes, categories, and shares from the terminal",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,15 +26,15 @@
|
|
|
26
26
|
"prepublishOnly": "npm run build"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@inquirer/prompts": "^7.3.2",
|
|
29
30
|
"chalk": "^5.4.1",
|
|
30
31
|
"cli-table3": "^0.6.5",
|
|
31
32
|
"commander": "^13.1.0",
|
|
32
|
-
"@inquirer/prompts": "^7.3.2",
|
|
33
33
|
"keytar": "^7.9.0"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
|
+
"@types/node": "^22.0.0",
|
|
36
37
|
"tsup": "^8.4.0",
|
|
37
|
-
"typescript": "~5.7.0"
|
|
38
|
-
"@types/node": "^22.0.0"
|
|
38
|
+
"typescript": "~5.7.0"
|
|
39
39
|
}
|
|
40
40
|
}
|