@hasna/shortlinks 0.2.1 → 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.
package/dist/cli/index.js CHANGED
@@ -2894,7 +2894,7 @@ async function upsertCloudflareDnsRecord(options) {
2894
2894
  return { id: created.id, action: "created" };
2895
2895
  }
2896
2896
 
2897
- // node_modules/.pnpm/@hasna+events@0.1.13/node_modules/@hasna/events/dist/commander.js
2897
+ // node_modules/@hasna/events/dist/commander.js
2898
2898
  import { chmod, mkdir, readFile, rename, writeFile } from "fs/promises";
2899
2899
  import { existsSync as existsSync3 } from "fs";
2900
2900
  import { homedir as homedir2 } from "os";
@@ -2911,83 +2911,29 @@ function getPathValue(input, path) {
2911
2911
  return;
2912
2912
  }, input);
2913
2913
  }
2914
- function getFieldValues(input, path) {
2915
- const values = [];
2916
- const push = (value) => {
2917
- if (!values.some((item) => Object.is(item, value)))
2918
- values.push(value);
2919
- };
2920
- if (path.includes(".") && path in input)
2921
- push(input[path]);
2922
- const nestedValue = getPathValue(input, path);
2923
- if (nestedValue !== undefined || !path.includes("."))
2924
- push(nestedValue);
2925
- return values;
2926
- }
2927
- function wildcardToRegExp(pattern, options = {}) {
2928
- let body = "";
2929
- for (let index = 0;index < pattern.length; index += 1) {
2930
- const char = pattern[index];
2931
- if (char === "*") {
2932
- if (pattern[index + 1] === "*") {
2933
- body += ".*";
2934
- index += 1;
2935
- } else {
2936
- body += options.segmentSafe ? "[^/]*" : ".*";
2937
- }
2938
- } else {
2939
- body += char.replace(/[|\\{}()[\]^$+?.]/g, "\\$&");
2940
- }
2941
- }
2942
- return new RegExp(`^${body}$`);
2914
+ function wildcardToRegExp(pattern) {
2915
+ const escaped = pattern.replace(/[|\\{}()[\]^$+?.]/g, "\\$&").replace(/\*/g, ".*");
2916
+ return new RegExp(`^${escaped}$`);
2943
2917
  }
2944
- function matchString(value, matcher, options = {}) {
2918
+ function matchString(value, matcher) {
2945
2919
  if (matcher === undefined)
2946
2920
  return true;
2947
2921
  if (value === undefined)
2948
2922
  return false;
2949
2923
  const matchers = Array.isArray(matcher) ? matcher : [matcher];
2950
- return matchers.some((item) => wildcardToRegExp(item, options).test(value));
2924
+ return matchers.some((item) => wildcardToRegExp(item).test(value));
2951
2925
  }
2952
2926
  function matchRecord(input, matcher) {
2953
2927
  if (!matcher)
2954
2928
  return true;
2955
2929
  return Object.entries(matcher).every(([path, expected]) => {
2956
- const actualValues = getFieldValues(input, path);
2957
- return matchField(actualValues, expected, path);
2930
+ const actual = getPathValue(input, path);
2931
+ if (typeof expected === "string" || Array.isArray(expected)) {
2932
+ return matchString(actual === undefined ? undefined : String(actual), expected);
2933
+ }
2934
+ return actual === expected;
2958
2935
  });
2959
2936
  }
2960
- function matchField(actualValues, expected, path) {
2961
- if (isNegativeMatcher(expected)) {
2962
- return !actualValues.some((actual) => matchPositiveField(actual, expected.not, path));
2963
- }
2964
- return actualValues.some((actual) => matchPositiveField(actual, expected, path));
2965
- }
2966
- function matchPositiveField(actual, expected, path) {
2967
- if (typeof expected === "string" || Array.isArray(expected)) {
2968
- return stringCandidates(actual).some((candidate) => matchString(candidate, expected, {
2969
- segmentSafe: path.endsWith("_path") || path.endsWith(".path")
2970
- }));
2971
- }
2972
- if (Array.isArray(actual)) {
2973
- return actual.some((item) => item === expected);
2974
- }
2975
- return actual === expected;
2976
- }
2977
- function stringCandidates(actual) {
2978
- if (actual === undefined)
2979
- return [];
2980
- if (Array.isArray(actual)) {
2981
- return actual.flatMap((item) => isPrimitiveFieldValue(item) ? [String(item)] : []);
2982
- }
2983
- return [String(actual)];
2984
- }
2985
- function isPrimitiveFieldValue(value) {
2986
- return value === null || typeof value === "string" || typeof value === "number" || typeof value === "boolean";
2987
- }
2988
- function isNegativeMatcher(value) {
2989
- return Boolean(value && typeof value === "object" && !Array.isArray(value) && "not" in value);
2990
- }
2991
2937
  function eventMatchesFilter(event, filter) {
2992
2938
  return matchString(event.source, filter.source) && matchString(event.type, filter.type) && matchString(event.subject, filter.subject) && matchString(event.severity, filter.severity) && matchRecord(event.data, filter.data) && matchRecord(event.metadata, filter.metadata);
2993
2939
  }
@@ -3003,13 +2949,6 @@ var HASNA_EVENTS_HOME_ENV = "HASNA_EVENTS_HOME";
3003
2949
  function getEventsDataDir(override) {
3004
2950
  return override || process.env[HASNA_EVENTS_DIR_ENV] || process.env[HASNA_EVENTS_HOME_ENV] || join4(homedir2(), ".hasna", "events");
3005
2951
  }
3006
- function getActiveEventsDirEnv() {
3007
- if (process.env[HASNA_EVENTS_DIR_ENV])
3008
- return HASNA_EVENTS_DIR_ENV;
3009
- if (process.env[HASNA_EVENTS_HOME_ENV])
3010
- return HASNA_EVENTS_HOME_ENV;
3011
- return null;
3012
- }
3013
2952
 
3014
2953
  class JsonEventsStore {
3015
2954
  dataDir;
@@ -3122,52 +3061,6 @@ class JsonEventsStore {
3122
3061
  });
3123
3062
  }
3124
3063
  }
