aemdm 0.4.1 → 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 +86 -6
- package/dist/lib/delivery.js +6 -1
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -39,6 +39,7 @@ const assetGetSchema = z
|
|
|
39
39
|
output: z.string().optional(),
|
|
40
40
|
metadata: z.boolean().default(false),
|
|
41
41
|
imsToken: z.string().optional(),
|
|
42
|
+
mimeType: z.string().optional(),
|
|
42
43
|
})
|
|
43
44
|
.superRefine((value, ctx) => {
|
|
44
45
|
if (value.metadata && value.output) {
|
|
@@ -193,6 +194,22 @@ async function handleAssetGet(assetId, options, runtime) {
|
|
|
193
194
|
writeJson(runtime.stdout, metadata);
|
|
194
195
|
return;
|
|
195
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
|
+
}
|
|
196
213
|
const url = buildAssetUrl(baseUrl, {
|
|
197
214
|
assetId,
|
|
198
215
|
seoName: parsed.seoName,
|
|
@@ -202,6 +219,7 @@ async function handleAssetGet(assetId, options, runtime) {
|
|
|
202
219
|
quality: parsed.quality,
|
|
203
220
|
maxQuality: parsed.maxQuality,
|
|
204
221
|
original: parsed.original,
|
|
222
|
+
mimeType,
|
|
205
223
|
});
|
|
206
224
|
if (!parsed.binary) {
|
|
207
225
|
writeLine(runtime.stdout, url);
|
|
@@ -285,6 +303,7 @@ async function handleSearch(options, runtime) {
|
|
|
285
303
|
return;
|
|
286
304
|
}
|
|
287
305
|
const dimensions = resolveDimensions(parsed.size, parsed.width, parsed.height);
|
|
306
|
+
const mimeType = firstHit.repositoryMetadata?.["dc:format"];
|
|
288
307
|
const assetUrl = buildAssetUrl(baseUrl, {
|
|
289
308
|
assetId,
|
|
290
309
|
seoName: parsed.seoName,
|
|
@@ -294,6 +313,7 @@ async function handleSearch(options, runtime) {
|
|
|
294
313
|
quality: parsed.quality,
|
|
295
314
|
maxQuality: parsed.maxQuality,
|
|
296
315
|
original: parsed.original,
|
|
316
|
+
mimeType,
|
|
297
317
|
});
|
|
298
318
|
if (parsed.firstUrl) {
|
|
299
319
|
writeLine(runtime.stdout, assetUrl);
|
|
@@ -353,6 +373,33 @@ function buildProgram(runtime) {
|
|
|
353
373
|
.version(pkg.version)
|
|
354
374
|
.showHelpAfterError()
|
|
355
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`)
|
|
356
403
|
.configureOutput({
|
|
357
404
|
writeOut: (text) => runtime.stdout.write(text),
|
|
358
405
|
writeErr: (text) => runtime.stderr.write(text),
|
|
@@ -369,7 +416,8 @@ function buildProgram(runtime) {
|
|
|
369
416
|
.option("--output <file>", "Output file path for --binary. Use - for stdout")
|
|
370
417
|
.option("--metadata", "Fetch metadata JSON instead of building a URL")
|
|
371
418
|
.option("--ims-token <token>", "IMS bearer token for metadata or binary requests")
|
|
372
|
-
.
|
|
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));
|
|
373
421
|
configureCommonDeliveryOptions(program.command("search").description("Search assets and optionally resolve the first result"))
|
|
374
422
|
.option("--bucket <bucket-or-url>", "Bucket host or full bucket URL")
|
|
375
423
|
.option("--ims-token <token>", "IMS bearer token")
|
|
@@ -401,12 +449,39 @@ Core commands:
|
|
|
401
449
|
- aemdm asset get <assetId>
|
|
402
450
|
- aemdm search
|
|
403
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
|
+
|
|
404
483
|
Important defaults:
|
|
405
|
-
-
|
|
406
|
-
- A standalone call like aemdm --bucket delivery-p123-e456.adobeaemcloud.com saves the default bucket to the local aemdm profile config.
|
|
407
|
-
- aemdm --ims-token <token> saves the IMS token to the profile config. Both can be saved together.
|
|
408
|
-
- Search auth comes from --ims-token/AEMDM_IMS_TOKEN/profile config and --api-key/AEMDM_API_KEY.
|
|
409
|
-
- asset get prints a URL by default.
|
|
484
|
+
- asset get prints a delivery URL by default.
|
|
410
485
|
- asset get --metadata prints full JSON metadata when authenticated, or basic public JSON metadata when no token is supplied.
|
|
411
486
|
- asset get --binary downloads the asset and requires --output.
|
|
412
487
|
- search --first-id prints one asset ID for piping.
|
|
@@ -419,6 +494,7 @@ Asset URL examples:
|
|
|
419
494
|
- aemdm asset get urn:aaid:aem:1234 --original --binary --output ./asset.bin
|
|
420
495
|
- aemdm asset get urn:aaid:aem:1234 --metadata
|
|
421
496
|
- aemdm asset get urn:aaid:aem:1234 --metadata --ims-token <token>
|
|
497
|
+
- aemdm asset get urn:aaid:aem:1234 --mime-type application/pdf
|
|
422
498
|
|
|
423
499
|
Search examples:
|
|
424
500
|
- aemdm search --text "hero banner"
|
|
@@ -444,8 +520,12 @@ LLM usage guidance:
|
|
|
444
520
|
- Use search when you need to discover an asset by metadata or text.
|
|
445
521
|
- Prefer --first-id or --ids-only when another CLI call needs asset IDs.
|
|
446
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.
|
|
447
524
|
- Prefer --first-metadata when the user wants the resolved asset metadata after search.
|
|
448
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
|
|
449
529
|
`;
|
|
450
530
|
}
|
|
451
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,7 +41,7 @@
|
|
|
41
41
|
"node": ">=20"
|
|
42
42
|
},
|
|
43
43
|
"dependencies": {
|
|
44
|
-
"aemdm": "^0.4.
|
|
44
|
+
"aemdm": "^0.4.1",
|
|
45
45
|
"commander": "^14.0.1",
|
|
46
46
|
"zod": "^4.1.12"
|
|
47
47
|
},
|