aemdm 0.1.3 → 0.2.3

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.
Files changed (3) hide show
  1. package/README.md +7 -24
  2. package/dist/cli.js +41 -4
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -189,36 +189,19 @@ aemdm search --raw-query @./query.json
189
189
 
190
190
  ## Publishing
191
191
 
192
- Before publishing a new release, verify the package contents and publish from the repo root:
192
+ The repository includes a `/release` skill for Claude Code that automates the full release process:
193
193
 
194
- ```bash
195
- npm test
196
- npm run pack:check
197
- npm publish
198
194
  ```
199
-
200
- `prepack` builds `dist/`, and `prepublishOnly` runs the test suite during `npm publish`.
201
-
202
- ### Automated npm publish from GitHub
203
-
204
- The repository includes a GitHub Actions workflow that publishes to npm when you push a version tag like `v0.1.3` or publish a GitHub release for that tag.
205
-
206
- Required setup:
207
-
208
- ```bash
209
- NPM_TOKEN
195
+ /release patch # 0.2.1 → 0.2.2
196
+ /release minor # 0.2.1 0.3.0
197
+ /release major # 0.2.1 → 1.0.0
210
198
  ```
211
199
 
212
- Add `NPM_TOKEN` as a GitHub repository secret with permission to publish the `aemdm` package on npm.
213
-
214
- Release flow:
200
+ The skill bumps the version across all files, builds, tests, commits, pushes, creates a git tag, and creates a GitHub release.
215
201
 
216
- ```bash
217
- git tag v0.1.3
218
- git push origin v0.1.3
219
- ```
202
+ Publishing to npm is triggered automatically when a GitHub release is created. The workflow uses npm trusted publishing (OIDC) via the `npm` GitHub environment — no token secret is needed.
220
203
 
221
- The workflow verifies that the tag matches the `version` field in `package.json`, runs `lint`, `build`, and `test`, and then publishes the package.
204
+ The workflow verifies that the release tag matches the `version` field in `package.json`, runs `lint`, `build`, and `test`, and then publishes the package with provenance.
222
205
 
223
206
  ## References
224
207
 
package/dist/cli.js CHANGED
@@ -1,5 +1,6 @@
1
1
  #!/usr/bin/env node
2
- import { pathToFileURL } from "node:url";
2
+ import { fileURLToPath } from "node:url";
3
+ import { realpathSync } from "node:fs";
3
4
  import { Command, CommanderError, Option } from "commander";
4
5
  import { z } from "zod";
5
6
  import { CliError, request, requestJson, resolveBucket, resolveOptionalImsToken, resolveSearchAuth, } from "./lib/client.js";
@@ -7,6 +8,11 @@ import { readProfileConfig, writeProfileConfig, } from "./lib/config.js";
7
8
  import { buildAssetUrl, buildMetadataUrl, deliveryFormatSchema, resolveDimensions, } from "./lib/delivery.js";
8
9
  import { buildSearchRequest, getAssetIdFromHit, loadRawQuery, } from "./lib/search.js";
9
10
  import { formatSearchResults, writeBinaryOutput, writeJson, writeLine, } from "./lib/output.js";
