node-autotask 0.39.2 → 0.39.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/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ## [0.39.3] - 2026-10-30
11
+
12
+ Patch: standalone fixes (#263, #264, #265, #266, #306 part a). No capability-plan change.
13
+
14
+ ### Fixed
15
+ - **#264:** `credentialShapeProblem` now reports an interior line feed (`'line feed'`), matching its "interior CR/LF always reported" doc; previously an LF-laden credential reached fetch and surfaced as an opaque `NETWORK_ERROR`.
16
+ - **#265:** `createIfNotExists` treats a dedup match with an all-digit string id (above 2^53) as existing, and the create dry-run `parent-exists` check accepts a string-id parent; both go through `parseIdentifier`.
17
+ - **#263:** a mutation sent with `idempotent: true` (for example `client.http.request`) now voids cached reads like any other write. `idempotent` governs retry only; the internal `/query`, `/query/count` and `/query/next` read POSTs still skip invalidation.
18
+ - **#306 (a):** the picklist-unavailable note now names the resource (`... unavailable for tickets.status (see reasons)`), matching the `<resource>.<field>` `reasons` keys; the `resolveCompositeNames` catch branch is covered by a test.
19
+
20
+ ### Changed
21
+ - **#266 / #306 (a):** docs only. Pagination module headers now state that same-origin cursors are used and cross-origin cursors are refused with `ResponseRejectedError` (issue #54); the API.md note on id 0 is reworded as a node rule, not a vendor claim.
22
+
8
23
  ## [0.39.2] - 2026-10-30
9
24
 
10
25
  Patch: follow-ups to the 0.39.0 / 0.39.1 label work (#302, #303, #304). The plan hash is unchanged (`9bb87de7...`); no capability-plan change, so the MCP server needs no re-pin.
package/README.md CHANGED
@@ -120,7 +120,7 @@ code `INVALID_CREDENTIAL_SHAPE`) **before any request is built**. The three cano
120
120
  `AUTOTASK_API_INTEGRATION_CODE` and `AUTOTASK_USER` are read as fall-backs, canonical first.
121
121
 
122
122
  **What the SDK refuses at construction.** `apiIntegrationCode`, `userName`, `secret` and
123
- `impersonationResourceId` reject a value with a surrounding quote pair or an interior CR (and refuse
123
+ `impersonationResourceId` reject a value with a surrounding quote pair or an interior CR or LF (and refuse
124
124
  whitespace-only blank values exactly as before); padding-only whitespace is still trimmed as it
125
125
  always was. The same gate runs at the wire boundary, so a value that reaches the transport by any
126
126
  other route is refused before the request is sent. Errors are value-free: they name the field and
@@ -125,7 +125,7 @@ import {
125
125
  VersionInformationResource,
126
126
  VersionResource,
127
127
  ZoneInformationResource
128
- } from "./chunk-GSGP2B4I.js";
128
+ } from "./chunk-K6RZDRWX.js";
129
129
  import {
130
130
  AutotaskConfigError,
131
131
  BillingCodesResource,
@@ -141,7 +141,7 @@ import {
141
141
  TimeEntriesResource,
142
142
  resolveConfig,
143
143
  runWithSignal
144
- } from "./chunk-UNOQESFU.js";
144
+ } from "./chunk-GSMFRPYB.js";
145
145
 
146
146
  // src/client.ts
147
147
  var AutotaskClient = class {
@@ -1095,6 +1095,7 @@ function credentialShapeProblem(value, options = {}) {
1095
1095
  return "single- or double-quote surrounding the value";
1096
1096
  }
1097
1097
  if (value.includes("\r")) return "carriage return";
1098
+ if (value.includes("\n")) return "line feed";
1098
1099
  return void 0;
1099
1100
  }
1100
1101
  var CREDENTIAL_ENV_LOAD_ACTION = "value appears shell-quoted or line-break contaminated \u2014 check how your env file was loaded (single-quoted values must be shell-sourced, not parsed by a quote-preserving loader)";
@@ -17469,7 +17470,7 @@ var HttpClient = class {
17469
17470
  }
17470
17471
  /** A real write (even a failed one — it may have partly applied) voids cached reads. */
17471
17472
  invalidateAfterWrite(opts) {
17472
- if (opts.method === "GET" || opts.idempotent === true) return;
17473
+ if (opts.method === "GET" || opts.idempotent === true && /\/query(\/|\?|$)/.test(opts.path)) return;
17473
17474
  _optionalChain([this, 'access', _120 => _120.readCache, 'optionalAccess', _121 => _121.clear, 'call', _122 => _122()]);
17474
17475
  this.latestCountCache.clear();
17475
17476
  const nameOp = typeof opts.operation === "string" ? opts.operation : void 0;
@@ -20281,9 +20282,9 @@ var MutationBase = class extends MetaBase {
20281
20282
  const first = matches[0];
20282
20283
  if (first !== void 0) {
20283
20284
  const firstId = first.id;
20284
- if (typeof firstId === "number") {
20285
+ if (isIdentifierCandidate(firstId)) {
20285
20286
  existing = first;
20286
- existingId = firstId;
20287
+ existingId = parseIdentifier(firstId, "id");
20287
20288
  }
20288
20289
  }
20289
20290
  }
@@ -20382,9 +20383,13 @@ var MutationBase = class extends MetaBase {
20382
20383
  );
20383
20384
  }
20384
20385
  let parent = null;
20385
- if (typeof parentId === "number" && Number.isInteger(parentId) && parentId >= 0) {
20386
+ if (isIdentifierCandidate(parentId)) {
20386
20387
  try {
20387
- parent = await this.fetchRecordRaw(parentPath, parentId, true);
20388
+ parent = await this.fetchRecordRaw(
20389
+ parentPath,
20390
+ parseIdentifier(parentId, "parentId"),
20391
+ true
20392
+ );
20388
20393
  } catch (err) {
20389
20394
  if (!(err instanceof NotFoundError)) throw err;
20390
20395
  }
@@ -20877,7 +20882,7 @@ function readNamesOpt(value, where) {
20877
20882
  }
20878
20883
  return value;
20879
20884
  }
20880
- async function labelRows(client, resourceKey, rows) {
20885
+ async function labelRows(client, resourceKey, rows, resourceKeyedReasons = false) {
20881
20886
  const keys = /* @__PURE__ */ new Set();
20882
20887
  for (const row of rows) for (const k of Object.keys(row)) keys.add(k);
20883
20888
  if (keys.size === 0) return { rows: [...rows] };
@@ -20944,7 +20949,7 @@ async function labelRows(client, resourceKey, rows) {
20944
20949
  if (capped === 0 && unresolved.length === 0 && catalogError === void 0) return { rows: out };
20945
20950
  const parts = [];
20946
20951
  if (capped > 0) parts.push(`${capped} id(s) left unlabelled (their *Name is null): the per-call cap of ${DEFAULT_MAX_NAME_READS} uncached name reads was hit \u2014 names already read are cached, so repeating or narrowing the call labels more`);
20947
- if (unresolved.length > 0) parts.push(`picklist label(s) unavailable for ${unresolved.join(", ")} (see reasons)`);
20952
+ if (unresolved.length > 0) parts.push(`picklist label(s) unavailable for ${unresolved.map((f) => resourceKeyedReasons ? `${resourceKey}.${f}` : f).join(", ")} (see reasons)`);
20948
20953
  if (catalogError !== void 0) {
20949
20954
  parts.push(
20950
20955
  `the ${resourceKey} field catalog read failed (${catalogError.code}), so picklist labels are unavailable for this call, not absent: ` + (unavailable.length > 0 ? `the *Label is null for ${unavailable.join(", ")}` : "no *Label sibling was added (the picklist fields are unknown until a catalog read succeeds)") + " \u2014 retry the call to label them"
@@ -20971,7 +20976,7 @@ async function labelFetchResults(client, result) {
20971
20976
  const reasons = {};
20972
20977
  const catalogErrors = {};
20973
20978
  for (const [resource, indices] of byResource) {
20974
- const labelled = await labelRows(client, resource, indices.map((i) => results[i].value));
20979
+ const labelled = await labelRows(client, resource, indices.map((i) => results[i].value), true);
20975
20980
  indices.forEach((idx, j) => {
20976
20981
  results[idx] = { ...results[idx], value: labelled.rows[j] };
20977
20982
  });