3125
- async function getEventsStatus(dataDir) {
3126
- const store = new JsonEventsStore(dataDir);
3127
- await store.init();
3128
- const [channels, events, deliveries] = await Promise.all([
3129
- store.listChannels(),
3130
- store.listEvents(),
3131
- store.listDeliveries()
3132
- ]);
3133
- const transports = channels.reduce((counts, channel) => {
3134
- counts[channel.transport] = (counts[channel.transport] ?? 0) + 1;
3135
- return counts;
3136
- }, {});
3137
- return {
3138
- service: "events",
3139
- schemaVersion: "1.0",
3140
- dataDir: store.dataDir,
3141
- env: {
3142
- primary: HASNA_EVENTS_DIR_ENV,
3143
- fallback: HASNA_EVENTS_HOME_ENV,
3144
- active: getActiveEventsDirEnv()
3145
- },
3146
- files: {
3147
- channels: statusFile(store.dataDir, "channels.json", channels.length),
3148
- events: statusFile(store.dataDir, "events.json", events.length),
3149
- deliveries: statusFile(store.dataDir, "deliveries.json", deliveries.length)
3150
- },
3151
- counts: {
3152
- channels: channels.length,
3153
- enabledChannels: channels.filter((channel) => channel.enabled).length,
3154
- disabledChannels: channels.filter((channel) => !channel.enabled).length,
3155
- events: events.length,
3156
- deliveries: deliveries.length
3157
- },
3158
- transports,
3159
- safety: {
3160
- includesEventPayloads: false,
3161
- includesWebhookSecrets: false,
3162
- listOutputsRedactSecrets: true,
3163
- statusOutputIsMetadataOnly: true
3164
- }
3165
- };
3166
- }
3167
- function statusFile(dataDir, fileName, records) {
3168
- const path = join4(dataDir, fileName);
3169
- return { path, exists: existsSync3(path), records };
3170
- }
3171
3064
  var DEFAULT_SIGNATURE_TOLERANCE_MS = 5 * 60 * 1000;
3172
3065
  function buildSignatureBase(timestamp, body) {
3173
3066
  return `${timestamp}.${body}`;
@@ -3393,7 +3286,7 @@ class EventsClient {
3393
3286
  }
3394
3287
  return deliveries;
3395
3288
  }