11
+ function verbose(runtime, message) {
12
+ if (runtime.verbose) {
13
+ writeLine(runtime.stderr, `[verbose] ${message}`);
14
+ }
15
+ }
10
16
  const numberOption = (flagName) => (value) => {
11
17
  const parsed = Number(value);
12
18
  if (!Number.isInteger(parsed)) {
@@ -163,6 +169,17 @@ async function handleAssetGet(assetId, options, runtime) {
163
169
  const baseUrl = resolveBucket(parsed.bucket, runtime.env, profile.bucket);
164
170
  const imsToken = resolveOptionalImsToken(parsed.imsToken, runtime.env);
165
171
  const dimensions = resolveDimensions(parsed.size, parsed.width, parsed.height);
172
+ verbose(runtime, `bucket: ${baseUrl}`);
173
+ verbose(runtime, `asset: ${assetId}`);
174
+ if (imsToken)
175
+ verbose(runtime, `auth: IMS token provided`);
176
+ if (dimensions.width || dimensions.height) {
177
+ verbose(runtime, `dimensions: ${dimensions.width ?? "auto"}x${dimensions.height ?? "auto"}`);
178
+ }
179
+ if (parsed.format)
180
+ verbose(runtime, `format: ${parsed.format}`);
181
+ if (parsed.quality)
182
+ verbose(runtime, `quality: ${parsed.quality}`);
166
183
  if (parsed.metadata) {
167
184
  const metadata = imsToken
168
185
  ? await requestJson(buildMetadataUrl(baseUrl, assetId), {
@@ -213,6 +230,18 @@ async function handleSearch(options, runtime) {
213
230
  const { imsToken, apiKey } = resolveSearchAuth(parsed.imsToken, parsed.apiKey, runtime.env);
214
231
  const searchBody = await buildSearchBody(parsed);
215
232
  const searchUrl = `${baseUrl}/search`;
233
+ verbose(runtime, `bucket: ${baseUrl}`);
234
+ verbose(runtime, `search: POST ${searchUrl}`);
235
+ verbose(runtime, `api-key: ${apiKey}`);
236
+ verbose(runtime, `auth: IMS token provided`);
237
+ if (parsed.text)
238
+ verbose(runtime, `text: "${parsed.text}"`);
239
+ if (parsed.where.length > 0)
240
+ verbose(runtime, `where: ${parsed.where.join(", ")}`);
241
+ if (parsed.limit !== undefined)
242
+ verbose(runtime, `limit: ${parsed.limit}`);
243
+ if (parsed.rawQuery)
244
+ verbose(runtime, `raw-query: ${parsed.rawQuery}`);
216
245
  const response = await requestJson(searchUrl, {
217
246
  method: "POST",
218
247
  imsToken,
@@ -220,6 +249,9 @@ async function handleSearch(options, runtime) {
220
249
  jsonBody: searchBody,
221
250
  fetchImpl: runtime.fetchImpl,
222
251
  });
252
+ const resultCount = response.hits?.results?.length ?? 0;
253
+ const totalCount = response.search_metadata?.totalCount?.total;
254
+ verbose(runtime, `results: ${resultCount} returned${totalCount !== undefined ? ` (${totalCount} total)` : ""}`);
223
255
  if (parsed.json) {
224
256
  writeJson(runtime.stdout, response);
225
257
  return;
@@ -315,13 +347,17 @@ function buildProgram(runtime) {
315
347
  program
316
348
  .name("aemdm")
317
349
  .description("CLI for Adobe Dynamic Media with OpenAPI")
318
- .version("0.1.0")
350
+ .version("0.2.3")
319
351
  .showHelpAfterError()
352
+ .option("-v, --verbose", "Show additional diagnostic output")
320
353
  .configureOutput({
321
354
  writeOut: (text) => runtime.stdout.write(text),
322
355
  writeErr: (text) => runtime.stderr.write(text),
323
356
  })
324
- .exitOverride();
357
+ .exitOverride()
358
+ .hook("preAction", () => {
359
+ runtime.verbose = program.opts().verbose === true;
360
+ });
325
361
  configureCommonDeliveryOptions(program.command("asset").description("Asset operations"))
326
362
  .command("get <assetId>")
327
363
  .description("Build a delivery URL, fetch metadata, or download a binary for an asset")
@@ -442,6 +478,7 @@ export async function runCli(argv, runtimeOverrides = {}) {
442
478
  stdout: process.stdout,
443
479
  stderr: process.stderr,
444
480
  fetchImpl: fetch,
481
+ verbose: false,
445
482
  ...runtimeOverrides,
446
483
  };
447
484
  try {
@@ -470,7 +507,7 @@ export async function runCli(argv, runtimeOverrides = {}) {
470
507
  }
471
508
  }
472
509
  const executedDirectly = process.argv[1] !== undefined &&
473
- import.meta.url === pathToFileURL(process.argv[1]).href;
510
+ fileURLToPath(import.meta.url) === realpathSync(process.argv[1]);
474
511
  if (executedDirectly) {
475
512
  const exitCode = await runCli(process.argv.slice(2));
476
513
  process.exitCode = exitCode;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "aemdm",
3
- "version": "0.1.3",
3
+ "version": "0.2.3",
4
4
  "description": "CLI for Adobe Dynamic Media with OpenAPI",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Chris Pilsworth",