aemdm 0.4.0 → 0.5.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/cli.js +91 -8
- package/dist/lib/delivery.js +6 -1
- package/package.json +2 -1
package/dist/cli.js
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import { fileURLToPath } from "node:url";
|
|
3
|
+
import { createRequire } from "node:module";
|
|
3
4
|
import { realpathSync } from "node:fs";
|
|
5
|
+
const require = createRequire(import.meta.url);
|
|
6
|
+
const pkg = require("../package.json");
|
|
4
7
|
import { Command, CommanderError, Option } from "commander";
|
|
5
8
|
import { z } from "zod";
|
|
6
9
|
import { CliError, normalizeBucket, request, requestJson, resolveBucket, resolveOptionalImsToken, resolveSearchAuth, } from "./lib/client.js";
|
|
@@ -36,6 +39,7 @@ const assetGetSchema = z
|
|
|
36
39
|
output: z.string().optional(),
|
|
37
40
|
metadata: z.boolean().default(false),
|
|
38
41
|
imsToken: z.string().optional(),
|
|
42
|
+
mimeType: z.string().optional(),
|
|
39
43
|
})
|
|
40
44
|
.superRefine((value, ctx) => {
|
|
41
45
|
if (value.metadata && value.output) {
|
|
@@ -190,6 +194,22 @@ async function handleAssetGet(assetId, options, runtime) {
|
|
|
190
194
|
writeJson(runtime.stdout, metadata);
|
|
191
195
|
return;
|
|
192
196
|
}
|
|
197
|
+
let mimeType = parsed.mimeType;
|
|
198
|
+
if (!parsed.original && !parsed.format && !parsed.binary && !mimeType) {
|
|
199
|
+
if (imsToken) {
|
|
200
|
+
const metadata = await requestJson(buildMetadataUrl(baseUrl, assetId), {
|
|
201
|
+
imsToken,
|
|
202
|
+
fetchImpl: runtime.fetchImpl,
|
|
203
|
+
});
|
|
204
|
+
mimeType = metadata?.repositoryMetadata?.["dc:format"];
|
|
205
|
+
if (mimeType)
|
|
206
|
+
verbose(runtime, `detected mime type: ${mimeType}`);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
throw new CliError("Cannot determine asset type without authentication. " +
|
|
210
|
+
"Provide --format for images, --original for documents, or --ims-token to auto-detect.");
|
|
211
|
+
}
|
|
212
|
+
}
|
|
193
213
|
const url = buildAssetUrl(baseUrl, {
|
|
194
214
|
assetId,
|
|
195
215
|
seoName: parsed.seoName,
|
|
@@ -199,6 +219,7 @@ async function handleAssetGet(assetId, options, runtime) {
|
|
|
199
219
|
quality: parsed.quality,
|
|
200
220
|
maxQuality: parsed.maxQuality,
|
|
201
221
|
original: parsed.original,
|
|
222
|
+
mimeType,
|
|
202
223
|
});
|
|
203
224
|
if (!parsed.binary) {
|
|
204
225
|
writeLine(runtime.stdout, url);
|
|
@@ -282,6 +303,7 @@ async function handleSearch(options, runtime) {
|
|
|
282
303
|
return;
|
|
283
304
|
}
|
|
284
305
|
const dimensions = resolveDimensions(parsed.size, parsed.width, parsed.height);
|
|
306
|
+
const mimeType = firstHit.repositoryMetadata?.["dc:format"];
|
|
285
307
|
const assetUrl = buildAssetUrl(baseUrl, {
|
|
286
308
|
assetId,
|
|
287
309
|
seoName: parsed.seoName,
|
|
@@ -291,6 +313,7 @@ async function handleSearch(options, runtime) {
|
|
|
291
313
|
quality: parsed.quality,
|
|
292
314
|
maxQuality: parsed.maxQuality,
|
|
293
315
|
original: parsed.original,
|
|
316
|
+
mimeType,
|
|
294
317
|
});
|
|
295
318
|
if (parsed.firstUrl) {
|
|
296
319
|
writeLine(runtime.stdout, assetUrl);
|
|
@@ -346,10 +369,37 @@ function buildProgram(runtime) {
|
|
|
346
369
|
const program = new Command();
|
|
347
370
|
program
|
|
348
371
|
.name("aemdm")
|
|
349
|
-
.description(
|
|
350
|
-
.version(
|
|
372
|
+
.description(`CLI for Adobe Dynamic Media with OpenAPI v${pkg.version}`)
|
|
373
|
+
.version(pkg.version)
|
|
351
374
|
.showHelpAfterError()
|
|
352
375
|
.option("-v, --verbose", "Show additional diagnostic output")
|
|
376
|
+
.addHelpText("after", `
|
|
377
|
+
Bucket:
|
|
378
|
+
Most commands need a delivery bucket. Provide it in one of three ways:
|
|
379
|
+
1. --bucket delivery-p123-e456.adobeaemcloud.com (per-command flag)
|
|
380
|
+
2. AEMDM_BUCKET environment variable
|
|
381
|
+
3. Save a default: aemdm --bucket delivery-p123-e456.adobeaemcloud.com
|
|
382
|
+
This writes to ~/.aemdm/config.json and is used when no flag or env var is set.
|
|
383
|
+
|
|
384
|
+
Authentication:
|
|
385
|
+
Public asset URLs and basic metadata (HEAD-based) require no authentication.
|
|
386
|
+
Full metadata, binary downloads, and search require an IMS bearer token:
|
|
387
|
+
1. --ims-token <token> (per-command flag)
|
|
388
|
+
2. AEMDM_IMS_TOKEN environment variable
|
|
389
|
+
3. Save a default: aemdm --ims-token <token>
|
|
390
|
+
This writes the token to ~/.aemdm/config.json for reuse.
|
|
391
|
+
|
|
392
|
+
Search also requires an Adobe API key:
|
|
393
|
+
1. --api-key <key> (per-command flag)
|
|
394
|
+
2. AEMDM_API_KEY environment variable
|
|
395
|
+
|
|
396
|
+
Examples:
|
|
397
|
+
aemdm --bucket delivery-p123-e456.adobeaemcloud.com Save default bucket
|
|
398
|
+
aemdm asset get urn:aaid:aem:1234 Print delivery URL
|
|
399
|
+
aemdm asset get urn:aaid:aem:1234 --format webp Print URL with format
|
|
400
|
+
aemdm asset get urn:aaid:aem:1234 --metadata Fetch asset metadata
|
|
401
|
+
aemdm search --text "hero banner" Search by text
|
|
402
|
+
aemdm search --text "logo" --first-url --format png Search and get URL`)
|
|
353
403
|
.configureOutput({
|
|
354
404
|
writeOut: (text) => runtime.stdout.write(text),
|
|
355
405
|
writeErr: (text) => runtime.stderr.write(text),
|
|
@@ -366,7 +416,8 @@ function buildProgram(runtime) {
|
|
|
366
416
|
.option("--output <file>", "Output file path for --binary. Use - for stdout")
|
|
367
417
|
.option("--metadata", "Fetch metadata JSON instead of building a URL")
|
|
368
418
|
.option("--ims-token <token>", "IMS bearer token for metadata or binary requests")
|
|
369
|
-
.
|
|
419
|
+
.option("--mime-type <type>", "Asset MIME type (skips metadata lookup for route detection)")
|
|
420
|
+
.action((assetId, options, cmd) => handleAssetGet(assetId, { ...cmd.parent.opts(), ...options }, runtime));
|
|
370
421
|
configureCommonDeliveryOptions(program.command("search").description("Search assets and optionally resolve the first result"))
|
|
371
422
|
.option("--bucket <bucket-or-url>", "Bucket host or full bucket URL")
|
|
372
423
|
.option("--ims-token <token>", "IMS bearer token")
|
|
@@ -398,12 +449,39 @@ Core commands:
|
|
|
398
449
|
- aemdm asset get <assetId>
|
|
399
450
|
- aemdm search
|
|
400
451
|
|
|
452
|
+
Bucket configuration (pick one):
|
|
453
|
+
- --bucket delivery-p123-e456.adobeaemcloud.com (per-command flag)
|
|
454
|
+
- AEMDM_BUCKET environment variable
|
|
455
|
+
- Save a default: aemdm --bucket delivery-p123-e456.adobeaemcloud.com
|
|
456
|
+
This writes to ~/.aemdm/config.json and is used when no flag or env var is set.
|
|
457
|
+
|
|
458
|
+
Authentication:
|
|
459
|
+
- Public asset URLs and basic metadata (HEAD-based) require no authentication.
|
|
460
|
+
- Full metadata, binary downloads, and search require an IMS bearer token (pick one):
|
|
461
|
+
1. --ims-token <token> (per-command flag)
|
|
462
|
+
2. AEMDM_IMS_TOKEN environment variable
|
|
463
|
+
3. Save a default: aemdm --ims-token <token>
|
|
464
|
+
This writes the token to ~/.aemdm/config.json for reuse.
|
|
465
|
+
- Both bucket and token can be saved together: aemdm --bucket <host> --ims-token <token>
|
|
466
|
+
- Search also requires an Adobe API key via --api-key <key> or AEMDM_API_KEY.
|
|
467
|
+
|
|
468
|
+
URL format:
|
|
469
|
+
- Images: https://<bucket>/adobe/assets/<assetId>/as/<seoName>.<format>
|
|
470
|
+
- Documents/video: https://<bucket>/adobe/assets/<assetId>/original/as/<seoName>
|
|
471
|
+
- Default seo-name is "asset", default format is "png".
|
|
472
|
+
- Use --format to override (gif, png, jpg, jpeg, webp, avif).
|
|
473
|
+
- Use --seo-name to set a custom SEO-friendly name segment.
|
|
474
|
+
|
|
475
|
+
Route detection:
|
|
476
|
+
- When authenticated, asset get auto-detects the MIME type via the metadata endpoint.
|
|
477
|
+
Images get the /as/<seoName>.<format> route; documents/video get /original/as/<seoName>.
|
|
478
|
+
- When unauthenticated, you must specify --format (for images) or --original (for documents).
|
|
479
|
+
- Use --mime-type <type> to skip the metadata lookup when you already know the type
|
|
480
|
+
(e.g. from a prior search result's dc:format field).
|
|
481
|
+
- search --first-url auto-detects using the dc:format from the search hit (no extra call).
|
|
482
|
+
|
|
401
483
|
Important defaults:
|
|
402
|
-
-
|
|
403
|
-
- A standalone call like aemdm --bucket delivery-p123-e456.adobeaemcloud.com saves the default bucket to the local aemdm profile config.
|
|
404
|
-
- aemdm --ims-token <token> saves the IMS token to the profile config. Both can be saved together.
|
|
405
|
-
- Search auth comes from --ims-token/AEMDM_IMS_TOKEN/profile config and --api-key/AEMDM_API_KEY.
|
|
406
|
-
- asset get prints a URL by default.
|
|
484
|
+
- asset get prints a delivery URL by default.
|
|
407
485
|
- asset get --metadata prints full JSON metadata when authenticated, or basic public JSON metadata when no token is supplied.
|
|
408
486
|
- asset get --binary downloads the asset and requires --output.
|
|
409
487
|
- search --first-id prints one asset ID for piping.
|
|
@@ -416,6 +494,7 @@ Asset URL examples:
|
|
|
416
494
|
- aemdm asset get urn:aaid:aem:1234 --original --binary --output ./asset.bin
|
|
417
495
|
- aemdm asset get urn:aaid:aem:1234 --metadata
|
|
418
496
|
- aemdm asset get urn:aaid:aem:1234 --metadata --ims-token <token>
|
|
497
|
+
- aemdm asset get urn:aaid:aem:1234 --mime-type application/pdf
|
|
419
498
|
|
|
420
499
|
Search examples:
|
|
421
500
|
- aemdm search --text "hero banner"
|
|
@@ -441,8 +520,12 @@ LLM usage guidance:
|
|
|
441
520
|
- Use search when you need to discover an asset by metadata or text.
|
|
442
521
|
- Prefer --first-id or --ids-only when another CLI call needs asset IDs.
|
|
443
522
|
- Prefer --first-url when the user wants a delivery URL from a search result.
|
|
523
|
+
--first-url uses the dc:format from the search hit to pick the correct route automatically.
|
|
444
524
|
- Prefer --first-metadata when the user wants the resolved asset metadata after search.
|
|
445
525
|
- Prefer --first-binary with --output when the user wants the downloaded file.
|
|
526
|
+
- When piping search results to asset get, pass --mime-type with the dc:format from the
|
|
527
|
+
search result to avoid an extra metadata call and ensure the correct route.
|
|
528
|
+
Example: aemdm asset get <id> --mime-type application/pdf
|
|
446
529
|
`;
|
|
447
530
|
}
|
|
448
531
|
function parseStandaloneConfig(argv) {
|
package/dist/lib/delivery.js
CHANGED
|
@@ -5,6 +5,9 @@ export const TRANSFORM_FALLBACK_FORMAT = "png";
|
|
|
5
5
|
export const deliveryFormatSchema = z.enum(["gif", "png", "jpg", "jpeg", "webp", "avif"]);
|
|
6
6
|
const qualitySchema = z.number().int().min(1).max(100);
|
|
7
7
|
const dimensionSchema = z.number().int().min(1);
|
|
8
|
+
function isImageMimeType(mimeType) {
|
|
9
|
+
return mimeType.startsWith("image/");
|
|
10
|
+
}
|
|
8
11
|
export function parseSize(value) {
|
|
9
12
|
const match = /^(?<width>\d+)?x(?<height>\d+)?$/i.exec(value.trim());
|
|
10
13
|
if (!match?.groups) {
|
|
@@ -58,7 +61,9 @@ export function buildAssetUrl(baseUrl, options) {
|
|
|
58
61
|
if (options.height !== undefined) {
|
|
59
62
|
dimensionSchema.parse(options.height);
|
|
60
63
|
}
|
|
61
|
-
|
|
64
|
+
const useOriginal = options.original ||
|
|
65
|
+
(options.mimeType !== undefined && !isImageMimeType(options.mimeType));
|
|
66
|
+
if (useOriginal) {
|
|
62
67
|
return `${normalizedBase}/${encodedAssetId}/original/as/${encodedSeoName}`;
|
|
63
68
|
}
|
|
64
69
|
const shouldUseTransformRoute = options.format !== undefined ||
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aemdm",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "CLI for Adobe Dynamic Media with OpenAPI",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"author": "Chris Pilsworth",
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"node": ">=20"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
+
"aemdm": "^0.4.1",
|
|
44
45
|
"commander": "^14.0.1",
|
|
45
46
|
"zod": "^4.1.12"
|
|
46
47
|
},
|