3396
- async matchChannel(id, input = {}) {
3289
+ async testChannel(id, input = {}) {
3397
3290
  const channel = await this.store.getChannel(id);
3398
3291
  if (!channel)
3399
3292
  throw new Error(`Channel not found: ${id}`);
@@ -3410,34 +3303,6 @@ class EventsClient {
3410
3303
  time: input.time,
3411
3304
  id: input.id
3412
3305
  });
3413
- const matched = channelMatchesEvent(channel, event);
3414
- return {
3415
- channelId: channel.id,
3416
- matched,
3417
- event,
3418
- filters: channel.filters,
3419
- reason: matched ? undefined : channel.enabled ? "event did not match channel filters" : "channel is disabled"
3420
- };
3421
- }
3422
- async testChannel(id, input = {}, options = {}) {
3423
- const channel = await this.store.getChannel(id);
3424
- if (!channel)
3425
- throw new Error(`Channel not found: ${id}`);
3426
- const match = await this.matchChannel(id, input);
3427
- const event = match.event;
3428
- if (options.honorFilters && !match.matched) {
3429
- const timestamp = new Date().toISOString();
3430
- const result2 = createDeliveryResult(event, channel, [{
3431
- attempt: 1,
3432
- status: "skipped",
3433
- startedAt: timestamp,
3434
- completedAt: timestamp,
3435
- error: match.reason
3436
- }]);
3437
- result2.metadata = { reason: "filter_mismatch" };
3438
- await this.store.appendDelivery(result2);
3439
- return result2;
3440
- }
3441
3306
  const eventForChannel = await this.applyRedaction(event, channel);
3442
3307
  const result = await this.deliverWithRetry(eventForChannel, channel);
3443
3308
  await this.store.appendDelivery(result);
@@ -3548,76 +3413,6 @@ function normalizeRetryPolicy(policy) {
3548
3413
  multiplier: Math.max(1, policy?.multiplier ?? 2)
3549
3414
  };
3550
3415
  }
3551
- function parseFieldMatchers(values, label, typed = false) {
3552
- if (!values?.length)
3553
- return;
3554
- const result = {};
3555
- for (const value of values) {
3556
- const parsed = parseMatcherExpression(value, label);
3557
- const path = parsed.path;
3558
- if (path in result)
3559
- throw new Error(`Duplicate ${label} filter path: ${path}`);
3560
- const matcherValue = typed ? parseTypedMatcherValue(parsed.rawValue, label) : parsed.rawValue;
3561
- result[path] = parsed.negated ? { not: matcherValue } : matcherValue;
3562
- }
3563
- return result;
3564
- }
3565
- function parseFilterOptions(options) {
3566
- const filter2 = {};
3567
- if (options.source)
3568
- filter2.source = options.source;
3569
- if (options.type)
3570
- filter2.type = options.type;
3571
- if (options.subject)
3572
- filter2.subject = options.subject;
3573
- if (options.severity)
3574
- filter2.severity = options.severity;
3575
- const data = mergeMatchers(parseFieldMatchers(options.data, "data"), parseFieldMatchers(options.dataJson, "data-json", true));
3576
- const metadata = mergeMatchers(parseFieldMatchers(options.metadata, "metadata"), parseFieldMatchers(options.metadataJson, "metadata-json", true));
3577
- if (Object.keys(data).length > 0)
3578
- filter2.data = data;
3579
- if (Object.keys(metadata).length > 0)
3580
- filter2.metadata = metadata;
3581
- return Object.keys(filter2).length > 0 ? [filter2] : undefined;
3582
- }
3583
- function mergeMatchers(...records) {
3584
- const result = {};
3585
- for (const record of records) {
3586
- if (!record)
3587
- continue;
3588
- for (const [path, value] of Object.entries(record)) {
3589
- if (path in result)
3590
- throw new Error(`Duplicate filter path: ${path}`);
3591
- result[path] = value;
3592
- }
3593
- }
3594
- return result;
3595
- }
3596
- function parseTypedMatcherValue(value, label) {
3597
- const parsed = JSON.parse(value);
3598
- if (parsed === null || typeof parsed === "string" || typeof parsed === "number" || typeof parsed === "boolean" || Array.isArray(parsed) && parsed.every((item) => typeof item === "string")) {
3599
- return parsed;
3600
- }
3601
- throw new Error(`${label} filter JSON values must be string, string[], number, boolean, or null`);
3602
- }
3603
- function parseMatcherExpression(value, label) {
3604
- const negativeSeparator = value.indexOf("!=");
3605
- if (negativeSeparator > 0) {
3606
- return {
3607
- path: value.slice(0, negativeSeparator),
3608
- rawValue: value.slice(negativeSeparator + 2),
3609
- negated: true
3610
- };
3611
- }
3612
- const separator = value.indexOf("=");
3613
- if (separator <= 0)
3614
- throw new Error(`Invalid ${label} filter, expected path=value or path!=value: ${value}`);
3615
- return {
3616
- path: value.slice(0, separator),
3617
- rawValue: value.slice(separator + 1),
3618
- negated: false
3619
- };
3620
- }
3621
3416
  function parseJsonObject2(value, fallback) {
3622
3417
  if (!value)
3623
3418
  return fallback;
@@ -3639,6 +3434,18 @@ function parseHeaders(values) {
3639
3434
  }
3640
3435
  return headers;
3641
3436
  }
