@jant/core 0.3.46 → 0.3.48
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/bin/commands/db/execute-file.js +12 -4
- package/bin/commands/db/rehearse.js +2 -2
- package/bin/commands/export.js +12 -4
- package/bin/commands/import-site.js +60 -267
- package/bin/commands/migrate.js +36 -69
- package/bin/commands/reset-password.js +10 -4
- package/bin/commands/site/export.js +59 -248
- package/bin/commands/site/snapshot/export.js +58 -45
- package/bin/commands/site/snapshot/import.js +104 -52
- package/bin/lib/node-env.js +100 -0
- package/bin/lib/runtime-target.js +64 -0
- package/bin/lib/site-snapshot.js +185 -54
- package/bin/lib/sql-export.js +19 -2
- package/dist/app-DU7dpJID.js +6 -0
- package/dist/{app-DB-P66E5.js → app-DdnIoX7y.js} +333 -191
- package/dist/client/.vite/manifest.json +2 -2
- package/dist/client/_assets/client-BoUn7xBo.css +2 -0
- package/dist/client/_assets/{client-auth-BLCUje4M.js → client-auth-Ce5WEAVS.js} +102 -49
- package/dist/{github-sync-CQ1x271f.js → export-ZBlfKSKm.js} +12 -439
- package/dist/github-sync-C593r22F.js +4 -0
- package/dist/github-sync-bL1hnx3Q.js +428 -0
- package/dist/index.js +3 -2
- package/dist/node.js +5 -4
- package/package.json +3 -2
- package/src/__tests__/helpers/export-fixtures.ts +0 -1
- package/src/client/components/__tests__/jant-settings-avatar.test.ts +2 -0
- package/src/client/components/__tests__/jant-settings-general.test.ts +70 -0
- package/src/client/components/jant-settings-general.ts +164 -22
- package/src/client/components/settings-types.ts +4 -6
- package/src/client-auth.ts +1 -1
- package/src/db/__tests__/demo-canonical-snapshot.test.ts +1 -1
- package/src/db/__tests__/migration-rehearsal.test.ts +2 -5
- package/src/db/backfills/0004_register_apple_touch_media_rows.sql +65 -0
- package/src/db/migrations/0021_thankful_phalanx.sql +16 -0
- package/src/db/migrations/meta/0021_snapshot.json +2121 -0
- package/src/db/migrations/meta/_journal.json +7 -0
- package/src/db/migrations/pg/0019_gray_natasha_romanoff.sql +20 -0
- package/src/db/migrations/pg/meta/0019_snapshot.json +2718 -0
- package/src/db/migrations/pg/meta/_journal.json +7 -0
- package/src/db/pg/schema.ts +21 -26
- package/src/db/rehearsal-fixtures/demo-current.json +1 -1
- package/src/db/schema.ts +16 -20
- package/src/i18n/__tests__/middleware.test.ts +43 -1
- package/src/i18n/coverage.generated.ts +17 -0
- package/src/i18n/i18n.ts +18 -2
- package/src/i18n/index.ts +3 -0
- package/src/i18n/locales/settings/en.po +16 -11
- package/src/i18n/locales/settings/en.ts +1 -1
- package/src/i18n/locales/settings/zh-Hans.po +17 -12
- package/src/i18n/locales/settings/zh-Hans.ts +1 -1
- package/src/i18n/locales/settings/zh-Hant.po +16 -11
- package/src/i18n/locales/settings/zh-Hant.ts +1 -1
- package/src/i18n/locales.ts +84 -2
- package/src/i18n/middleware.ts +25 -16
- package/src/i18n/supported-locales.ts +153 -0
- package/src/lib/__tests__/csp-builder.test.ts +19 -2
- package/src/lib/__tests__/feed.test.ts +242 -1
- package/src/lib/__tests__/post-meta.test.ts +0 -1
- package/src/lib/__tests__/view.test.ts +0 -1
- package/src/lib/api-posts.ts +9 -7
- package/src/lib/csp-builder.ts +28 -10
- package/src/lib/feed.ts +153 -3
- package/src/middleware/__tests__/secure-headers.test.ts +89 -0
- package/src/middleware/auth.ts +1 -1
- package/src/middleware/secure-headers.ts +47 -1
- package/src/node/__tests__/cli-runtime-target.test.ts +110 -2
- package/src/node/__tests__/cli-site-snapshot.test.ts +308 -13
- package/src/node/__tests__/cli-site-token-env.test.ts +2 -7
- package/src/node/__tests__/cli-snapshot-meta.test.ts +85 -0
- package/src/node/__tests__/cli-sql-export.test.ts +49 -0
- package/src/node/index.ts +1 -0
- package/src/preset.css +8 -2
- package/src/routes/api/__tests__/settings.test.ts +3 -2
- package/src/routes/api/github-sync.tsx +1 -1
- package/src/routes/api/settings.ts +4 -1
- package/src/routes/auth/signin.tsx +6 -0
- package/src/routes/pages/archive.tsx +4 -2
- package/src/services/__tests__/post.test.ts +19 -19
- package/src/services/__tests__/search.test.ts +0 -1
- package/src/services/__tests__/settings.test.ts +22 -3
- package/src/services/bootstrap.ts +7 -3
- package/src/services/collection.ts +3 -3
- package/src/services/export.ts +0 -3
- package/src/services/navigation.ts +0 -2
- package/src/services/path.ts +1 -38
- package/src/services/post.ts +32 -66
- package/src/services/search.ts +0 -6
- package/src/services/settings.ts +47 -6
- package/src/services/site-admin.ts +6 -1
- package/src/styles/ui.css +14 -25
- package/src/types/entities.ts +0 -1
- package/src/ui/color-themes.ts +1 -1
- package/src/ui/dash/settings/GeneralContent.tsx +17 -19
- package/src/ui/dash/settings/SettingsRootContent.tsx +17 -28
- package/src/ui/feed/NoteCard.tsx +1 -11
- package/src/ui/feed/__tests__/timeline-cards.test.ts +1 -1
- package/src/ui/pages/PostPage.tsx +2 -0
- package/bin/commands/collections.js +0 -268
- package/bin/commands/media.js +0 -302
- package/bin/commands/posts.js +0 -262
- package/bin/commands/search.js +0 -53
- package/bin/commands/settings.js +0 -93
- package/bin/lib/http-api.js +0 -223
- package/bin/lib/media-upload.js +0 -206
- package/dist/app-CM7sb3xO.js +0 -5
- package/dist/client/_assets/client-DDs6NzB3.css +0 -2
- package/src/__tests__/bin/content-cli.test.ts +0 -179
- package/src/__tests__/bin/media-cli.test.ts +0 -192
- /package/dist/{github-api-BkRWnqMx.js → github-api-Bh0PH3zr.js} +0 -0
- /package/dist/{github-app-WeadXMb8.js → github-app-D0GvNnqp.js} +0 -0
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { parseArgs } from "node:util";
|
|
2
|
-
import {
|
|
3
|
-
getOptionalApiToken,
|
|
4
|
-
printJson,
|
|
5
|
-
readJsonInput,
|
|
6
|
-
requestJson,
|
|
7
|
-
requireApiToken,
|
|
8
|
-
requireSiteUrl,
|
|
9
|
-
runCommand,
|
|
10
|
-
sharedApiOptions,
|
|
11
|
-
} from "../lib/http-api.js";
|
|
12
|
-
|
|
13
|
-
function showHelp() {
|
|
14
|
-
console.log("Usage: jant collections <subcommand> [options]");
|
|
15
|
-
console.log("");
|
|
16
|
-
console.log("Subcommands:");
|
|
17
|
-
console.log(" list List collections");
|
|
18
|
-
console.log(" get <id> Get one collection");
|
|
19
|
-
console.log(" create Create a collection from JSON");
|
|
20
|
-
console.log(" update <id> Update a collection from JSON");
|
|
21
|
-
console.log(" delete <id> Delete a collection");
|
|
22
|
-
console.log(" add-post <collection> <post> Add a post to a collection");
|
|
23
|
-
console.log(
|
|
24
|
-
" remove-post <collection> <post> Remove a post from a collection",
|
|
25
|
-
);
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
export async function run(argv) {
|
|
29
|
-
return runCommand(async () => {
|
|
30
|
-
const [subcommand, ...rest] = argv;
|
|
31
|
-
|
|
32
|
-
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
33
|
-
showHelp();
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
switch (subcommand) {
|
|
38
|
-
case "list":
|
|
39
|
-
await runList(rest);
|
|
40
|
-
return;
|
|
41
|
-
case "get":
|
|
42
|
-
await runGet(rest);
|
|
43
|
-
return;
|
|
44
|
-
case "create":
|
|
45
|
-
await runCreate(rest);
|
|
46
|
-
return;
|
|
47
|
-
case "update":
|
|
48
|
-
await runUpdate(rest);
|
|
49
|
-
return;
|
|
50
|
-
case "delete":
|
|
51
|
-
await runDelete(rest);
|
|
52
|
-
return;
|
|
53
|
-
case "add-post":
|
|
54
|
-
await runAddPost(rest);
|
|
55
|
-
return;
|
|
56
|
-
case "remove-post":
|
|
57
|
-
await runRemovePost(rest);
|
|
58
|
-
return;
|
|
59
|
-
default:
|
|
60
|
-
throw new Error(`Unknown collections subcommand: ${subcommand}`);
|
|
61
|
-
}
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
async function runList(argv) {
|
|
66
|
-
const { values } = parseArgs({
|
|
67
|
-
args: argv,
|
|
68
|
-
allowPositionals: false,
|
|
69
|
-
options: {
|
|
70
|
-
...sharedApiOptions,
|
|
71
|
-
view: { type: "string" },
|
|
72
|
-
},
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
if (values.help) {
|
|
76
|
-
console.log("Usage: jant collections list [--view compose] [options]");
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
const siteUrl = requireSiteUrl(values, "Listing collections");
|
|
81
|
-
const result = await requestJson({
|
|
82
|
-
siteUrl,
|
|
83
|
-
path: "/api/collections",
|
|
84
|
-
token: getOptionalApiToken(values),
|
|
85
|
-
query: { view: values.view },
|
|
86
|
-
});
|
|
87
|
-
printJson(result);
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
async function runGet(argv) {
|
|
91
|
-
const { values, positionals } = parseArgs({
|
|
92
|
-
args: argv,
|
|
93
|
-
allowPositionals: true,
|
|
94
|
-
options: sharedApiOptions,
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
if (values.help) {
|
|
98
|
-
console.log("Usage: jant collections get <id> [options]");
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const collectionId = positionals[0];
|
|
103
|
-
if (!collectionId) {
|
|
104
|
-
throw new Error("Collection ID is required.");
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
const siteUrl = requireSiteUrl(values, "Getting a collection");
|
|
108
|
-
const result = await requestJson({
|
|
109
|
-
siteUrl,
|
|
110
|
-
path: `/api/collections/${collectionId}`,
|
|
111
|
-
token: getOptionalApiToken(values),
|
|
112
|
-
});
|
|
113
|
-
printJson(result);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
async function runCreate(argv) {
|
|
117
|
-
const { values } = parseArgs({
|
|
118
|
-
args: argv,
|
|
119
|
-
allowPositionals: false,
|
|
120
|
-
options: {
|
|
121
|
-
...sharedApiOptions,
|
|
122
|
-
input: { type: "string" },
|
|
123
|
-
json: { type: "string" },
|
|
124
|
-
},
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
if (values.help) {
|
|
128
|
-
console.log(
|
|
129
|
-
"Usage: jant collections create (--json '{...}' | --input <path>)",
|
|
130
|
-
);
|
|
131
|
-
return;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const siteUrl = requireSiteUrl(values, "Creating a collection");
|
|
135
|
-
const token = requireApiToken(values, "Creating a collection");
|
|
136
|
-
const body = await readJsonInput(values);
|
|
137
|
-
const result = await requestJson({
|
|
138
|
-
siteUrl,
|
|
139
|
-
path: "/api/collections",
|
|
140
|
-
method: "POST",
|
|
141
|
-
token,
|
|
142
|
-
body,
|
|
143
|
-
});
|
|
144
|
-
printJson(result);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
async function runUpdate(argv) {
|
|
148
|
-
const { values, positionals } = parseArgs({
|
|
149
|
-
args: argv,
|
|
150
|
-
allowPositionals: true,
|
|
151
|
-
options: {
|
|
152
|
-
...sharedApiOptions,
|
|
153
|
-
input: { type: "string" },
|
|
154
|
-
json: { type: "string" },
|
|
155
|
-
},
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
if (values.help) {
|
|
159
|
-
console.log(
|
|
160
|
-
"Usage: jant collections update <id> (--json '{...}' | --input <path>)",
|
|
161
|
-
);
|
|
162
|
-
return;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
const collectionId = positionals[0];
|
|
166
|
-
if (!collectionId) {
|
|
167
|
-
throw new Error("Collection ID is required.");
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
const siteUrl = requireSiteUrl(values, "Updating a collection");
|
|
171
|
-
const token = requireApiToken(values, "Updating a collection");
|
|
172
|
-
const body = await readJsonInput(values);
|
|
173
|
-
const result = await requestJson({
|
|
174
|
-
siteUrl,
|
|
175
|
-
path: `/api/collections/${collectionId}`,
|
|
176
|
-
method: "PUT",
|
|
177
|
-
token,
|
|
178
|
-
body,
|
|
179
|
-
});
|
|
180
|
-
printJson(result);
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
async function runDelete(argv) {
|
|
184
|
-
const { values, positionals } = parseArgs({
|
|
185
|
-
args: argv,
|
|
186
|
-
allowPositionals: true,
|
|
187
|
-
options: sharedApiOptions,
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
if (values.help) {
|
|
191
|
-
console.log("Usage: jant collections delete <id> [options]");
|
|
192
|
-
return;
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
const collectionId = positionals[0];
|
|
196
|
-
if (!collectionId) {
|
|
197
|
-
throw new Error("Collection ID is required.");
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
const siteUrl = requireSiteUrl(values, "Deleting a collection");
|
|
201
|
-
const token = requireApiToken(values, "Deleting a collection");
|
|
202
|
-
const result = await requestJson({
|
|
203
|
-
siteUrl,
|
|
204
|
-
path: `/api/collections/${collectionId}`,
|
|
205
|
-
method: "DELETE",
|
|
206
|
-
token,
|
|
207
|
-
});
|
|
208
|
-
printJson(result);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
async function runAddPost(argv) {
|
|
212
|
-
const { values, positionals } = parseArgs({
|
|
213
|
-
args: argv,
|
|
214
|
-
allowPositionals: true,
|
|
215
|
-
options: sharedApiOptions,
|
|
216
|
-
});
|
|
217
|
-
|
|
218
|
-
if (values.help) {
|
|
219
|
-
console.log("Usage: jant collections add-post <collectionId> <postId>");
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
const collectionId = positionals[0];
|
|
224
|
-
const postId = positionals[1];
|
|
225
|
-
if (!collectionId || !postId) {
|
|
226
|
-
throw new Error("Collection ID and post ID are required.");
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
const siteUrl = requireSiteUrl(values, "Adding a post to a collection");
|
|
230
|
-
const token = requireApiToken(values, "Adding a post to a collection");
|
|
231
|
-
const result = await requestJson({
|
|
232
|
-
siteUrl,
|
|
233
|
-
path: `/api/collections/${collectionId}/posts`,
|
|
234
|
-
method: "POST",
|
|
235
|
-
token,
|
|
236
|
-
body: { postId },
|
|
237
|
-
});
|
|
238
|
-
printJson(result);
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
async function runRemovePost(argv) {
|
|
242
|
-
const { values, positionals } = parseArgs({
|
|
243
|
-
args: argv,
|
|
244
|
-
allowPositionals: true,
|
|
245
|
-
options: sharedApiOptions,
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
if (values.help) {
|
|
249
|
-
console.log("Usage: jant collections remove-post <collectionId> <postId>");
|
|
250
|
-
return;
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
const collectionId = positionals[0];
|
|
254
|
-
const postId = positionals[1];
|
|
255
|
-
if (!collectionId || !postId) {
|
|
256
|
-
throw new Error("Collection ID and post ID are required.");
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
const siteUrl = requireSiteUrl(values, "Removing a post from a collection");
|
|
260
|
-
const token = requireApiToken(values, "Removing a post from a collection");
|
|
261
|
-
const result = await requestJson({
|
|
262
|
-
siteUrl,
|
|
263
|
-
path: `/api/collections/${collectionId}/posts/${postId}`,
|
|
264
|
-
method: "DELETE",
|
|
265
|
-
token,
|
|
266
|
-
});
|
|
267
|
-
printJson(result);
|
|
268
|
-
}
|
package/bin/commands/media.js
DELETED
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
import { parseArgs } from "node:util";
|
|
2
|
-
import {
|
|
3
|
-
printJson,
|
|
4
|
-
requestJson,
|
|
5
|
-
requireApiToken,
|
|
6
|
-
requireSiteUrl,
|
|
7
|
-
runCommand,
|
|
8
|
-
sharedApiOptions,
|
|
9
|
-
} from "../lib/http-api.js";
|
|
10
|
-
import { uploadMediaFile } from "../lib/media-upload.js";
|
|
11
|
-
|
|
12
|
-
function parseOptionalNonNegativeInteger(value, label) {
|
|
13
|
-
if (value === undefined) {
|
|
14
|
-
return undefined;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
const parsed = Number.parseInt(value, 10);
|
|
18
|
-
if (!Number.isInteger(parsed) || parsed < 0) {
|
|
19
|
-
throw new Error(`${label} must be a non-negative integer.`);
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
return parsed;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
function parseOptionalPositiveInteger(value, label) {
|
|
26
|
-
if (value === undefined) {
|
|
27
|
-
return undefined;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const parsed = Number.parseInt(value, 10);
|
|
31
|
-
if (!Number.isInteger(parsed) || parsed < 1) {
|
|
32
|
-
throw new Error(`${label} must be a positive integer.`);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
return parsed;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
function showHelp() {
|
|
39
|
-
console.log("Usage: jant media <subcommand> [options]");
|
|
40
|
-
console.log("");
|
|
41
|
-
console.log("Subcommands:");
|
|
42
|
-
console.log(" list List uploaded media");
|
|
43
|
-
console.log(" get <id> Get one media item");
|
|
44
|
-
console.log(" upload <file> Upload one file");
|
|
45
|
-
console.log(" content <id> Get text attachment markdown");
|
|
46
|
-
console.log(" set-alt <id> --alt <t> Update alt text");
|
|
47
|
-
console.log(" delete <id> Delete a media item");
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export async function run(argv) {
|
|
51
|
-
return runCommand(async () => {
|
|
52
|
-
const [subcommand, ...rest] = argv;
|
|
53
|
-
|
|
54
|
-
if (!subcommand || subcommand === "--help" || subcommand === "-h") {
|
|
55
|
-
showHelp();
|
|
56
|
-
return;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
switch (subcommand) {
|
|
60
|
-
case "list":
|
|
61
|
-
await runList(rest);
|
|
62
|
-
return;
|
|
63
|
-
case "get":
|
|
64
|
-
await runGet(rest);
|
|
65
|
-
return;
|
|
66
|
-
case "upload":
|
|
67
|
-
await runUpload(rest);
|
|
68
|
-
return;
|
|
69
|
-
case "content":
|
|
70
|
-
await runContent(rest);
|
|
71
|
-
return;
|
|
72
|
-
case "set-alt":
|
|
73
|
-
await runSetAlt(rest);
|
|
74
|
-
return;
|
|
75
|
-
case "delete":
|
|
76
|
-
await runDelete(rest);
|
|
77
|
-
return;
|
|
78
|
-
default:
|
|
79
|
-
throw new Error(`Unknown media subcommand: ${subcommand}`);
|
|
80
|
-
}
|
|
81
|
-
});
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
async function runList(argv) {
|
|
85
|
-
const { values } = parseArgs({
|
|
86
|
-
args: argv,
|
|
87
|
-
allowPositionals: false,
|
|
88
|
-
options: {
|
|
89
|
-
...sharedApiOptions,
|
|
90
|
-
limit: { type: "string" },
|
|
91
|
-
mimePrefix: { type: "string" },
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
if (values.help) {
|
|
96
|
-
console.log(
|
|
97
|
-
"Usage: jant media list [--limit 50] [--mimePrefix image/] [options]",
|
|
98
|
-
);
|
|
99
|
-
return;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
const siteUrl = requireSiteUrl(values, "Listing media");
|
|
103
|
-
const token = requireApiToken(values, "Listing media");
|
|
104
|
-
const result = await requestJson({
|
|
105
|
-
siteUrl,
|
|
106
|
-
path: "/api/upload",
|
|
107
|
-
token,
|
|
108
|
-
query: {
|
|
109
|
-
limit: values.limit,
|
|
110
|
-
mimePrefix: values.mimePrefix,
|
|
111
|
-
},
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
printJson(result);
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
async function runGet(argv) {
|
|
118
|
-
const { values, positionals } = parseArgs({
|
|
119
|
-
args: argv,
|
|
120
|
-
allowPositionals: true,
|
|
121
|
-
options: sharedApiOptions,
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
if (values.help) {
|
|
125
|
-
console.log("Usage: jant media get <id> [options]");
|
|
126
|
-
return;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const mediaId = positionals[0];
|
|
130
|
-
if (!mediaId) {
|
|
131
|
-
throw new Error("Media ID is required.");
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const siteUrl = requireSiteUrl(values, "Getting media");
|
|
135
|
-
const token = requireApiToken(values, "Getting media");
|
|
136
|
-
const result = await requestJson({
|
|
137
|
-
siteUrl,
|
|
138
|
-
path: `/api/upload/${mediaId}`,
|
|
139
|
-
token,
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
printJson(result);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
async function runUpload(argv) {
|
|
146
|
-
const { values, positionals } = parseArgs({
|
|
147
|
-
args: argv,
|
|
148
|
-
allowPositionals: true,
|
|
149
|
-
options: {
|
|
150
|
-
...sharedApiOptions,
|
|
151
|
-
alt: { type: "string" },
|
|
152
|
-
blurhash: { type: "string" },
|
|
153
|
-
chars: { type: "string" },
|
|
154
|
-
contentType: { type: "string" },
|
|
155
|
-
durationSeconds: { type: "string" },
|
|
156
|
-
height: { type: "string" },
|
|
157
|
-
poster: { type: "string" },
|
|
158
|
-
summary: { type: "string" },
|
|
159
|
-
waveform: { type: "string" },
|
|
160
|
-
width: { type: "string" },
|
|
161
|
-
},
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
if (values.help) {
|
|
165
|
-
console.log("Usage: jant media upload <file> [options]");
|
|
166
|
-
console.log("");
|
|
167
|
-
console.log("Options:");
|
|
168
|
-
console.log(" --contentType Override inferred MIME type");
|
|
169
|
-
console.log(" --alt Alt text");
|
|
170
|
-
console.log(" --summary Text summary");
|
|
171
|
-
console.log(" --width Pixel width");
|
|
172
|
-
console.log(" --height Pixel height");
|
|
173
|
-
console.log(" --durationSeconds Duration for audio or video");
|
|
174
|
-
console.log(" --blurhash Image blurhash");
|
|
175
|
-
console.log(" --waveform Audio waveform string");
|
|
176
|
-
console.log(" --poster Poster image path for video uploads");
|
|
177
|
-
return;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const filePath = positionals[0];
|
|
181
|
-
if (!filePath) {
|
|
182
|
-
throw new Error("File path is required.");
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
const siteUrl = requireSiteUrl(values, "Uploading media");
|
|
186
|
-
const token = requireApiToken(values, "Uploading media");
|
|
187
|
-
const result = await uploadMediaFile({
|
|
188
|
-
alt: values.alt?.trim() || undefined,
|
|
189
|
-
blurhash: values.blurhash?.trim() || undefined,
|
|
190
|
-
chars: parseOptionalNonNegativeInteger(values.chars, "chars"),
|
|
191
|
-
contentType: values.contentType,
|
|
192
|
-
durationSeconds: parseOptionalPositiveInteger(
|
|
193
|
-
values.durationSeconds,
|
|
194
|
-
"durationSeconds",
|
|
195
|
-
),
|
|
196
|
-
filePath,
|
|
197
|
-
height: parseOptionalPositiveInteger(values.height, "height"),
|
|
198
|
-
posterPath: values.poster,
|
|
199
|
-
siteUrl,
|
|
200
|
-
summary: values.summary?.trim() || undefined,
|
|
201
|
-
token,
|
|
202
|
-
waveform: values.waveform?.trim() || undefined,
|
|
203
|
-
width: parseOptionalPositiveInteger(values.width, "width"),
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
printJson(result);
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
async function runContent(argv) {
|
|
210
|
-
const { values, positionals } = parseArgs({
|
|
211
|
-
args: argv,
|
|
212
|
-
allowPositionals: true,
|
|
213
|
-
options: sharedApiOptions,
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
if (values.help) {
|
|
217
|
-
console.log("Usage: jant media content <id> [options]");
|
|
218
|
-
return;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
const mediaId = positionals[0];
|
|
222
|
-
if (!mediaId) {
|
|
223
|
-
throw new Error("Media ID is required.");
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
const siteUrl = requireSiteUrl(values, "Getting attachment content");
|
|
227
|
-
const token = requireApiToken(values, "Getting attachment content");
|
|
228
|
-
const result = await requestJson({
|
|
229
|
-
siteUrl,
|
|
230
|
-
path: `/api/attachments/${mediaId}/content`,
|
|
231
|
-
token,
|
|
232
|
-
});
|
|
233
|
-
|
|
234
|
-
printJson(result);
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
async function runSetAlt(argv) {
|
|
238
|
-
const { values, positionals } = parseArgs({
|
|
239
|
-
args: argv,
|
|
240
|
-
allowPositionals: true,
|
|
241
|
-
options: {
|
|
242
|
-
...sharedApiOptions,
|
|
243
|
-
alt: { type: "string" },
|
|
244
|
-
},
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
if (values.help) {
|
|
248
|
-
console.log("Usage: jant media set-alt <id> --alt <text> [options]");
|
|
249
|
-
return;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
const mediaId = positionals[0];
|
|
253
|
-
if (!mediaId) {
|
|
254
|
-
throw new Error("Media ID is required.");
|
|
255
|
-
}
|
|
256
|
-
if (values.alt === undefined) {
|
|
257
|
-
throw new Error("--alt is required.");
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
const siteUrl = requireSiteUrl(values, "Updating media alt text");
|
|
261
|
-
const token = requireApiToken(values, "Updating media alt text");
|
|
262
|
-
const result = await requestJson({
|
|
263
|
-
siteUrl,
|
|
264
|
-
path: `/api/upload/${mediaId}`,
|
|
265
|
-
method: "PATCH",
|
|
266
|
-
token,
|
|
267
|
-
body: {
|
|
268
|
-
alt: values.alt,
|
|
269
|
-
},
|
|
270
|
-
});
|
|
271
|
-
|
|
272
|
-
printJson(result);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
async function runDelete(argv) {
|
|
276
|
-
const { values, positionals } = parseArgs({
|
|
277
|
-
args: argv,
|
|
278
|
-
allowPositionals: true,
|
|
279
|
-
options: sharedApiOptions,
|
|
280
|
-
});
|
|
281
|
-
|
|
282
|
-
if (values.help) {
|
|
283
|
-
console.log("Usage: jant media delete <id> [options]");
|
|
284
|
-
return;
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
const mediaId = positionals[0];
|
|
288
|
-
if (!mediaId) {
|
|
289
|
-
throw new Error("Media ID is required.");
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const siteUrl = requireSiteUrl(values, "Deleting media");
|
|
293
|
-
const token = requireApiToken(values, "Deleting media");
|
|
294
|
-
const result = await requestJson({
|
|
295
|
-
siteUrl,
|
|
296
|
-
path: `/api/upload/${mediaId}`,
|
|
297
|
-
method: "DELETE",
|
|
298
|
-
token,
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
printJson(result);
|
|
302
|
-
}
|