3437
+ function parseFilter(options) {
3438
+ const filter2 = {};
3439
+ if (options.source)
3440
+ filter2.source = options.source;
3441
+ if (options.type)
3442
+ filter2.type = options.type;
3443
+ if (options.subject)
3444
+ filter2.subject = options.subject;
3445
+ if (options.severity)
3446
+ filter2.severity = options.severity;
3447
+ return Object.keys(filter2).length > 0 ? [filter2] : undefined;
3448
+ }
3642
3449
  function createClient(options) {
3643
3450
  if (options.createClient)
3644
3451
  return options.createClient();
@@ -3656,16 +3463,16 @@ function hasJsonOption(options) {
3656
3463
  function wantsJson(actionOptions, command) {
3657
3464
  return hasJsonOption(actionOptions) || hasJsonOption(command);
3658
3465
  }
3659
- function registerChannelCommands(program, options) {
3660
- const channels = program.command(options.channelsCommandName ?? "channels").description("Manage Hasna event channels");
3661
- channels.command("add").description("Add or replace a channel").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--data <path=value...>", "Event data field filter; string values, path!=value negatives, array-member matching, dot paths, * segment wildcard, ** recursive wildcard", collectValues, []).option("--metadata <path=value...>", "Event metadata field filter; string values, path!=value negatives, array-member matching, dot paths, * segment wildcard, ** recursive wildcard", collectValues, []).option("--data-json <path=json...>", "Event data field filter with typed JSON value; path!=json negatives supported", collectValues, []).option("--metadata-json <path=json...>", "Event metadata field filter with typed JSON value; path!=json negatives supported", collectValues, []).option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
3466
+ function registerWebhookCommands(program, options) {
3467
+ const webhooks = program.command(options.webhooksCommandName ?? "webhooks").description("Manage Hasna event webhook subscriptions");
3468
+ webhooks.command("add").description("Add or replace a webhook or command subscription").argument("<target>", "Webhook URL or command binary").requiredOption("--id <id>", "Subscription/channel identifier").option("--transport <kind>", "Transport kind: webhook or command", "webhook").option("--name <name>", "Display name").option("--type <pattern>", "Event type filter, e.g. todos.task.*").option("--source <pattern>", "Event source filter").option("--subject <pattern>", "Event subject filter").option("--severity <pattern>", "Event severity filter").option("--secret <secret>", "Webhook HMAC secret").option("--header <name=value...>", "Webhook header", collectValues, []).option("--arg <arg...>", "Command argument", collectValues, []).option("--timeout-ms <ms>", "Transport timeout in milliseconds", parseNumber).option("--retry-attempts <n>", "Maximum delivery attempts", parseNumber).option("--retry-backoff-ms <ms>", "Initial retry backoff in milliseconds", parseNumber).option("--redact <path...>", "Event field path to redact before delivery", collectValues, []).option("--disabled", "Create channel disabled", false).option("-j, --json", "Print JSON output", false).action(async (target, actionOptions, command) => {
3662
3469
  const timestamp = new Date().toISOString();
3663
3470
  const channel = {
3664
3471
  id: actionOptions.id,
3665
3472
  name: actionOptions.name,
3666
3473
  enabled: !actionOptions.disabled,
3667
3474
  transport: actionOptions.transport,
3668
- filters: parseFilterOptions(actionOptions),
3475
+ filters: parseFilter(actionOptions),
3669
3476
  retry: actionOptions.retryAttempts || actionOptions.retryBackoffMs ? { maxAttempts: actionOptions.retryAttempts, backoffMs: actionOptions.retryBackoffMs } : undefined,
3670
3477
  redact: actionOptions.redact?.length ? { paths: actionOptions.redact } : undefined,
3671
3478
  createdAt: timestamp,
@@ -3681,51 +3488,35 @@ function registerChannelCommands(program, options) {
3681
3488
  const saved = await createClient(options).addChannel(channel);
3682
3489
  print(sanitizeChannelForOutput(saved), wantsJson(actionOptions, command), `Added ${saved.transport} channel ${saved.id}`);
3683
3490
  });
3684
- channels.command("list").description("List configured channels").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
3685
- const channels2 = await createClient(options).listChannels();
3491
+ webhooks.command("list").description("List configured subscriptions").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
3492
+ const channels = await createClient(options).listChannels();
3686
3493
  if (wantsJson(actionOptions, command)) {
3687
- console.log(JSON.stringify(sanitizeChannelsForOutput(channels2), null, 2));
3494
+ console.log(JSON.stringify(sanitizeChannelsForOutput(channels), null, 2));
3688
3495
  return;
3689
3496
  }
3690
- if (!channels2.length) {
3497
+ if (!channels.length) {
3691
3498
  console.log("No channels configured.");
3692
3499
  return;
3693
3500
  }
3694
- for (const channel of channels2) {
3501
+ for (const channel of channels) {
3695
3502
  console.log(`${channel.id} ${channel.enabled ? "enabled" : "disabled"} ${channel.transport} ${channel.webhook?.url ?? channel.command?.command ?? channel.transport}`);
3696
3503
  }
3697
3504
  });
3698
- channels.command("status").description("Show events channel storage status").option("-j, --json", "Print JSON output", false).action(async (actionOptions, command) => {
3699
- const status = await getEventsStatus(options.dataDir);
3700
- print(status, wantsJson(actionOptions, command), `events dataDir: ${status.dataDir}`);
3701
- });
3702
- channels.command("remove").description("Remove a channel").argument("<id>", "Channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3505
+ webhooks.command("remove").description("Remove a subscription").argument("<id>", "Subscription/channel identifier").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3703
3506
  const removed = await createClient(options).removeChannel(id);
3704
3507
  print({ removed }, wantsJson(actionOptions, command), removed ? `Removed ${id}` : `Channel not found: ${id}`);
3705
3508
  });
3706
- channels.command("test").description("Send a test event to one channel").argument("<id>", "Channel identifier").option("--source <source>", "Event source override").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("--honor-filters", "Skip delivery when the sample event does not match channel filters", false).option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3509
+ webhooks.command("test").description("Send a test event to one subscription").argument("<id>", "Subscription/channel identifier").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events test delivery").option("--data <json>", "Event data JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3707
3510
  const result = await createClient(options).testChannel(id, {
3708
- source: actionOptions.source ?? options.source,
3709
- type: actionOptions.type,
3710
- subject: actionOptions.subject ?? id,
3711
- message: actionOptions.message,
3712
- data: parseJsonObject2(actionOptions.data, { test: true }),
3713
- metadata: parseJsonObject2(actionOptions.metadata, {})
3714
- }, { honorFilters: actionOptions.honorFilters });
3715
- print(result, wantsJson(actionOptions, command), `${result.status}: ${result.channelId}`);
3716
- });
3717
- channels.command("match").description("Check whether a sample event matches one channel without delivering").argument("<id>", "Channel identifier").option("--source <source>", "Event source override").option("--type <type>", "Event type", "events.test").option("--subject <subject>", "Event subject").option("--message <message>", "Event message", "Hasna events match preview").option("--data <json>", "Event data JSON object").option("--metadata <json>", "Event metadata JSON object").option("-j, --json", "Print JSON output", false).action(async (id, actionOptions, command) => {
3718
- const result = await createClient(options).matchChannel(id, {
3719
- source: actionOptions.source ?? options.source,
3511
+ source: options.source,
3720
3512
  type: actionOptions.type,
3721
3513
  subject: actionOptions.subject ?? id,
3722
3514
  message: actionOptions.message,
3723
- data: parseJsonObject2(actionOptions.data, { test: true }),
3724
- metadata: parseJsonObject2(actionOptions.metadata, {})
3515
+ data: parseJsonObject2(actionOptions.data, { test: true })
3725
3516
  });
3726
- print(result, wantsJson(actionOptions, command), `${result.matched ? "matched" : "skipped"}: ${result.channelId}`);
3517
+ print(result, wantsJson(actionOptions, command), `${result.status}: ${result.channelId}`);
3727
3518
  });
3728
- return channels;
3519
+ return webhooks;
3729
3520
  }
3730
3521
  function registerEventCommands(program, options) {
3731
3522
  const events = program.command(options.eventsCommandName ?? "events").description("Emit, list, and replay Hasna events");
@@ -3773,7 +3564,7 @@ function registerEventCommands(program, options) {
3773
3564
  return events;
3774
3565
  }
3775
3566
  function registerEventsCommands(program, options) {
3776
- registerChannelCommands(program, options);
3567
+ registerWebhookCommands(program, options);
3777
3568
  registerEventCommands(program, options);
3778
3569
  }
3779
3570
  function parseNumber(value) {
@@ -10761,7 +10552,7 @@ class CloudShortlinksStore {
10761
10552
  const domain = await this.getDomain(hostnameOrId);
10762
10553
  if (!domain)
10763
10554
  throw new Error("Domain not found.");
10764
- await this.client.delete("domains", domain.hostname);
10555
+ await this.transport.del(`/domains/${enc(domain.hostname)}`);
10765
10556
  return domain;
10766
10557
  }
10767
10558
  async createLink(input) {
@@ -10815,7 +10606,7 @@ class CloudShortlinksStore {
10815
10606
  const link = maybeSlug ? await this.getLink(domainOrSlug, maybeSlug) : await this.getLink(domainOrSlug);
10816
10607
  if (!link)
10817
10608
  throw new Error("Link not found.");
10818
- await this.client.delete("links", link.slug, maybeSlug ? { query: { domain: domainOrSlug } } : {});
10609
+ await this.transport.del(`/links/${enc(link.slug)}`, undefined, maybeSlug ? { query: { domain: domainOrSlug } } : {});
10819
10610
  return link;
10820
10611
  }
10821
10612
  async recordClick(_link, _input = {}) {
package/dist/index.js CHANGED
@@ -7659,7 +7659,7 @@ class CloudShortlinksStore {
7659
7659
  const domain = await this.getDomain(hostnameOrId);
7660
7660
  if (!domain)
7661
7661
  throw new Error("Domain not found.");
7662
- await this.client.delete("domains", domain.hostname);
7662
+ await this.transport.del(`/domains/${enc(domain.hostname)}`);
7663
7663
  return domain;
7664
7664
  }
7665
7665
  async createLink(input) {
@@ -7713,7 +7713,7 @@ class CloudShortlinksStore {
7713
7713
  const link = maybeSlug ? await this.getLink(domainOrSlug, maybeSlug) : await this.getLink(domainOrSlug);
7714
7714
  if (!link)
7715
7715
  throw new Error("Link not found.");
7716
- await this.client.delete("links", link.slug, maybeSlug ? { query: { domain: domainOrSlug } } : {});
7716
+ await this.transport.del(`/links/${enc(link.slug)}`, undefined, maybeSlug ? { query: { domain: domainOrSlug } } : {});
7717
7717
  return link;
7718
7718
  }
7719
7719
  async recordClick(_link, _input = {}) {
package/dist/mcp/index.js CHANGED
@@ -6501,7 +6501,7 @@ class CloudShortlinksStore {
6501
6501
  const domain = await this.getDomain(hostnameOrId);
6502
6502
  if (!domain)
6503
6503
  throw new Error("Domain not found.");
6504
- await this.client.delete("domains", domain.hostname);
6504
+ await this.transport.del(`/domains/${enc(domain.hostname)}`);
6505
6505
  return domain;
6506
6506
  }
6507
6507
  async createLink(input) {
@@ -6555,7 +6555,7 @@ class CloudShortlinksStore {
6555
6555
  const link = maybeSlug ? await this.getLink(domainOrSlug, maybeSlug) : await this.getLink(domainOrSlug);
6556
6556
  if (!link)
6557
6557
  throw new Error("Link not found.");
6558
- await this.client.delete("links", link.slug, maybeSlug ? { query: { domain: domainOrSlug } } : {});
6558
+ await this.transport.del(`/links/${enc(link.slug)}`, undefined, maybeSlug ? { query: { domain: domainOrSlug } } : {});
6559
6559
  return link;
6560
6560
  }
6561
6561
  async recordClick(_link, _input = {}) {