@hardfin/cli 0.1.1-dev.61 → 0.1.1-dev.63

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.
@@ -1,12 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="d29068e8-3e79-5da9-aa3a-0c5201101ca3")}catch(e){}}();
3
+ !function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="980cc947-6ea9-593a-bdbf-bc8ecfc40c65")}catch(e){}}();
4
4
  import { a as defineCommand, i as GLOBAL_FLAGS, r as ExitCode, t as toInvocation } from "./scrub-BZ0egWxC.js";
5
5
  import { n as toAnswer$1, r as toCompletion, t as PATH_VALUES } from "./completion-tree-DLC6ARLR.js";
6
6
  import { createRequire } from "node:module";
7
- import { Command, CommanderError, Option } from "commander";
7
+ import { Command, CommanderError, InvalidArgumentError, Option } from "commander";
8
8
  import { z } from "zod";
9
- import { accessSync, chmodSync, closeSync, constants, existsSync, mkdirSync, openAsBlob, openSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
9
+ import { accessSync, chmodSync, closeSync, constants, existsSync, mkdirSync, openAsBlob, openSync, readFileSync, readSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync, writeSync } from "node:fs";
10
10
  import { basename, delimiter, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
11
11
  import { parseEnv } from "node:util";
12
12
  import { fileURLToPath } from "node:url";
@@ -106,6 +106,7 @@ function toProgram(root, command, onRun, isSilent) {
106
106
  const option = new Option(`${short}--${flag.name}${value}`, flag.description);
107
107
  if (flag.negatable) program.addOption(new Option(`--no-${flag.name}`, `${flag.description}, turned off`));
108
108
  if (flag.repeatable) option.argParser(collect);
109
+ if (!flag.repeatable && flag.valueName) option.argParser(toOnce(flag.name));
109
110
  if (flag.defaultValue !== void 0) option.default(flag.defaultValue);
110
111
  program.addOption(option);
111
112
  }
@@ -139,6 +140,15 @@ function toArgumentList(value) {
139
140
  if (Array.isArray(value)) return value.map(String);
140
141
  return value === void 0 ? [] : [toText(value)];
141
142
  }
143
+ /** toOnce refuses a flag given a second time. */
144
+ function toOnce(name) {
145
+ let isGiven = false;
146
+ return (value) => {
147
+ if (isGiven) throw new InvalidArgumentError(`--${name} takes one value and is given more than once`);
148
+ isGiven = true;
149
+ return value;
150
+ };
151
+ }
142
152
  function collect(value, previous) {
143
153
  return [...previous ?? [], value];
144
154
  }
@@ -248,7 +258,7 @@ function toRelease(of) {
248
258
  //#endregion
249
259
  //#region src/config/settings.ts
250
260
  /** The API version this build was written against, sent on every request. */
251
- const API_VERSION = "2026-09-17";
261
+ const API_VERSION = "2026-10-12";
252
262
  /** The file a local build reads its overrides from, in the working directory. */
253
263
  const CONFIG_FILE = "config.local.json";
254
264
  const DEFAULT_API_URL = "https://api.hardfin.com/v2";
@@ -1490,7 +1500,8 @@ function toDescribed(flag) {
1490
1500
  schema: toFlagSchema(flag),
1491
1501
  sends: sent.queryName !== void 0 ? { query: sent.queryName } : sent.jsonPath !== void 0 ? { body: sent.jsonPath } : void 0,
1492
1502
  element: sent.element,
1493
- elementTypes: sent.elementTypes
1503
+ elementTypes: sent.elementTypes,
1504
+ elementLists: sent.elementLists
1494
1505
  };
1495
1506
  return Object.fromEntries(Object.entries(described).filter(([, value]) => value !== void 0 && value !== false));
1496
1507
  }
@@ -1554,21 +1565,58 @@ var InputFailure = class extends Error {
1554
1565
  this.name = "InputFailure";
1555
1566
  }
1556
1567
  };
1568
+ /** toStandardInput reads everything piped to the command, however slowly it arrives. */
1569
+ function toStandardInput() {
1570
+ const chunks = [];
1571
+ const chunk = Buffer.alloc(65536);
1572
+ const pause = new Int32Array(new SharedArrayBuffer(4));
1573
+ for (;;) {
1574
+ let size;
1575
+ try {
1576
+ size = readSync(0, chunk, 0, chunk.length, null);
1577
+ } catch (error) {
1578
+ const code = error.code;
1579
+ if (code === "EAGAIN") {
1580
+ Atomics.wait(pause, 0, 0, 5);
1581
+ continue;
1582
+ }
1583
+ if (code === "EOF") break;
1584
+ throw error;
1585
+ }
1586
+ if (size === 0) break;
1587
+ chunks.push(Buffer.from(chunk.subarray(0, size)));
1588
+ }
1589
+ return Buffer.concat(chunks).toString("utf8");
1590
+ }
1591
+ /** The deepest a body may nest, which is far past any the API takes and well short of what Node can copy. */
1592
+ const DEEPEST_BODY = 100;
1593
+ /** isTooDeep reports whether a value nests past the limit, without recursing into it. */
1594
+ function isTooDeep(value) {
1595
+ let level = [value];
1596
+ for (let depth = 0; level.length > 0; depth++) {
1597
+ if (depth > DEEPEST_BODY) return true;
1598
+ level = level.flatMap((entry) => typeof entry === "object" && entry !== null ? Object.values(entry) : []);
1599
+ }
1600
+ return false;
1601
+ }
1557
1602
  /** toJSONInput reads the JSON a command was given with --input, from a file or from standard input. */
1558
1603
  function toJSONInput(source) {
1559
1604
  const name = source === "-" ? "standard input" : source;
1560
1605
  let text;
1561
1606
  try {
1562
- text = readFileSync(source === "-" ? 0 : source, "utf8");
1607
+ text = source === "-" ? toStandardInput() : readFileSync(source, "utf8");
1563
1608
  } catch {
1564
1609
  return new InputFailure(`${name} cannot be read`);
1565
1610
  }
1566
1611
  if (text.trim() === "") return new InputFailure(`${name} is empty, and a body needs JSON`);
1612
+ let parsed;
1567
1613
  try {
1568
- return JSON.parse(text);
1614
+ parsed = JSON.parse(text);
1569
1615
  } catch {
1570
1616
  return new InputFailure(`${name} does not hold JSON`);
1571
1617
  }
1618
+ if (isTooDeep(parsed)) return new InputFailure(`${name} nests more than ${DEEPEST_BODY} levels deep, which no endpoint takes`);
1619
+ return parsed;
1572
1620
  }
1573
1621
  //#endregion
1574
1622
  //#region src/command/operation.ts
@@ -1579,6 +1627,15 @@ function toJSONInput(source) {
1579
1627
  function toEnum(values) {
1580
1628
  return z.string().transform((value) => values.find((allowed) => allowed.toLowerCase() === value.toLowerCase()) ?? value).pipe(z.enum(values));
1581
1629
  }
1630
+ /** A number as a flag spells it, which is digits with an optional sign and fraction. */
1631
+ const NUMBER = /^-?\d+(\.\d+)?$/;
1632
+ /**
1633
+ * toNumber reads a flag's text as a number only when it is spelled as one. Coercing would
1634
+ * read an empty value as 0 and 0x5 as 5, and send a number nobody typed.
1635
+ */
1636
+ function toNumber(bounds = z.number()) {
1637
+ return z.union([z.number(), z.string().regex(NUMBER).transform(Number)]).pipe(bounds);
1638
+ }
1582
1639
  /** The word that clears a field the API takes null for, and the way to send that word as text. */
1583
1640
  const NULL_WORD = "null";
1584
1641
  /**
@@ -1663,11 +1720,13 @@ async function runOperation(operation, input) {
1663
1720
  writeFailure("missing_flag", `this command needs ${missing.map((flag) => `--${flag.name}`).join(", ")}`, input.isJSON);
1664
1721
  return ExitCode.USAGE;
1665
1722
  }
1666
- const body = toBody(operation, input.flags, given);
1667
- if (body instanceof Error) {
1668
- writeFailure("invalid_flag", body.message, input.isJSON);
1723
+ const built = toBody(operation, input.flags, given);
1724
+ if (built instanceof Error) {
1725
+ writeFailure("invalid_flag", built.message, input.isJSON);
1669
1726
  return ExitCode.USAGE;
1670
1727
  }
1728
+ const isBareAction = operation.method === "POST" && operation.pathParameters.length > 0 && !operation.upload;
1729
+ const body = built === void 0 && isBareAction && operation.bodyFlags.length > 0 ? {} : built;
1671
1730
  if (operation.bodyFlags.length > 0 && body === void 0) {
1672
1731
  writeFailure("empty_request", `this command changes nothing unless a flag is given, such as ${operation.bodyFlags.slice(0, 3).map((flag) => `--${flag.name}`).join(", ")}. Run it with --help for the rest`, input.isJSON);
1673
1732
  return ExitCode.USAGE;
@@ -1749,6 +1808,7 @@ const NOT_A_KEY = /* @__PURE__ */ new Set([
1749
1808
  /** toPath fills the path template from the positional arguments, in order. */
1750
1809
  function toPath(operation, args) {
1751
1810
  if (args.length !== operation.pathParameters.length || args.some((argument) => NOT_A_KEY.has(argument))) return;
1811
+ if (args.some((argument) => /[/\\]/.test(argument))) return;
1752
1812
  let path = operation.path;
1753
1813
  for (const [index, parameter] of operation.pathParameters.entries()) path = path.replace(`{${parameter.name}}`, encodeURIComponent(args[index] ?? ""));
1754
1814
  return path;
@@ -1841,6 +1901,7 @@ function toCleared(operation, flags, body) {
1841
1901
  const flag = operation.bodyFlags.find((entry) => entry.name === name.replace(/^--/, ""));
1842
1902
  if (!flag) return /* @__PURE__ */ new Error(`--unset names no field called ${name}`);
1843
1903
  if (!flag.nullable) return /* @__PURE__ */ new Error(`--${flag.name} cannot be cleared, because the API does not accept null for it`);
1904
+ if (flags[toOptionKey(flag.name)] !== void 0) return /* @__PURE__ */ new Error(`--${flag.name} is given a value and also named by --unset, and only one of them can be sent`);
1844
1905
  set(body, flag.jsonPath, null);
1845
1906
  }
1846
1907
  return names.length > 0;
@@ -1850,19 +1911,29 @@ function toElements(flag, values) {
1850
1911
  const elements = [];
1851
1912
  for (const value of values) {
1852
1913
  const element = {};
1914
+ const given = /* @__PURE__ */ new Set();
1853
1915
  for (const pair of value.split(",")) {
1854
1916
  const split = pair.indexOf("=");
1855
1917
  if (split < 1) return /* @__PURE__ */ new Error(`--${flag.name} takes ${flag.element?.join("=, ") ?? ""}=, such as --${flag.name} ${flag.element?.[0] ?? "field"}=value. A value cannot contain a comma`);
1856
1918
  const isJSON = pair[split - 1] === ":";
1857
1919
  const key = pair.slice(0, isJSON ? split - 1 : split).trim();
1858
1920
  if (flag.element && !flag.element.includes(key)) return /* @__PURE__ */ new Error(`--${flag.name} has no field ${key}. It takes ${flag.element.join(", ")}`);
1859
- if (key in element) return /* @__PURE__ */ new Error(`--${flag.name} names ${key} twice in one element, so which one it takes is not clear`);
1921
+ const isList = flag.elementLists?.includes(key) === true;
1922
+ if (given.has(key) && !isList) return /* @__PURE__ */ new Error(`--${flag.name} names ${key} twice in one element, so which one it takes is not clear`);
1923
+ const clash = [...given].find((other) => key.startsWith(`${other}.`) || other.startsWith(`${key}.`));
1924
+ if (clash) return /* @__PURE__ */ new Error(`--${flag.name} gives both ${clash} and ${key} in one element, and only one of them can be sent`);
1925
+ given.add(key);
1860
1926
  const value = pair.slice(split + 1).trim();
1927
+ if (isList && !isJSON) {
1928
+ element[key] = [...element[key] ?? [], value];
1929
+ continue;
1930
+ }
1861
1931
  if (flag.elementUuids?.includes(key) && !z.uuid().safeParse(value).success) return /* @__PURE__ */ new Error(`--${flag.name} needs a UUID for ${key}, such as 3f2a9c1e-5b7d-4e8a-9c21-7d4e5f6a8b90, and ${value || "nothing"} is not one`);
1862
1932
  const types = flag.elementTypes?.[key];
1863
1933
  const typed = isJSON ? toJSONValue(value, types ?? ["string"]) : toTyped(value, types);
1934
+ if (typed === NOT_TAKEN && types?.some((type) => type === "object" || type === "array")) return /* @__PURE__ */ new Error(`--${flag.name} cannot carry ${key}, which holds more than one value. Send the request body with --input instead`);
1864
1935
  if (typed === NOT_TAKEN) return /* @__PURE__ */ new Error(`--${flag.name} needs ${toNamedTypes(types ?? ["string"])} for ${key}, and ${value || "nothing"} is not one`);
1865
- element[key] = typed;
1936
+ set(element, key.split("."), typed);
1866
1937
  }
1867
1938
  elements.push(element);
1868
1939
  }
@@ -1870,7 +1941,6 @@ function toElements(flag, values) {
1870
1941
  }
1871
1942
  /** Marks text that is none of the types a field takes. */
1872
1943
  const NOT_TAKEN = Symbol("not taken");
1873
- const NUMBER = /^-?\d+(\.\d+)?$/;
1874
1944
  /**
1875
1945
  * toTyped reads the text after key= as the type the document gives the field. A field that
1876
1946
  * takes text is sent as typed, whatever it looks like, because 36 may be a serial number. A
@@ -1882,7 +1952,7 @@ function toTyped(text, types) {
1882
1952
  if (types === void 0 || types.includes("string")) return text;
1883
1953
  if ((types.includes("integer") || types.includes("number")) && NUMBER.test(text)) {
1884
1954
  const value = Number(text);
1885
- if (types.includes("number") || Number.isInteger(value)) return value;
1955
+ if (types.includes("number") || Number.isSafeInteger(value)) return value;
1886
1956
  }
1887
1957
  if (types.includes("boolean") && (text === "true" || text === "false")) return text === "true";
1888
1958
  return NOT_TAKEN;
@@ -3032,7 +3102,7 @@ function toFiles(directory) {
3032
3102
  //#endregion
3033
3103
  //#region src/command/types.generated.ts
3034
3104
  /** API_TYPES is the TypeScript hardfin types prints. */
3035
- const API_TYPES = "// Types for the Hardfin API, version 2026-09-17, generated from its published document.\n// Regenerate them with hardfin types after upgrading the CLI.\n\n/** ApiError is one entry in a response's errors. */\nexport interface ApiError {\n error: string;\n statusCode: number;\n}\n\n/** ApiEnvelope is the shape every response takes, with the record or records in data. */\nexport interface ApiEnvelope<T> {\n data: T;\n metadata: {\n errors?: ApiError[] | null;\n requestId?: string;\n requestTime?: string;\n statusCode?: number;\n pagination?: unknown;\n };\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ArchivedState = \"all\" | \"false\" | \"true\";\n\nexport type Asset = SparseAsset & AssetLocationData & {\n /** The asset's cost basis, depreciation, and accounting history. */\n accounting?: AssetAccountingDetails;\n /** The asset's recent events, such as shipments and deliveries. */\n activity?: AssetEvent[];\n /** A free-form description of the asset. */\n description?: string | null;\n /** The number of files attached to the asset. */\n fileCount?: number;\n /** The day the asset entered inventory. */\n inInventoryDate?: string;\n /** The asset's value for each custom field its item defines. */\n metadata?: AssetMetadataFieldWrapper[];\n /** Who owns the asset now. */\n ownership?: AssetOwnership;\n /** The project the asset is assigned to, or null when it is unassigned. */\n project?: SparseProject | null;\n /** How and when the asset was scrapped, or null when it has not been. */\n scrappedContext?: AssetScrappedContext | null;\n /** The number of tickets about the asset. */\n ticketCount?: number;\n /** The number of links attached to the asset. */\n urlLinkCount?: number;\n};\n\nexport interface AssetAccountingDetails {\n /** The asset's inventory cost basis, before deployment costs, which is what inventory is relieved by when the asset leaves it. */\n acquisitionCogs?: string | null;\n /** The asset's share of overhead. */\n allocatedIndirect?: string | null;\n /** The problems that keep the asset's accounting from being computed, such as a missing cost basis. */\n assetExceptions?: AssetExceptionType[];\n /** The parts cost. */\n billOfMaterials?: string | null;\n /** The cost basis on the books now, the acquisition basis in inventory and the deployed basis once the asset is a fixed asset. */\n capitalizedCosts?: string | null;\n /** The capitalizations and impairments made to the asset's cost after it was acquired. */\n costAdjustments?: AssetCostAdjustment[];\n /** The method the asset is depreciated by. */\n depreciationModel?: Depreciation;\n /** The asset's book value month by month, from its inventory month, or null while it has an accounting exception. */\n depreciationPeriods?: AssetDepreciationChartPeriod[] | null;\n /** The labor cost to build the asset. */\n directLabor?: string | null;\n /** The shipping cost to receive the asset. */\n freightInbound?: string | null;\n /** The shipping cost to deploy the asset, a deployment cost. */\n freightOutbound?: string | null;\n /** The day the asset was put into service and began depreciating. */\n inServiceDate?: string | null;\n /** The cost to install the asset, a deployment cost. */\n installation?: string | null;\n /** The financing cost of the asset. */\n interest?: string | null;\n /** Whether Hardfin sets the in-service date itself rather than keeping one a person entered. */\n isInServiceDateManagedAutomatically?: boolean;\n /** The value the asset keeps at the end of its useful life. */\n salvageValue?: string | null;\n /** A single cost entered in place of the cost components. */\n simpleCostBasis?: string | null;\n /** The import duty paid on the asset. */\n tariffs?: string | null;\n /** The tax paid on the asset. */\n tax?: string | null;\n /** The deployed cost basis, including deployment costs, which is what is capitalized once the asset is put into service. */\n totalPotentialCOGS?: string | null;\n /** The number of months the asset is depreciated over. */\n usefulLife?: number | null;\n /** The changes made to the asset's useful life. */\n usefulLifeRevisions?: AssetUsefulLifeRevision[];\n}\n\nexport interface AssetCostAdjustment {\n /** CAPITALIZATION to add to the cost basis, or IMPAIRMENT to write it down. */\n adjustmentType?: CostAdjustmentType;\n /** The size of the adjustment. */\n amount?: string;\n /** When the adjustment was recorded. */\n createdAt?: string;\n /** The person who recorded the adjustment. */\n createdBy?: SparsePerson;\n /** The day the adjustment takes effect. */\n effectiveDate?: string;\n /** The cost adjustment's key. */\n key?: string;\n /** Free-form detail about the adjustment. */\n notes?: string | null;\n /** Why the cost changed. */\n reason?: CostAdjustmentReason;\n}\n\nexport interface AssetDepreciationChartPeriod {\n /** The depreciation charged from the in-service date through the end of the period. */\n accumulated?: string;\n /** The asset's value on the books at the end of the period. */\n bookValue?: string;\n /** The last day of the month the period covers. */\n date?: string;\n /** The depreciation charged in the period. */\n depreciation?: string;\n}\n\nexport interface AssetEvent {\n /** When the event was recorded. */\n createdAt?: string;\n /** The IANA time zone the event's times were entered in. */\n eventTimezone?: string;\n /** When the event is expected to happen, or null when no one has said. */\n expectedAt?: string | null;\n /** The event's unique identifier. */\n id?: string;\n /** Whether the event has to happen for its group to complete. */\n isRequired?: boolean;\n /** When the event happened, or null while it has not. */\n occurredAt?: string | null;\n /** The day the event was promised to a customer, or null when none was. */\n promiseDate?: string | null;\n /** The event's values a person set, such as carrier tracking. */\n properties?: AssetEventProperty[];\n /** The event's position within its group. */\n sequence?: number;\n /** When someone marked the event as happened in Hardfin, or null while it has not happened. */\n triggeredAt?: string | null;\n /** What kind of event this is. */\n type?: AssetEventType;\n}\n\nexport interface AssetEventConfiguration {\n /** The properties an event of the type carries. */\n properties?: AssetEventProperty[];\n /** The kind of event the configuration describes. */\n type?: AssetEventType;\n}\n\nexport interface AssetEventGroup {\n /** The kind of group this is, and the events it carries. */\n configuration?: AssetEventGroupConfiguration;\n /** Where the movement ends, or null when the group does not move the asset. */\n destination?: SparseLocationWithParent | null;\n /** The events the group has recorded so far. */\n events?: AssetEvent[];\n /** The event group's unique identifier. */\n id?: string;\n /** The event group's key, which the event group endpoints take as eventGroupKey. */\n key?: string;\n /** Where the movement started, or null when the group does not move the asset. */\n origin?: SparseLocationWithParent | null;\n /** The shipment the movement travels on, or null when it travels on none. */\n shipment?: SparseShipment | null;\n}\n\nexport interface AssetEventGroupConfiguration {\n /** The events a group of the kind carries, in the order they happen. */\n events?: AssetEventConfiguration[];\n /** The configuration's unique identifier. */\n id?: string;\n /** The configuration's key. */\n key?: string;\n /** What the configuration is called, such as ship and deliver. */\n name?: string;\n}\n\nexport interface AssetEventProperty {\n /** The event property's unique identifier. */\n id?: string;\n /** Whether Hardfin sets the property itself rather than a person, which responses leave out. */\n isSystemProperty?: boolean;\n /** The property's display name. */\n label?: string;\n /** The kind of value the property holds, such as CARRIER_TRACKING or CACHED_LOCATION. */\n type?: string;\n /** The property's value, whose JSON shape depends on the property's type. */\n value?: unknown[] | boolean | number | Record<string, unknown> | string | null;\n}\n\nexport interface AssetEventType {\n /** The event type's unique identifier. */\n id?: string;\n /** The event type's name, such as Ship or Deliver. */\n name?: string;\n /** Whether an event of this type only happens as part of a group, such as a shipment. */\n requiresEventGroup?: boolean;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AssetExceptionType = \"DEPLOYMENT_WITHOUT_ACQUISITION\" | \"DISPOSAL_DATE_BEFORE_INVENTORY\" | \"FIRST_ASSIGNMENT_BEFORE_INVENTORY\" | \"FIRST_MOVEMENT_BEFORE_INVENTORY\" | \"FIRST_SALE_DATE_BEFORE_INVENTORY\" | \"IN_SERVICE_DATE_BEFORE_INVENTORY\" | \"MISSING_COST_BASIS\" | \"MISSING_USEFUL_LIFE\" | \"SALVAGE_EXCEEDS_50_PERCENT\" | \"UNKNOWN\";\n\nexport interface AssetFile {\n /** The file's unique identifier. */\n id?: string;\n /** Whether the file is readable with any organization's API key. */\n isPublic?: boolean;\n /** The file's key, which the file endpoints take as fileKey. */\n key?: string;\n /** The file's media type, or an empty string when the upload named none. */\n mimeType?: string;\n /** The name the file had when it was uploaded. */\n name?: string;\n /** The file's size in bytes. */\n size?: number;\n /** The file type the file was uploaded as. */\n type?: string;\n /** When the file was uploaded. */\n uploadedAt?: string;\n}\n\n/** Whether an asset works, is broken, awaits review, or has been scrapped. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AssetFunctionalStatus = \"FUNCTIONAL\" | \"NEEDS_REVIEW\" | \"NON-FUNCTIONAL\" | \"SCRAPPED\";\n\nexport interface AssetFunctionalStatusHistoryItem {\n /** When the asset left the status, or null while it still holds it. */\n end?: string | null;\n /** When the asset took the status. */\n start?: string;\n /** Whether the asset worked, was broken, awaited review, or had been scrapped through the period. */\n status?: AssetFunctionalStatus;\n}\n\nexport interface AssetListing {\n /** The page of records. */\n results?: Asset[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\nexport interface AssetLocationData {\n /** Where the asset is, or null while it is in transit. */\n currentLocation?: SparseLocationWithParent | null;\n /** Whether the asset has shipped and not yet been delivered. */\n inTransit?: boolean;\n /** Where a planned or in-progress move takes the asset, or null when none is planned. */\n nextLocation?: SparseLocationWithParent | null;\n /** The location the asset was at before its current one, or null when it has not moved. */\n previousLocation?: SparseLocationWithParent | null;\n}\n\nexport interface AssetMetadataField {\n /** The item field's unique identifier. */\n id?: string;\n /** The item field's key. */\n key?: string;\n /** The field's display name. */\n label?: string;\n /** The field's position within its section, starting at 0. */\n order?: number;\n /** The group the field is shown in, starting at 0. */\n section?: number;\n /** The kind of value the field holds, which decides the JSON type of its value. */\n type?: ItemFieldType;\n}\n\nexport type AssetMetadataFieldWrapper = {\n field?: {\n type?: \"BOOLEAN\";\n };\n value?: boolean | null;\n} | {\n field?: {\n type?: \"DATE\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"DATE_TIME\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"INTEGER\";\n };\n value?: number | null;\n} | {\n field?: {\n type?: \"MULTILINE_TEXT\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"NUMBER\";\n };\n value?: number | null;\n} | {\n field?: {\n type?: \"TEXT\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"TIME\";\n };\n value?: string | null;\n};\n\nexport interface AssetMoveToPlan {\n /** The ID of the asset to move. */\n assetId?: string;\n /** When the asset reaches its destination, or null when the move only ships. */\n deliverAt?: string | null;\n /** The client's own name for the move, which the plan echoes back beside its answer. */\n id?: string;\n /** When the asset leaves its origin, or null when the move only delivers. */\n shipAt?: string | null;\n}\n\nexport interface AssetOwnership {\n /** The customer that owns the asset, or null when your organization owns it. */\n customer?: SparseCustomer | null;\n /** The day the asset's current owner took ownership, or null when its ownership has never changed. */\n ownershipChangeDate?: string | null;\n}\n\nexport interface AssetOwnershipHistoryItem {\n /** When the segment was recorded. */\n createdAt?: string;\n /** The customer that owned the asset during the segment, or null when your organization did. */\n customer?: SparseCustomer | null;\n /** The day the segment's owner took ownership. */\n date?: string;\n /** The ownership segment's unique identifier. */\n id?: string;\n /** The ownership segment's key, which the segment endpoints take as segmentKey. */\n key?: string;\n /** When the segment was last changed. */\n lastModifiedAt?: string;\n /** What the owner paid for the asset, or null when no price was recorded. */\n salePrice?: string | null;\n}\n\nexport interface AssetPlannedIntersection {\n /** The ID of the event group the move would collide with, or null when none names one. */\n aegId?: string | null;\n /** The key of the event group the move would collide with, or null when none names one. */\n aegKey?: string | null;\n /** When the colliding movement ends, or null while it has no end. */\n end?: string | null;\n /** When the colliding movement starts. */\n start?: string;\n}\n\nexport interface AssetPlannedMove {\n /** The client's own name for the move, echoed from the plan it asked about. */\n id?: string;\n /** The movement the move would collide with, or null when it collides with none. */\n intersection?: AssetPlannedIntersection | null;\n /** Whether the move can be carried out as asked. */\n isValid?: boolean;\n}\n\nexport interface AssetProposedMultiMove {\n /** The ID of the asset to move. */\n assetId?: string;\n /** When the asset reaches its destination, which a move sends unless it ships. */\n deliverAt?: string | null;\n /** The timezone the delivery time was entered in, or null for the organization's. */\n deliverAtTimezone?: string | null;\n /** The ID of the location the asset arrives at. */\n destinationId?: string;\n /** The ID of the location the asset leaves. */\n originId?: string;\n /** When the asset leaves its origin, which a move sends unless it delivers. */\n shipAt?: string | null;\n /** The timezone the ship time was entered in, or null for the organization's. */\n shipAtTimezone?: string | null;\n}\n\nexport interface AssetScrappedContext {\n /** The day the asset was scrapped. */\n disposalDate?: string;\n /** What the scrapped asset was sold for, or null when it was not sold. */\n disposalPrice?: string | null;\n /** Why the asset was scrapped. */\n disposalReason?: string | null;\n}\n\nexport interface AssetUpdateMetadataItem {\n /** The ID of the item field to set on the asset. */\n fieldId?: string;\n /** The field's new value, in the JSON type the field's type calls for, or null to clear it. */\n value?: unknown[] | boolean | number | Record<string, unknown> | string | null;\n}\n\nexport interface AssetUsefulLifeRevision {\n /** When the revision was recorded. */\n createdAt?: string;\n /** The person who recorded the revision. */\n createdBy?: SparsePerson;\n /** The day the new useful life takes effect. */\n effectiveDate?: string;\n /** The revision's key. */\n key?: string;\n /** Free-form detail about the revision. */\n notes?: string | null;\n /** Why the useful life changed. */\n reason?: UsefulLifeRevisionReason;\n /** The asset's new useful life in months. */\n usefulLifeMonths?: number;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type BillingFrequency = \"ANNUALLY\" | \"BIENNIALLY\" | \"BIWEEKLY\" | \"DAILY\" | \"MONTHLY\" | \"ONCE\" | \"QUADRENNIALLY\" | \"QUARTERLY\" | \"QUINQUENNIALLY\" | \"SEMIANNUALLY\" | \"TRIENNIALLY\" | \"WEEKLY\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type BillingSchedule = \"MILESTONE\" | \"PERIODIC\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type BillingTiming = \"ADVANCE\" | \"ARREARS\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CostAdjustmentReason = \"ADDITION\" | \"BETTERMENT\" | \"DAMAGE\" | \"INSTALLATION\" | \"LIFE_EXTENSION\" | \"MARKET_DECLINE\" | \"OBSOLESCENCE\" | \"OTHER\" | \"REGULATORY\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CostAdjustmentType = \"CAPITALIZATION\" | \"IMPAIRMENT\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CostBasisMode = \"ADVANCED\" | \"SIMPLE\" | null;\n\n/** The kind of credential a request was made with. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `API_KEY` | An API key, for an integration that runs unattended | | `OAUTH` | An OAuth access token, issued to an application a person connected | | `SESSION` | A person signed in to Hardfin in a browser | */\nexport type CredentialType = \"API_KEY\" | \"OAUTH\" | \"SESSION\";\n\nexport interface Currency {\n /** The value as a decimal string with two decimal places. */\n amount?: string;\n /** The value's ISO 4217 currency code. */\n isoCode?: string;\n}\n\nexport type Customer = SparseCustomer & {\n /** The number of the customer's active projects. */\n activeProjectCt?: number;\n /** The number of assets the customer owns. */\n assetCount?: number;\n /** The number of assets at the customer's locations. */\n assetsAtLocation?: number;\n /** The address invoices are sent to. */\n billingAddress?: string | null;\n /** The person who receives the customer's invoices. */\n billingContact?: CustomerBillingContact | null;\n /** A free-form note about the customer. */\n comment?: string | null;\n /** The customer's web domain, used to look up its logo. */\n domain?: string | null;\n /** The customer's identifier in another system. */\n externalId?: string | null;\n /** The number of the customer's incomplete projects. */\n incompleteProjectCt?: number;\n /** The customer's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** The number of the customer's locations. */\n locationCount?: number;\n /** The customer's locations. */\n locations?: SparseLocationWithParent[];\n /** The storage key of the customer's logo file. */\n logoFileKey?: string | null;\n /** The number of the customer's past projects. */\n pastProjectCt?: number;\n /** The number of the customer's upcoming projects. */\n upcomingProjectCt?: number;\n};\n\nexport interface CustomerBillingContact {\n /** The billing contact's email address. */\n email?: string | null;\n /** The billing contact's name. */\n name?: string | null;\n /** The billing contact's phone number. */\n phone?: string | null;\n}\n\nexport interface CustomerListing {\n /** The page of records. */\n results?: Customer[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type Depreciation = \"DOUBLE_DECLINING\" | \"STRAIGHT_LINE\" | \"SUM_YEAR\" | \"UNIT_OF_PRODUCTION\" | null;\n\nexport interface Error {\n error: string;\n statusCode: number;\n}\n\nexport interface FileNewUpload {\n /** The uploaded file's unique identifier. */\n fileId?: string;\n /** The uploaded file's key, which the file endpoints take as fileKey. */\n fileKey?: string;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type FrontendItemType = \"BULK\" | \"DEVICE\" | \"SERVICE\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type IntegrationCategory = \"CRM\" | \"ERP\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type IntegrationID = \"HUBSPOT\" | \"NETSUITE\" | \"NONE\" | \"QBO\" | \"SFDC\";\n\nexport interface Item {\n /** Whether a BULK item records serial numbers on its units, which is false for SERVICE and DEVICE items. */\n acceptsBulkSerials?: boolean;\n /** The number of assets of a DEVICE item, and null for other types. */\n assetCount?: number | null;\n /** A free-form description of the item. */\n description?: string | null;\n /** The item's unique identifier. */\n id?: string;\n /** The item's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** Whether the item is archived. */\n isArchived?: boolean;\n /** The item's key, which the item endpoints take as itemKey. */\n key?: string;\n /** When the item was last changed. */\n lastUpdatedAt?: string | null;\n /** The person who last changed the item. */\n lastUpdatedBy?: SparsePerson;\n /** The item's display name. */\n name?: string;\n /** Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. */\n shouldRenderSerialFields?: boolean;\n /** The item's stock keeping unit, unique within your organization. */\n sku?: string;\n /** SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. */\n type?: FrontendItemType;\n}\n\nexport interface ItemAccounting {\n /** The default share of overhead for one unit. */\n allocatedIndirect?: string | null;\n /** The default parts cost for one unit. */\n billOfMaterials?: string | null;\n /** The default method one unit is depreciated by. */\n depreciationModel?: Depreciation;\n /** The default labor cost to build one unit. */\n directLabor?: string | null;\n /** The default shipping cost to receive one unit. */\n freightInbound?: string | null;\n /** The default shipping cost to deliver one unit. */\n freightOutbound?: string | null;\n /** The default cost to install one unit. */\n installation?: string | null;\n /** The default financing cost for one unit. */\n interest?: string | null;\n /** The default value one unit keeps at the end of its useful life. */\n salvageValue?: string | null;\n /** A single default cost for one unit, used instead of the cost components. */\n simpleCostBasis?: string | null;\n /** The default import duty paid on one unit. */\n tariffs?: string | null;\n /** The default tax paid on one unit. */\n tax?: string | null;\n /** The default cost of goods sold for one unit, which is the simple cost basis when set and otherwise the sum of the cost components. */\n totalCOGS?: string | null;\n /** The default number of months one unit is depreciated over. */\n usefulLife?: number | null;\n}\n\nexport interface ItemBOMItem {\n /** The BULK part the bill of materials uses. */\n item?: SparseItem;\n /** The number of the part one unit of the item uses. */\n quantity?: number;\n}\n\nexport interface ItemDetail {\n /** Whether a BULK item records serial numbers on its units, which is false for SERVICE and DEVICE items. */\n acceptsBulkSerials?: boolean;\n /** The default costs and depreciation for a unit of a DEVICE or BULK item. */\n accounting?: ItemAccounting;\n /** The number of assets of a DEVICE item, and null for other types. */\n assetCount?: number | null;\n /** The bill of materials, the BULK parts one unit of the item is built from, or null when it has none. */\n bom?: ItemBOMItem[] | null;\n /** The pricing a project line item's billing plan starts from when it sells the item, or null when the item has none. */\n defaultPricing?: ItemPricing | null;\n /** A free-form description of the item. */\n description?: string | null;\n /** The custom fields each asset of a DEVICE item can hold. */\n fields?: ItemField[];\n /** Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. */\n hasAssets?: boolean;\n /** The item's unique identifier. */\n id?: string;\n /** The item's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** The number of inventory movements of a BULK item, and null for other types. */\n inventoryMovementCount?: number | null;\n /** Whether the item is archived. */\n isArchived?: boolean;\n /** Whether the item is physical, which is true for DEVICE and BULK items. */\n isPhysical?: boolean;\n /** The item's key, which the item endpoints take as itemKey. */\n key?: string;\n /** When the item was last changed. */\n lastUpdatedAt?: string | null;\n /** The person who last changed the item. */\n lastUpdatedBy?: SparsePerson;\n /** The item's display name. */\n name?: string;\n /** Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. */\n shouldRenderSerialFields?: boolean;\n /** The item's stock keeping unit, unique within your organization. */\n sku?: string;\n /** SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. */\n type?: FrontendItemType;\n}\n\nexport interface ItemField {\n /** The field's unique identifier. */\n id?: string;\n /** The field's key, which the item field endpoints take as fieldKey. */\n key?: string;\n /** The field's display name. */\n label?: string;\n /** The number of assets that hold a value for the field. */\n metadataCount?: number;\n /** The field's position within its section, starting at 0. */\n order?: number;\n /** The group the field is shown in, starting at 0. */\n section?: number;\n /** The kind of value the field holds. */\n type?: ItemFieldType;\n}\n\nexport interface ItemFieldOrderingUpdateItem {\n /** The ID of the item field to move. */\n fieldId?: string;\n /** The field's position within its section, starting at 0. */\n order?: number;\n /** The group the field is shown in, starting at 0. */\n section?: number;\n}\n\n/** The kind of value an item's custom field holds. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ItemFieldType = \"BOOLEAN\" | \"DATE\" | \"DATE_TIME\" | \"INTEGER\" | \"MULTILINE_TEXT\" | \"NUMBER\" | \"TEXT\" | \"TIME\";\n\nexport interface ItemListing {\n /** The page of records. */\n results?: Item[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\nexport interface ItemPricing {\n /** How often a PERIODIC charge recurs. */\n chargeFrequency?: BillingFrequency | null;\n /** PERIODIC to charge on a recurring cadence, or MILESTONE to charge when a milestone is reached. */\n chargeSchedule?: BillingSchedule | null;\n /** The default price for the whole line, used when pricingMode is FIXED. */\n fixedPrice?: Currency | null;\n /** How often the charges are invoiced. */\n invoiceFrequency?: BillingFrequency | null;\n /** ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends. */\n invoiceMode?: BillingTiming | null;\n /** PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price for the line whatever its quantity. */\n pricingMode?: PricingMode | null;\n /** The default price for each unit, used when pricingMode is PER_UNIT. */\n unitPrice?: Currency | null;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ItemType = \"marked_bulk\" | \"service\" | \"tracked_device\" | \"unmarked_bulk\";\n\nexport type Location = SparseLocationWithIntegration & {\n /** The number of active projects at the location. */\n activeProjectCount?: number;\n /** The number of assets currently at the location. */\n assetCount?: number;\n /** The number of incomplete projects at the location. */\n incompleteProjectCount?: number;\n /** The number of past projects at the location. */\n pastProjectCount?: number;\n /** The number of upcoming projects at the location. */\n upcomingProjectCount?: number;\n};\n\nexport interface LocationListing {\n /** The page of records. */\n results?: Location[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type LocationType = \"SITE\" | \"UNKNOWN\" | \"ZONE\" | null;\n\nexport interface Metadata {\n errors: Error[] | null;\n /** The identifier to quote when asking Hardfin about this request. */\n requestId: string;\n /** How long the server took to answer. */\n requestTime: string;\n statusCode: number;\n}\n\nexport interface MetadataLocationComponents {\n /** The first line of the street address. */\n addressLine1?: string | null;\n /** The second line of the street address, such as a suite. */\n addressLine2?: string | null;\n /** The city. */\n city?: string | null;\n /** The country. */\n country?: string | null;\n /** The whole address on one line. */\n formattedAddress?: string | null;\n /** The postal or ZIP code. */\n postalCode?: string | null;\n /** The state or region. */\n state?: string | null;\n}\n\nexport interface MetadataLocationSite {\n /** The location's structured address, which a zone reads from its parent site. */\n address?: MetadataLocationComponents | null;\n /** Google's place ID for the address, when it was found through Google. */\n googlePlaceId?: string | null;\n /** The location's latitude, sent as a decimal string. */\n latitude?: string | null;\n /** The location's longitude, sent as a decimal string. */\n longitude?: string | null;\n /** The person or business that receives shipments at the location. */\n shippingName?: string | null;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type PricingMode = \"FIXED\" | \"PER_UNIT\";\n\n/** The item type a request asks an item to become. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type RequestedItemType = \"BULK\" | \"DEVICE\" | \"SERVICE\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ScrappedState = \"all\" | \"false\" | \"true\";\n\nexport interface SharedBool {\n /** Whether the operation completed. */\n success?: boolean;\n}\n\nexport interface SharedIntegration {\n /** The Hardfin error code of the failed sync, or null when the sync did not fail. */\n errorCode?: number | null;\n /** The integrated system, such as SFDC or HUBSPOT. */\n id?: IntegrationID;\n /** Whether the last sync with the external system failed. */\n inError?: boolean;\n /** Whether a sync with the external system is pending. */\n isSyncing?: boolean;\n /** The system's display name. */\n label?: string;\n /** A URL to the linked record in the external system. */\n link?: string | null;\n /** Whether the record differs from the external system and needs a person to review it. */\n needsReview?: boolean;\n /** The kind of system, CRM or ERP. */\n type?: IntegrationCategory;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type SortOrder = \"ASC\" | \"DESC\";\n\nexport interface SparseAsset {\n /** Whether the asset works, is broken, awaits review, or has been scrapped. */\n functionalStatus?: AssetFunctionalStatus;\n /** The asset's unique identifier. */\n id?: string;\n /** The day the asset entered inventory. */\n inInventoryDate?: string;\n /** Whether the asset is archived. */\n isArchived?: boolean;\n /** Whether the asset has shipped and not yet been delivered. */\n isInTransit?: boolean;\n /** The catalog item the asset is a unit of. */\n item?: SparseItem;\n /** The asset's key, which the asset endpoints take as assetKey. */\n key?: string;\n /** The asset's serial number, unique within its item. */\n serial?: string;\n}\n\nexport interface SparseCustomer {\n /** The customer's unique identifier. */\n id?: string;\n /** Whether the customer is archived. */\n isArchived?: boolean;\n /** Whether the company is a customer. */\n isCustomer?: boolean;\n /** Whether the company is a supplier. */\n isSupplier?: boolean;\n /** The customer's key, which the customer endpoints take as customerKey. */\n key?: string;\n /** The customer's display name. */\n name?: string;\n}\n\nexport interface SparseItem {\n /** Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. */\n hasAssets?: boolean;\n /** The item's unique identifier. */\n id?: string;\n /** Whether the item is archived. */\n isArchived?: boolean;\n /** Whether the item is physical, which is true for DEVICE and BULK items. */\n isPhysical?: boolean;\n /** The item's key, which the item endpoints take as itemKey. */\n key?: string;\n /** The item's display name. */\n name?: string;\n /** Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. */\n shouldRenderSerialFields?: boolean;\n /** The item's stock keeping unit, unique within your organization. */\n sku?: string;\n /** SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. */\n type?: FrontendItemType;\n /** The unit the item's quantities are counted in. */\n unitOfMeasure?: UnitOfMeasure;\n}\n\nexport type SparseLocation = MetadataLocationSite & {\n /** The number of archived zones at a site. */\n archivedZoneCount?: number;\n /** The customer a zone is designated for, such as for reservations, provisioning or a 3PL. */\n consignee?: SparseCustomer | null;\n /** The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. */\n customer?: SparseCustomer | null;\n /** A free-form description of a zone. */\n description?: string | null;\n /** The location's unique identifier. */\n id?: string;\n /** Whether the location is archived. */\n isArchived?: boolean;\n /** Whether assets at the location count as inventory for reporting. */\n isInventory?: boolean;\n /** Whether a zone sets its own isInventory rather than inheriting its parent site's. */\n isInventoryOverride?: boolean;\n /** Whether a third-party logistics (3PL) provider fulfills orders from the location. */\n isThirdPartyEnabled?: boolean;\n /** Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. */\n isTransient?: boolean;\n /** The location's key, which the location endpoints take as locationKey. */\n key?: string;\n /** The location's display name. */\n name?: string;\n /** The 3PL provider's identifier for the location. */\n thirdPartyIdentifier?: string | null;\n /** SITE for a site, or ZONE for a zone within a site. */\n type?: LocationType;\n /** The number of zones at a site. */\n zoneCount?: number;\n /** The site's zones. */\n zones?: SparseZone[];\n};\n\nexport type SparseLocationWithIntegration = SparseLocationWithParent & {\n /** The location's links to integrated systems. */\n integrations?: SharedIntegration[];\n};\n\nexport type SparseLocationWithParent = SparseLocation & {\n /** The site a zone belongs to, or null for a site. */\n parentLocation?: SparseLocation | null;\n};\n\nexport interface SparseOrganization {\n /** The organization's ID */\n id?: string;\n /** The public identifier that can be used in URLs */\n key?: string;\n /** The name of the organization */\n name?: string;\n}\n\nexport interface SparsePerson {\n /** The person's first name. */\n firstName?: string | null;\n /** The person's unique identifier. */\n id?: string;\n /** The person's key. */\n key?: string;\n /** The person's last name. */\n lastName?: string | null;\n}\n\nexport interface SparseProject {\n /** The customer the project is for. */\n customer?: SparseCustomer | null;\n /** The day the project ends. */\n end?: string | null;\n /** The project's unique identifier. */\n id?: string;\n /** The project's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** Whether the project is archived. */\n isArchived?: boolean;\n /** The project's key. */\n key?: string;\n /** The project's display name. */\n name?: string;\n /** The name of the project's payment term. */\n paymentTermLabel?: string | null;\n /** The customer's purchase order number, which new invoices for the project carry. */\n purchaseOrderNumber?: string | null;\n /** The day the project starts. */\n start?: string | null;\n /** Whether the project is upcoming, active, or past, judged from its dates. */\n status?: string;\n}\n\nexport interface SparseShipment {\n /** When the shipment arrived, or null while it has not. */\n deliveredAt?: string | null;\n /** The shipment's unique identifier. */\n id?: string;\n /** The shipment's key. */\n key?: string;\n /** The number the shipment is known by. */\n shipmentNumber?: string;\n /** What kind of movement the shipment carries. */\n shipmentType?: string;\n /** When the shipment left, or null while it has not. */\n shippedAt?: string | null;\n}\n\nexport interface SparseZone {\n /** The number of assets in the zone. */\n assetCount?: number;\n /** The customer the zone is designated for, such as for reservations, provisioning or a 3PL. */\n consignee?: SparseCustomer | null;\n /** A free-form description of the zone. */\n description?: string | null;\n /** The zone's unique identifier. */\n id?: string;\n /** Whether the zone is archived. */\n isArchived?: boolean;\n /** Whether assets in the zone count as inventory for reporting. */\n isInventory?: boolean;\n /** The zone's key. */\n key?: string;\n /** The zone's display name, unique within its site. */\n name?: string;\n}\n\nexport interface Token {\n /** When the API key was created, the application was connected, or the person signed in. */\n createdAt?: string;\n /** When the access token or session expires, or null for an API key, which does not. */\n expiresAt?: string | null;\n /** The API key's public identifier or the application's client_id, or null for a session. */\n identifier?: string | null;\n /** The API key's label or the application's name, or null when there is none. */\n label?: string | null;\n /** When the API key was last regenerated or the access token was issued, or null for a session. */\n lastRegeneratedAt?: string | null;\n /** The organization the credential acts in. */\n organization?: SparseOrganization;\n /** The person the credential acts for. */\n person?: SparsePerson;\n scopes?: string[];\n /** The kind of credential. */\n type?: CredentialType;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type TransientState = \"all\" | \"false\" | \"true\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type TransitStatus = \"IN_TRANSIT\" | \"IN_TRANSIT_TO_FIELD\" | \"IN_TRANSIT_TO_INVENTORY\" | \"NOT_IN_TRANSIT\";\n\nexport interface URLLink {\n /** When the link was created. */\n createdAt?: string;\n /** The URL link's unique identifier. */\n id?: string;\n /** The URL link's key, which the URL link endpoints take as linkKey. */\n key?: string;\n /** The link's display name, or null when the link shows its address instead. */\n name?: string | null;\n /** When the link was last changed. */\n updatedAt?: string;\n /** The address the link points to. */\n url?: string;\n}\n\n/** The unit a quantity is counted in, sent as its UNECE Recommendation 20 code. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `BG` | Bag | | `BO` | Bottle | | `BX` | Box | | `C62` | Unit | | `CMK` | Square centimeter (cm2) | | `CMT` | Centimeter (cm) | | `CR` | Crate | | `CS` | Case | | `CT` | Carton | | `DMQ` | Cubic decimeter (dm3) | | `DR` | Drum | | `DZN` | Dozen (doz) | | `EA` | Each (ea) | | `EN` | Envelope | | `FOT` | Foot (ft) | | `FTK` | Square foot (ft2) | | `FTQ` | Cubic foot (ft3) | | `GLL` | Gallon (gal) | | `GRM` | Gram (g) | | `GRO` | Gross | | `H87` | Piece (pc) | | `INH` | Inch (in) | | `INK` | Square inch (in2) | | `INQ` | Cubic inch (in3) | | `KG` | Keg | | `KGM` | Kilogram (kg) | | `KMT` | Kilometer (km) | | `KT` | Kit | | `LBR` | Pound (lb) | | `LO` | Lot | | `LTR` | Liter (L) | | `MGM` | Milligram (mg) | | `MLT` | Milliliter (mL) | | `MMK` | Square millimeter (mm2) | | `MMT` | Millimeter (mm) | | `MTK` | Square meter (m2) | | `MTQ` | Cubic meter (m3) | | `MTR` | Meter (m) | | `ONZ` | Ounce (oz) | | `OZA` | Fluid ounce (fl oz) | | `PK` | Pack | | `PR` | Pair (pr) | | `PTI` | Pint (pt) | | `PX` | Pallet | | `QTI` | Quart (qt) | | `RL` | Reel | | `RO` | Roll | | `SET` | Set | | `SMI` | Mile (mi) | | `ST` | Sheet | | `STN` | Ton US (NT) | | `SV` | Skid | | `TNE` | Tonne metric (t) | | `TU` | Tube | | `YDK` | Square yard (yd2) | | `YDQ` | Cubic yard (yd3) | | `YRD` | Yard (yd) | */\nexport type UnitOfMeasure = \"BG\" | \"BO\" | \"BX\" | \"C62\" | \"CMK\" | \"CMT\" | \"CR\" | \"CS\" | \"CT\" | \"DMQ\" | \"DR\" | \"DZN\" | \"EA\" | \"EN\" | \"FOT\" | \"FTK\" | \"FTQ\" | \"GLL\" | \"GRM\" | \"GRO\" | \"H87\" | \"INH\" | \"INK\" | \"INQ\" | \"KG\" | \"KGM\" | \"KMT\" | \"KT\" | \"LBR\" | \"LO\" | \"LTR\" | \"MGM\" | \"MLT\" | \"MMK\" | \"MMT\" | \"MTK\" | \"MTQ\" | \"MTR\" | \"ONZ\" | \"OZA\" | \"PK\" | \"PR\" | \"PTI\" | \"PX\" | \"QTI\" | \"RL\" | \"RO\" | \"SET\" | \"SMI\" | \"ST\" | \"STN\" | \"SV\" | \"TNE\" | \"TU\" | \"YDK\" | \"YDQ\" | \"YRD\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type UsefulLifeRevisionReason = \"CHANGE_IN_USE\" | \"DAMAGE\" | \"OBSOLESCENCE\" | \"OTHER\" | \"REASSESSMENT\" | \"REFURBISHMENT\" | \"REGULATORY\";\n";
3105
+ const API_TYPES = "// Types for the Hardfin API, version 2026-10-12, generated from its published document.\n// Regenerate them with hardfin types after upgrading the CLI.\n\n/** ApiError is one entry in a response's errors. */\nexport interface ApiError {\n error: string;\n statusCode: number;\n}\n\n/** ApiEnvelope is the shape every response takes, with the record or records in data. */\nexport interface ApiEnvelope<T> {\n data: T;\n metadata: {\n errors?: ApiError[] | null;\n requestId?: string;\n requestTime?: string;\n statusCode?: number;\n pagination?: unknown;\n };\n}\n\n/** Accepted in any case, and also as t, f, 1, 0, or 2 for all. The listed spelling is the one the API sends back. */\nexport type ArchivedState = \"all\" | \"false\" | \"true\";\n\nexport type Asset = SparseAsset & AssetLocationData & {\n /** The asset's cost basis, depreciation, and accounting history. */\n accounting?: AssetAccountingDetails;\n /** The asset's recent events, such as shipments and deliveries. */\n activity?: AssetEvent[];\n /** A free-form description of the asset. */\n description?: string | null;\n /** The number of files attached to the asset. */\n fileCount?: number;\n /** The day the asset entered inventory. */\n inInventoryDate?: string;\n /** The asset's value for each custom field its item defines. */\n metadata?: AssetMetadataFieldWrapper[];\n /** Who owns the asset now. */\n ownership?: AssetOwnership;\n /** The project the asset is assigned to, or null when it is unassigned. */\n project?: SparseProject | null;\n /** How and when the asset was scrapped, or null when it has not been. */\n scrappedContext?: AssetScrappedContext | null;\n /** The number of tickets about the asset. */\n ticketCount?: number;\n /** The number of links attached to the asset. */\n urlLinkCount?: number;\n};\n\nexport interface AssetAccountingDetails {\n /** The asset's inventory cost basis, before deployment costs, which is what inventory is relieved by when the asset leaves it. */\n acquisitionCogs?: string | null;\n /** The asset's share of overhead. */\n allocatedIndirect?: string | null;\n /** The problems that keep the asset's accounting from being computed, such as a missing cost basis. */\n assetExceptions?: AssetExceptionType[];\n /** The parts cost. */\n billOfMaterials?: string | null;\n /** The cost basis on the books now, the acquisition basis in inventory and the deployed basis once the asset is a fixed asset. */\n capitalizedCosts?: string | null;\n /** The capitalizations and impairments made to the asset's cost after it was acquired. */\n costAdjustments?: AssetCostAdjustment[];\n /** The method the asset is depreciated by. */\n depreciationModel?: Depreciation;\n /** The asset's book value month by month, from its inventory month, or null while it has an accounting exception. */\n depreciationPeriods?: AssetDepreciationChartPeriod[] | null;\n /** The labor cost to build the asset. */\n directLabor?: string | null;\n /** The shipping cost to receive the asset. */\n freightInbound?: string | null;\n /** The shipping cost to deploy the asset, a deployment cost. */\n freightOutbound?: string | null;\n /** The day the asset was put into service and began depreciating. */\n inServiceDate?: string | null;\n /** The cost to install the asset, a deployment cost. */\n installation?: string | null;\n /** The financing cost of the asset. */\n interest?: string | null;\n /** Whether Hardfin sets the in-service date itself rather than keeping one a person entered. */\n isInServiceDateManagedAutomatically?: boolean;\n /** The value the asset keeps at the end of its useful life. */\n salvageValue?: string | null;\n /** A single cost entered in place of the cost components. */\n simpleCostBasis?: string | null;\n /** The import duty paid on the asset. */\n tariffs?: string | null;\n /** The tax paid on the asset. */\n tax?: string | null;\n /** The deployed cost basis, including deployment costs, which is what is capitalized once the asset is put into service. */\n totalPotentialCOGS?: string | null;\n /** The number of months the asset is depreciated over. */\n usefulLife?: number | null;\n /** The changes made to the asset's useful life. */\n usefulLifeRevisions?: AssetUsefulLifeRevision[];\n}\n\nexport interface AssetCostAdjustment {\n /** CAPITALIZATION to add to the cost basis, or IMPAIRMENT to write it down. */\n adjustmentType?: CostAdjustmentType;\n /** The size of the adjustment. */\n amount?: string;\n /** When the adjustment was recorded. */\n createdAt?: string;\n /** The person who recorded the adjustment. */\n createdBy?: SparsePerson;\n /** The day the adjustment takes effect. */\n effectiveDate?: string;\n /** The cost adjustment's key. */\n key?: string;\n /** Free-form detail about the adjustment. */\n notes?: string | null;\n /** Why the cost changed. */\n reason?: CostAdjustmentReason;\n}\n\nexport interface AssetDepreciationChartPeriod {\n /** The depreciation charged from the in-service date through the end of the period. */\n accumulated?: string;\n /** The asset's value on the books at the end of the period. */\n bookValue?: string;\n /** The last day of the month the period covers. */\n date?: string;\n /** The depreciation charged in the period. */\n depreciation?: string;\n}\n\nexport interface AssetEvent {\n /** When the event was recorded. */\n createdAt?: string;\n /** The IANA time zone the event's times were entered in. */\n eventTimezone?: string;\n /** When the event is expected to happen, or null when no one has said. */\n expectedAt?: string | null;\n /** The event's unique identifier. */\n id?: string;\n /** Whether the event has to happen for its group to complete. */\n isRequired?: boolean;\n /** When the event happened, or null while it has not. */\n occurredAt?: string | null;\n /** The day the event was promised to a customer, or null when none was. */\n promiseDate?: string | null;\n /** The event's values a person set, such as carrier tracking. */\n properties?: AssetEventProperty[];\n /** The event's position within its group. */\n sequence?: number;\n /** When someone marked the event as happened in Hardfin, or null while it has not happened. */\n triggeredAt?: string | null;\n /** What kind of event this is. */\n type?: AssetEventType;\n}\n\nexport interface AssetEventConfiguration {\n /** The properties an event of the type carries. */\n properties?: AssetEventProperty[];\n /** The kind of event the configuration describes. */\n type?: AssetEventType;\n}\n\nexport interface AssetEventGroup {\n /** The kind of group this is, and the events it carries. */\n configuration?: AssetEventGroupConfiguration;\n /** Where the movement ends, or null when the group does not move the asset. */\n destination?: SparseLocationWithParent | null;\n /** The events the group has recorded so far. */\n events?: AssetEvent[];\n /** The event group's unique identifier. */\n id?: string;\n /** The event group's key, which the event group endpoints take as eventGroupKey. */\n key?: string;\n /** Where the movement started, or null when the group does not move the asset. */\n origin?: SparseLocationWithParent | null;\n /** The shipment the movement travels on, or null when it travels on none. */\n shipment?: SparseShipment | null;\n}\n\nexport interface AssetEventGroupConfiguration {\n /** The events a group of the kind carries, in the order they happen. */\n events?: AssetEventConfiguration[];\n /** The configuration's unique identifier. */\n id?: string;\n /** The configuration's key. */\n key?: string;\n /** What the configuration is called, such as ship and deliver. */\n name?: string;\n}\n\nexport interface AssetEventProperty {\n /** The event property's unique identifier. */\n id?: string;\n /** Whether Hardfin sets the property itself rather than a person, which responses leave out. */\n isSystemProperty?: boolean;\n /** The property's display name. */\n label?: string;\n /** The kind of value the property holds, such as CARRIER_TRACKING or CACHED_LOCATION. */\n type?: string;\n /** The property's value, whose JSON shape depends on the property's type. */\n value?: unknown[] | boolean | number | Record<string, unknown> | string | null;\n}\n\nexport interface AssetEventType {\n /** The event type's unique identifier. */\n id?: string;\n /** The event type's name, such as Ship or Deliver. */\n name?: string;\n /** Whether an event of this type only happens as part of a group, such as a shipment. */\n requiresEventGroup?: boolean;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AssetExceptionType = \"DEPLOYMENT_WITHOUT_ACQUISITION\" | \"DISPOSAL_DATE_BEFORE_INVENTORY\" | \"FIRST_ASSIGNMENT_BEFORE_INVENTORY\" | \"FIRST_MOVEMENT_BEFORE_INVENTORY\" | \"FIRST_SALE_DATE_BEFORE_INVENTORY\" | \"IN_SERVICE_DATE_BEFORE_INVENTORY\" | \"MISSING_COST_BASIS\" | \"MISSING_USEFUL_LIFE\" | \"SALVAGE_EXCEEDS_50_PERCENT\" | \"UNKNOWN\";\n\nexport interface AssetFile {\n /** The file's unique identifier. */\n id?: string;\n /** Whether the file is readable with any organization's API key. */\n isPublic?: boolean;\n /** The file's key, which the file endpoints take as fileKey. */\n key?: string;\n /** The file's media type, or an empty string when the upload named none. */\n mimeType?: string;\n /** The name the file had when it was uploaded. */\n name?: string;\n /** The file's size in bytes. */\n size?: number;\n /** The file type the file was uploaded as. */\n type?: string;\n /** When the file was uploaded. */\n uploadedAt?: string;\n}\n\n/** Whether an asset works, is broken, awaits review, or has been scrapped. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AssetFunctionalStatus = \"FUNCTIONAL\" | \"NEEDS_REVIEW\" | \"NON-FUNCTIONAL\" | \"SCRAPPED\";\n\nexport interface AssetFunctionalStatusHistoryItem {\n /** When the asset left the status, or null while it still holds it. */\n end?: string | null;\n /** When the asset took the status. */\n start?: string;\n /** Whether the asset worked, was broken, awaited review, or had been scrapped through the period. */\n status?: AssetFunctionalStatus;\n}\n\nexport interface AssetListing {\n /** The page of records. */\n results?: Asset[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\nexport interface AssetLocationData {\n /** Where the asset is, or null while it is in transit. */\n currentLocation?: SparseLocationWithParent | null;\n /** Whether the asset has shipped and not yet been delivered. */\n inTransit?: boolean;\n /** Where a planned or in-progress move takes the asset, or null when none is planned. */\n nextLocation?: SparseLocationWithParent | null;\n /** The location the asset was at before its current one, or null when it has not moved. */\n previousLocation?: SparseLocationWithParent | null;\n}\n\nexport interface AssetMetadataField {\n /** The item field's unique identifier. */\n id?: string;\n /** The item field's key. */\n key?: string;\n /** The field's display name. */\n label?: string;\n /** The field's position within its section, starting at 0. */\n order?: number;\n /** The group the field is shown in, starting at 0. */\n section?: number;\n /** The kind of value the field holds, which decides the JSON type of its value. */\n type?: ItemFieldType;\n}\n\nexport type AssetMetadataFieldWrapper = {\n field?: {\n type?: \"BOOLEAN\";\n };\n value?: boolean | null;\n} | {\n field?: {\n type?: \"DATE\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"DATE_TIME\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"INTEGER\";\n };\n value?: number | null;\n} | {\n field?: {\n type?: \"MULTILINE_TEXT\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"NUMBER\";\n };\n value?: number | null;\n} | {\n field?: {\n type?: \"TEXT\";\n };\n value?: string | null;\n} | {\n field?: {\n type?: \"TIME\";\n };\n value?: string | null;\n};\n\nexport interface AssetMoveToPlan {\n /** The ID of the asset to move. */\n assetId: string;\n /** When the asset reaches its destination, or null when the move only ships. */\n deliverAt?: string | null;\n /** The client's own name for the move, which the plan echoes back beside its answer. */\n id: string;\n /** When the asset leaves its origin, or null when the move only delivers. */\n shipAt?: string | null;\n}\n\nexport interface AssetOwnership {\n /** The customer that owns the asset, or null when your organization owns it. */\n customer?: SparseCustomer | null;\n /** The day the asset's current owner took ownership, or null when its ownership has never changed. */\n ownershipChangeDate?: string | null;\n}\n\nexport interface AssetOwnershipHistoryItem {\n /** When the segment was recorded. */\n createdAt?: string;\n /** The customer that owned the asset during the segment, or null when your organization did. */\n customer?: SparseCustomer | null;\n /** The day the segment's owner took ownership. */\n date?: string;\n /** The ownership segment's unique identifier. */\n id?: string;\n /** The ownership segment's key, which the segment endpoints take as segmentKey. */\n key?: string;\n /** When the segment was last changed. */\n lastModifiedAt?: string;\n /** What the owner paid for the asset, or null when no price was recorded. */\n salePrice?: string | null;\n}\n\nexport interface AssetPlannedIntersection {\n /** The ID of the event group the move would collide with, or null when none names one. */\n aegId?: string | null;\n /** The key of the event group the move would collide with, or null when none names one. */\n aegKey?: string | null;\n /** When the colliding movement ends, or null while it has no end. */\n end?: string | null;\n /** When the colliding movement starts. */\n start?: string;\n}\n\nexport interface AssetPlannedMove {\n /** The client's own name for the move, echoed from the plan it asked about. */\n id?: string;\n /** The movement the move would collide with, or null when it collides with none. */\n intersection?: AssetPlannedIntersection | null;\n /** Whether the move can be carried out as asked. */\n isValid?: boolean;\n}\n\n/** A project assignment the asset list filters by. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AssetProjectStatusFilter = \"ACTIVE\" | \"NONE\" | \"PAST\" | \"UPCOMING\";\n\nexport interface AssetProposedMultiMove {\n /** The ID of the asset to move. */\n assetId: string;\n /** When the asset reaches its destination, and one of shipAt or deliverAt is required. */\n deliverAt?: string | null;\n /** The IANA time zone name the delivery time was entered in, such as America/Denver; when omitted, the delivery time's clock time is read in the organization's time zone. */\n deliverAtTimezone?: string | null;\n /** The ID of the location the asset arrives at. */\n destinationId: string;\n /** The ID of the location the asset leaves. */\n originId: string;\n /** When the asset leaves its origin, and one of shipAt or deliverAt is required. */\n shipAt?: string | null;\n /** The IANA time zone name the ship time was entered in, such as America/Denver; when omitted, the ship time's clock time is read in the organization's time zone. */\n shipAtTimezone?: string | null;\n}\n\nexport interface AssetScrappedContext {\n /** The day the asset was scrapped. */\n disposalDate?: string;\n /** What the scrapped asset was sold for, or null when it was not sold. */\n disposalPrice?: string | null;\n /** Why the asset was scrapped. */\n disposalReason?: string | null;\n}\n\nexport interface AssetShippingData {\n /** When Hardfin recorded the update. */\n createdAt?: string;\n /** The tracking update's unique identifier. */\n id?: string;\n /** The tracking update's key. */\n key?: string;\n /** Where the carrier reported the shipment, or null when it reported nowhere. */\n location?: AssetShippingDataLocation | null;\n /** When the carrier says the update happened. */\n reportedAt?: string;\n /** The carrier's status for the shipment at that point. */\n status?: string;\n /** What the carrier wrote about the update. */\n statusText?: string;\n /** The carrier's finer status, or null when it reported none. */\n substatus?: string | null;\n /** When Hardfin last changed the update. */\n updatedAt?: string;\n}\n\nexport interface AssetShippingDataListing {\n /** Who carries the shipment, or null when no carrier is named. */\n carrier?: Carrier | null;\n /** When the carrier now expects to deliver, or null when it says nothing. */\n eta?: string | null;\n /** When the carrier first expected to deliver, or null when it said nothing. */\n originalEta?: string | null;\n /** The carrier's name when it is one Hardfin does not track itself, or null. */\n otherName?: string | null;\n /** The carrier's service the shipment travels on, or null when it names none. */\n serviceLevelName?: string | null;\n /** What the carrier has reported, newest first. */\n shippingHistory?: AssetShippingData[];\n /** The number the carrier tracks the shipment by, or null when it has none. */\n trackingNumber?: string | null;\n}\n\nexport interface AssetShippingDataLocation {\n /** The city the carrier reported. */\n city?: string;\n /** The country the carrier reported. */\n country?: string;\n /** The state or region the carrier reported. */\n state?: string;\n /** The postal code the carrier reported. */\n zip?: string;\n}\n\nexport interface AssetUpdateMetadataItem {\n /** The ID of the item field to set on the asset. */\n fieldId: string;\n /** The field's new value, in the JSON type the field's type calls for, or null to clear it. */\n value?: unknown[] | boolean | number | Record<string, unknown> | string | null;\n}\n\nexport interface AssetUsefulLifeRevision {\n /** When the revision was recorded. */\n createdAt?: string;\n /** The person who recorded the revision. */\n createdBy?: SparsePerson;\n /** The day the new useful life takes effect. */\n effectiveDate?: string;\n /** The revision's key. */\n key?: string;\n /** Free-form detail about the revision. */\n notes?: string | null;\n /** Why the useful life changed. */\n reason?: UsefulLifeRevisionReason;\n /** The asset's new useful life in months. */\n usefulLifeMonths?: number;\n}\n\n/** A machine-readable predicate describing why an entity needs attention. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AttentionReason = \"DELIVERED_NOT_RECEIVED\" | \"OPEN_NOT_SHIPPED\" | \"SHIPPED_NOT_DELIVERED\";\n\n/** An ordinal severity for the needs-attention signal. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type AttentionSeverity = \"CRITICAL\" | \"NOTICE\" | \"WARNING\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type BillingFrequency = \"ANNUALLY\" | \"BIENNIALLY\" | \"BIWEEKLY\" | \"DAILY\" | \"MONTHLY\" | \"ONCE\" | \"QUADRENNIALLY\" | \"QUARTERLY\" | \"QUINQUENNIALLY\" | \"SEMIANNUALLY\" | \"TRIENNIALLY\" | \"WEEKLY\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type BillingSchedule = \"MILESTONE\" | \"PERIODIC\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type BillingTiming = \"ADVANCE\" | \"ARREARS\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type Carrier = \"airterra\" | \"apc_postal\" | \"apg\" | \"aramex\" | \"asendia_us\" | \"australia_post\" | \"axlehire\" | \"better_trucks\" | \"borderguru\" | \"boxberry\" | \"bring\" | \"canada_post\" | \"cdl\" | \"chronopost\" | \"colissimo\" | \"collect_plus\" | \"correios_br\" | \"correos_espana\" | \"couriersplease\" | \"deutsche_post\" | \"dhl_benelux\" | \"dhl_ecommerce\" | \"dhl_express\" | \"dhl_germany\" | \"dhl_germany_c2c\" | \"dpd_de\" | \"dpd_uk\" | \"estafeta\" | \"fastway_australia\" | \"fedex\" | \"globegistics\" | \"gls_us\" | \"gophr\" | \"gso\" | \"hermes_germany_b2c\" | \"hermes_uk\" | \"hongkong_post\" | \"la_poste\" | \"lasership\" | \"lso\" | \"mondial_relay\" | \"new_zealand_post\" | \"nippon_express\" | \"ontrac\" | \"orangeds\" | \"other\" | \"parcel\" | \"parcelforce\" | \"passport\" | \"pcf\" | \"pitney_bowes\" | \"poste_italiane\" | \"posti\" | \"purolator\" | \"royal_mail\" | \"royal_mail_sf\" | \"rr_donnelley\" | \"russian_post\" | \"sendle\" | \"shippo\" | \"skypostal\" | \"stuart\" | \"swyft\" | \"uds\" | \"ups\" | \"usps\" | \"veho\" | \"x_delivery\" | \"yodel\";\n\nexport interface Charge {\n /** The day the charge became billable, or null while it has not. */\n billingEligibleDate?: string | null;\n /** The day the charge is planned to become billable, or null when it has no dates yet. */\n expectedBillableDate?: string | null;\n /** The charge's unique identifier. */\n id?: string;\n /** True when a person added, edited or split the charge, and false when it came from the line item's billing plan unchanged. */\n isCustomModified?: boolean;\n /** The charge's key. */\n key?: string;\n /** The charge's display name, such as the period it covers or the milestone it follows. */\n label?: string;\n /** PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. */\n pricingMode?: PricingMode;\n /** The number of units the charge bills. */\n quantity?: number;\n /** The charge's position among its line item's charges, in ascending order. */\n sequence?: number;\n /** The last day of the period the charge covers. */\n servicePeriodEnd?: string | null;\n /** The first day of the period the charge covers, or null when the charge has no dates yet. */\n servicePeriodStart?: string | null;\n /** PLANNED before the charge can be invoiced, BILLABLE once it can, INVOICED once it is on an invoice, or CANCELLED when it will not be billed. */\n status?: ChargeStatus;\n /** The amount the charge bills. */\n totalPrice?: Currency;\n /** TIME when the charge becomes billable on ExpectedBillableDate, or MANUAL when a person marks it billable. */\n triggerType?: ChargeTriggerType;\n /** The price of one unit behind the charge, or null when TotalPrice was not computed from one. */\n unitPrice?: Currency | null;\n}\n\nexport interface ChargeListItem {\n /** The moment the charge became billable, or null while it has not. */\n actualBillableAt?: string | null;\n /** Why the charge was cancelled, or null when none was given or it is not cancelled. */\n cancellationReason?: string | null;\n /** The moment the charge was cancelled, or null when it is not cancelled. */\n cancelledAt?: string | null;\n /** The line item's schedule: PERIODIC when its charges recur at a regular frequency, or MILESTONE when each follows a project milestone. */\n chargeSchedule?: BillingSchedule;\n /** The day the charge is planned to become billable, or null when it has no dates yet. */\n expectedBillableDate?: string | null;\n /** The charge's unique identifier. */\n id?: string;\n /** The item the charge's line item bills for. */\n item?: SparseItem;\n /** The charge's key. */\n key?: string;\n /** The charge's display name, such as the period it covers or the milestone it follows. */\n label?: string;\n /** CONFIRMED when the line item's charges carry dates, or PENDING when its activation date is not yet known, and a PERIODIC charge can be marked billable only once it is CONFIRMED. */\n lineItemChargeMode?: ChargeMode;\n /** The key of the line item the charge belongs to. */\n lineItemKey?: string;\n /** PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. */\n pricingMode?: PricingMode;\n /** The project the charge belongs to, which carries the charge's customer. */\n project?: SparseProject;\n /** The number of units the charge bills. */\n quantity?: number;\n /** The last day of the period the charge covers. */\n servicePeriodEnd?: string | null;\n /** The first day of the period the charge covers, or null when the charge has no dates yet. */\n servicePeriodStart?: string | null;\n /** The number of charges split from one charge, which is 1 for a charge that was never split. */\n splitCount?: number;\n /** The charge's position among the charges split from one charge, counted from 1. */\n splitIndex?: number;\n /** PLANNED before the charge can be invoiced, BILLABLE once it can, INVOICED once it is on an invoice, or CANCELLED when it will not be billed. */\n status?: ChargeStatus;\n /** The amount the charge bills. */\n totalPrice?: Currency;\n /** TIME when the charge becomes billable on ExpectedBillableDate, or MANUAL when a person marks it billable. */\n triggerType?: ChargeTriggerType;\n /** The price of one unit behind the charge, or null when TotalPrice was not computed from one. */\n unitPrice?: Currency | null;\n}\n\nexport interface ChargeMarkedBillable {\n /** The billable charge created for the quantity billed now, or null when the whole charge was billed. */\n newCharge?: Charge | null;\n /** The charge the request named, which keeps the quantity not billed when the charge was split. */\n updatedCharge?: Charge;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ChargeMode = \"CONFIRMED\" | \"PENDING\";\n\nexport interface ChargePage {\n /** The charges on this page. */\n results?: ChargeListItem[];\n /** The number of charges the filters match, across every page. */\n totalCount?: number;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ChargeStatus = \"BILLABLE\" | \"CANCELLED\" | \"INVOICED\" | \"PLANNED\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ChargeTriggerType = \"EVENT\" | \"MANUAL\" | \"TIME\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CompanyType = \"CUSTOMER\" | \"MANUFACTURER\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CostAdjustmentReason = \"ADDITION\" | \"BETTERMENT\" | \"DAMAGE\" | \"INSTALLATION\" | \"LIFE_EXTENSION\" | \"MARKET_DECLINE\" | \"OBSOLESCENCE\" | \"OTHER\" | \"REGULATORY\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CostAdjustmentType = \"CAPITALIZATION\" | \"IMPAIRMENT\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type CostBasisMode = \"ADVANCED\" | \"SIMPLE\" | null;\n\n/** The kind of credential a request was made with. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `API_KEY` | An API key, for an integration that runs unattended | | `OAUTH` | An OAuth access token, issued to an application a person connected | | `SESSION` | A person signed in to Hardfin in a browser | */\nexport type CredentialType = \"API_KEY\" | \"OAUTH\" | \"SESSION\";\n\nexport interface Currency {\n /** The value as a decimal string with two decimal places. */\n amount?: string;\n /** The value's ISO 4217 currency code. */\n isoCode?: string;\n}\n\nexport type Customer = SparseCustomer & {\n /** The number of the customer's active projects. */\n activeProjectCt?: number;\n /** The number of assets the customer owns. */\n assetCount?: number;\n /** The number of assets at the customer's locations. */\n assetsAtLocation?: number;\n /** The address invoices are sent to. */\n billingAddress?: string | null;\n /** The person who receives the customer's invoices. */\n billingContact?: CustomerBillingContact | null;\n /** A free-form note about the customer. */\n comment?: string | null;\n /** The customer's web domain, used to look up its logo. */\n domain?: string | null;\n /** The customer's identifier in another system. */\n externalId?: string | null;\n /** The number of the customer's incomplete projects. */\n incompleteProjectCt?: number;\n /** The customer's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** The number of the customer's locations. */\n locationCount?: number;\n /** The customer's locations. */\n locations?: SparseLocationWithParent[];\n /** The storage key of the customer's logo file. */\n logoFileKey?: string | null;\n /** The number of the customer's past projects. */\n pastProjectCt?: number;\n /** The number of the customer's upcoming projects. */\n upcomingProjectCt?: number;\n};\n\nexport interface CustomerBillingContact {\n /** The billing contact's email address. */\n email?: string | null;\n /** The billing contact's name. */\n name?: string | null;\n /** The billing contact's phone number. */\n phone?: string | null;\n}\n\nexport interface CustomerListing {\n /** The page of records. */\n results?: Customer[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type Depreciation = \"DOUBLE_DECLINING\" | \"STRAIGHT_LINE\" | \"SUM_YEAR\" | \"UNIT_OF_PRODUCTION\" | null;\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type EntityType = \"ASSET\" | \"BILLING\" | \"BILLING_PLAN\" | \"CHARGE\" | \"CONTACT\" | \"COST\" | \"CUSTOMER\" | \"FULFILLMENT_ORDER\" | \"INVOICE\" | \"ITEM\" | \"LOCATION\" | \"ORGANIZATION\" | \"PERSON\" | \"PROJECT\" | \"PURCHASE_ORDER\" | \"RETURN_ORDER\" | \"SHIPMENT\" | \"TIME_RECORD\";\n\nexport interface Error {\n error: string;\n statusCode: number;\n}\n\nexport interface FileNewUpload {\n /** The uploaded file's unique identifier. */\n fileId?: string;\n /** The uploaded file's key, which the file endpoints take as fileKey. */\n fileKey?: string;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type FrontendItemType = \"BULK\" | \"DEVICE\" | \"SERVICE\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type IntegrationCategory = \"CRM\" | \"ERP\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type IntegrationID = \"HUBSPOT\" | \"NETSUITE\" | \"NONE\" | \"QBO\" | \"SFDC\";\n\nexport interface Item {\n /** Whether a BULK item records serial numbers on its units, which is false for SERVICE and DEVICE items. */\n acceptsBulkSerials?: boolean;\n /** The number of assets of a DEVICE item, and null for other types. */\n assetCount?: number | null;\n /** A free-form description of the item. */\n description?: string | null;\n /** The item's unique identifier. */\n id?: string;\n /** The item's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** Whether the item is archived. */\n isArchived?: boolean;\n /** The item's key, which the item endpoints take as itemKey. */\n key?: string;\n /** When the item was last changed. */\n lastUpdatedAt?: string | null;\n /** The person who last changed the item. */\n lastUpdatedBy?: SparsePerson;\n /** The item's display name. */\n name?: string;\n /** Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. */\n shouldRenderSerialFields?: boolean;\n /** The item's stock keeping unit, unique within your organization. */\n sku?: string;\n /** SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. */\n type?: FrontendItemType;\n}\n\nexport interface ItemAccounting {\n /** The default share of overhead for one unit. */\n allocatedIndirect?: string | null;\n /** The default parts cost for one unit. */\n billOfMaterials?: string | null;\n /** The default method one unit is depreciated by. */\n depreciationModel?: Depreciation;\n /** The default labor cost to build one unit. */\n directLabor?: string | null;\n /** The default shipping cost to receive one unit. */\n freightInbound?: string | null;\n /** The default shipping cost to deliver one unit. */\n freightOutbound?: string | null;\n /** The default cost to install one unit. */\n installation?: string | null;\n /** The default financing cost for one unit. */\n interest?: string | null;\n /** The default value one unit keeps at the end of its useful life. */\n salvageValue?: string | null;\n /** A single default cost for one unit, used instead of the cost components. */\n simpleCostBasis?: string | null;\n /** The default import duty paid on one unit. */\n tariffs?: string | null;\n /** The default tax paid on one unit. */\n tax?: string | null;\n /** The default cost of goods sold for one unit, which is the simple cost basis when set and otherwise the sum of the cost components. */\n totalCOGS?: string | null;\n /** The default number of months one unit is depreciated over. */\n usefulLife?: number | null;\n}\n\nexport interface ItemBOMItem {\n /** The BULK part the bill of materials uses. */\n item?: SparseItem;\n /** The number of the part one unit of the item uses. */\n quantity?: number;\n}\n\nexport interface ItemDetail {\n /** Whether a BULK item records serial numbers on its units, which is false for SERVICE and DEVICE items. */\n acceptsBulkSerials?: boolean;\n /** The default costs and depreciation for a unit of a DEVICE or BULK item. */\n accounting?: ItemAccounting;\n /** The number of assets of a DEVICE item, and null for other types. */\n assetCount?: number | null;\n /** The bill of materials, the BULK parts one unit of the item is built from, or null when it has none. */\n bom?: ItemBOMItem[] | null;\n /** The pricing a project line item's billing plan starts from when it sells the item, or null when the item has none. */\n defaultPricing?: ItemPricing | null;\n /** A free-form description of the item. */\n description?: string | null;\n /** The custom fields each asset of a DEVICE item can hold. */\n fields?: ItemField[];\n /** Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. */\n hasAssets?: boolean;\n /** The item's unique identifier. */\n id?: string;\n /** The item's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** The number of inventory movements of a BULK item, and null for other types. */\n inventoryMovementCount?: number | null;\n /** Whether the item is archived. */\n isArchived?: boolean;\n /** Whether the item is physical, which is true for DEVICE and BULK items. */\n isPhysical?: boolean;\n /** The item's key, which the item endpoints take as itemKey. */\n key?: string;\n /** When the item was last changed. */\n lastUpdatedAt?: string | null;\n /** The person who last changed the item. */\n lastUpdatedBy?: SparsePerson;\n /** The item's display name. */\n name?: string;\n /** Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. */\n shouldRenderSerialFields?: boolean;\n /** The item's stock keeping unit, unique within your organization. */\n sku?: string;\n /** SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. */\n type?: FrontendItemType;\n}\n\nexport interface ItemField {\n /** The field's unique identifier. */\n id?: string;\n /** The field's key, which the item field endpoints take as fieldKey. */\n key?: string;\n /** The field's display name. */\n label?: string;\n /** The number of assets that hold a value for the field. */\n metadataCount?: number;\n /** The field's position within its section, starting at 0. */\n order?: number;\n /** The group the field is shown in, starting at 0. */\n section?: number;\n /** The kind of value the field holds. */\n type?: ItemFieldType;\n}\n\nexport interface ItemFieldOrderingUpdateItem {\n /** The ID of the item field to move. */\n fieldId: string;\n /** The field's position within its section, starting at 0. */\n order?: number;\n /** The group the field is shown in, starting at 0. */\n section?: number;\n}\n\n/** The kind of value an item's custom field holds. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ItemFieldType = \"BOOLEAN\" | \"DATE\" | \"DATE_TIME\" | \"INTEGER\" | \"MULTILINE_TEXT\" | \"NUMBER\" | \"TEXT\" | \"TIME\";\n\nexport interface ItemListing {\n /** The page of records. */\n results?: Item[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\nexport interface ItemPricing {\n /** How often a PERIODIC charge recurs. */\n chargeFrequency?: BillingFrequency | null;\n /** PERIODIC to charge on a recurring cadence, or MILESTONE to charge when a milestone is reached. */\n chargeSchedule?: BillingSchedule | null;\n /** The default price for the whole line, used when pricingMode is FIXED. */\n fixedPrice?: Currency | null;\n /** How often the charges are invoiced. */\n invoiceFrequency?: BillingFrequency | null;\n /** ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends. */\n invoiceMode?: BillingTiming | null;\n /** PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price for the line whatever its quantity. */\n pricingMode?: PricingMode | null;\n /** The default price for each unit, used when pricingMode is PER_UNIT. */\n unitPrice?: Currency | null;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ItemType = \"marked_bulk\" | \"service\" | \"tracked_device\" | \"unmarked_bulk\";\n\nexport type Location = SparseLocationWithIntegration & {\n /** The number of active projects at the location. */\n activeProjectCount?: number;\n /** The number of assets currently at the location. */\n assetCount?: number;\n /** The number of incomplete projects at the location. */\n incompleteProjectCount?: number;\n /** The number of past projects at the location. */\n pastProjectCount?: number;\n /** The number of upcoming projects at the location. */\n upcomingProjectCount?: number;\n};\n\nexport interface LocationListing {\n /** The page of records. */\n results?: Location[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type LocationType = \"SITE\" | \"ZONE\" | null;\n\nexport interface Metadata {\n errors: Error[] | null;\n /** What the client should know about its request, beside any error. A notice never fails a request. */\n notices?: Notice[];\n /** The identifier to quote when asking Hardfin about this request. */\n requestId: string;\n /** How long the server took to answer. */\n requestTime: string;\n statusCode: number;\n}\n\nexport interface MetadataLocationComponents {\n /** The first line of the street address. */\n addressLine1?: string | null;\n /** The second line of the street address, such as a suite. */\n addressLine2?: string | null;\n /** The city. */\n city?: string | null;\n /** The country. */\n country?: string | null;\n /** The whole address on one line. */\n formattedAddress?: string | null;\n /** The postal or ZIP code. */\n postalCode?: string | null;\n /** The state or region. */\n state?: string | null;\n}\n\nexport interface MetadataLocationSite {\n /** The location's structured address, which a zone reads from its parent site. */\n address?: MetadataLocationComponents | null;\n /** Google's place ID for the address, when it was found through Google. */\n googlePlaceId?: string | null;\n /** The location's latitude, sent as a decimal string. */\n latitude?: string | null;\n /** The location's longitude, sent as a decimal string. */\n longitude?: string | null;\n /** The person or business that receives shipments at the location. */\n shippingName?: string | null;\n}\n\nexport interface MetadataMilestonePhaseEntry {\n /** The phase's name, which its charge takes as a label, 255 characters or less. */\n name?: string;\n /** The share of the line item's total the phase bills, from 0 to 100. */\n percentage?: string | null;\n}\n\nexport interface MetadataMilestonePhases {\n /** The phases, in order. */\n entries?: MetadataMilestonePhaseEntry[];\n /** PERCENTAGE, the only way a phase's share is expressed. */\n mode?: string;\n}\n\nexport interface Notice {\n /** What the notice is about. API_VERSION_OUTDATED means an earlier version of the endpoint answered, because X-API-Version is behind its last change. Ignore a code that is not recognized. */\n code: string;\n /** The X-API-Version to move to so the notice stops. */\n latestVersion: string;\n message: string;\n}\n\nexport interface PaymentTerm {\n /** The payment term's identifier. */\n id?: string;\n /** The payment term's key. */\n key?: string;\n /** The payment term's name as people read it. */\n label?: string;\n /** The number of days after the invoice date that payment is due. */\n netDays?: number;\n /** The payment term's machine name. */\n value?: string;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type PricingMode = \"FIXED\" | \"PER_UNIT\";\n\nexport type Project = SparseProject & {\n /** The day the customer accepted the project. */\n acceptanceDate?: string | null;\n /** The workflow the project is on, with the project's current stage marked active, or null when it has no workflow. */\n activeWorkflow?: SparseActiveWorkflow | null;\n /** The project's annual recurring revenue, with one total for each currency its recurring line items are priced in. */\n annualRecurringRevenue?: ProjectCurrencyAmount[];\n /** The billing address the project's invoices use in place of the customer's. */\n billingAddress?: string | null;\n /** The billing contact email the project's invoices use in place of the customer's. */\n billingContactEmail?: string | null;\n /** The billing contact name the project's invoices use in place of the customer's. */\n billingContactName?: string | null;\n /** The billing contact phone number the project's invoices use in place of the customer's. */\n billingContactPhone?: string | null;\n /** The number of charges on the project's line items. */\n chargeCount?: number;\n /** What follows the project for its customer: it was renewed, the customer kept a later-ending project, or nothing followed. */\n completionClassification?: ProjectCompletionClassification;\n /** The day the contract was signed. */\n contractSignedOn?: string | null;\n /** The number of costs recorded against the project. */\n costCount?: number;\n /** The project's single currency and the field that established it, or null when no currency-bearing field is set. */\n currency?: ProjectCurrency | null;\n /** The customer the project is for. */\n customer?: SparseCustomer | null;\n /** The project's default location, which counts among its locations even when no line item names it. */\n defaultLocation?: SparseLocationWithParent | null;\n /** The project's description. */\n description?: string | null;\n /** The discount applied to the project. */\n discount?: Currency | null;\n /** The number of files attached to the project. */\n fileCount?: number;\n /** The day the project goes live. */\n goLiveDate?: string | null;\n /** The day of the installation. */\n installDate?: string | null;\n /** The number of the project's charges that have been invoiced. */\n invoicedChargeCount?: number;\n /** The project's line items, each an item the project sells or provides as a service. */\n items?: ProjectLineItem[];\n /** Every location the project names: the ones its line items ask for, and its default location. */\n locations?: SparseLocationWithParent[];\n /** The memo new invoices for the project carry. */\n memo?: string | null;\n /** The number of notes on the project. */\n noteCount?: number;\n /** The project's payment term. */\n paymentTerm?: PaymentTerm | null;\n /** The project this one renews. */\n previousProject?: SparseProject | null;\n /** Whether the items the project asks for have been fulfilled, judged across all of its line items. */\n projectFulfillmentStatus?: ProjectFulfillmentStatus;\n /** The customer's purchase order number, which new invoices for the project carry. */\n purchaseOrderNumber?: string | null;\n /** The day of the site visit. */\n siteVisitDate?: string | null;\n /** How the project relates to the customer's earlier projects: a renewal of a prior project, new business, or an expansion. */\n startClassification?: ProjectStartClassification;\n /** The number of tickets on the project. */\n ticketCount?: number;\n /** The number of time activities recorded against the project. */\n timeActivityCount?: number;\n /** The contract's total value, as entered on the project. */\n totalContractValue?: Currency | null;\n /** The day of the training. */\n trainingDate?: string | null;\n /** The number of URL links attached to the project. */\n urlLinkCount?: number;\n};\n\nexport interface ProjectChargeRequestItem {\n /** The day the charge is planned to become billable, or null when it has no dates yet. */\n expectedBillableDate?: string | null;\n /** The charge to update, or null to add a new one, and no two charges in the list send the same one. */\n id?: string | null;\n /** True when a person added, edited or split the charge, and false when it follows the line item's billing plan unchanged. */\n isCustomModified?: boolean;\n /** The charge's display name, such as the period it covers or the milestone it follows, which is required and 255 characters or less once the spaces around it are trimmed. */\n label?: string;\n /** PER_UNIT when the charge bills a unit price for each unit, or FIXED when it bills a flat amount. */\n pricingMode?: PricingMode;\n /** The number of units the charge bills, which is at least 1 when UnitPrice is sent and 2,147,483,647 or less. */\n quantity?: number;\n /** The charge's position among its line item's charges, in ascending order, which is zero or more and sent by one charge in the list. */\n sequence?: number;\n /** The last day of the period the charge covers, on or after ServicePeriodStart. */\n servicePeriodEnd?: string | null;\n /** The first day of the period the charge covers, or null when the charge has no dates yet. */\n servicePeriodStart?: string | null;\n /** The charge's status: PLANNED, BILLABLE, INVOICED or CANCELLED. */\n status?: ChargeStatus;\n /** The amount the charge bills, which equals UnitPrice times Quantity when UnitPrice is sent. */\n totalPrice?: Currency;\n /** TIME when the charge becomes billable on ExpectedBillableDate, or MANUAL when a person marks it billable, and is TIME when omitted. */\n triggerType?: ChargeTriggerType;\n /** The price of one unit, in the currency of TotalPrice, and is null on a FIXED charge. */\n unitPrice?: Currency | null;\n}\n\n/** What follows a project for its customer when it ends. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ProjectCompletionClassification = \"CHURN\" | \"CONTRACTION\" | \"RENEWED\";\n\nexport interface ProjectCurrency {\n /** The ISO 4217 code of the project's currency. */\n isoCode?: string;\n /** What fixed the project's currency: an invoiced charge, the contract value, the line items, or the discount. */\n source?: ProjectCurrencySource;\n}\n\nexport interface ProjectCurrencyAmount {\n /** The amount, in the currency IsoCode names. */\n amount?: string;\n /** The amount's ISO 4217 currency code. */\n isoCode?: string;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ProjectCurrencySource = \"DISCOUNT\" | \"INVOICED_CHARGE\" | \"LINE_ITEMS\" | \"PROJECT_VALUE\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ProjectFulfillmentStatus = \"FULFILLED\" | \"OVER_FULFILLED\" | \"PARTIALLY_FULFILLED\" | \"UNFULFILLED\";\n\nexport interface ProjectItemBinding {\n /** The day a periodic line item's charge schedule is anchored on, which defaults to StartOn. */\n activationDate?: string | null;\n /** The identifier that makes line items consecutive phases of one commitment when they send the same one, and is assigned when a new line item omits it. */\n aggregationKey?: string;\n /** The line item's single billing cadence, which fills ChargeFrequency and InvoiceFrequency on a periodic line item that omits them. */\n billingFrequency?: BillingFrequency | null;\n /** How often a periodic line item creates a charge, and is refused unless ChargeSchedule is PERIODIC. */\n chargeFrequency?: BillingFrequency | null;\n /** PERIODIC when charges recur at a regular frequency, or MILESTONE when each charge follows a project milestone. */\n chargeSchedule?: BillingSchedule | null;\n /** A free-form note about the line item, 65,536 characters or less. */\n details?: string | null;\n /** The last day of the line item's service window, on or after StartOn. */\n endOn?: string | null;\n /** The flat price when PricingMode is FIXED, and is not sent together with UnitPrice. */\n fixedPrice?: Currency | null;\n /** The line item to update, or omitted to add a new one. */\n id?: string | null;\n /** How often a periodic line item's charges are invoiced, which is never more often than ChargeFrequency. */\n invoiceFrequency?: BillingFrequency | null;\n /** ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends, and is refused unless ChargeSchedule is PERIODIC. */\n invoiceMode?: BillingTiming | null;\n /** The catalog item the line item is for. */\n itemId: string;\n /** The location the line item is for. */\n locationId?: string | null;\n /** The named phases of a milestone line item and each one's share of its total. */\n milestonePhases?: MetadataMilestonePhases | null;\n /** PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price whatever the quantity. */\n pricingMode?: PricingMode | null;\n /** The number of units the line item covers, which is zero or more. */\n quantity?: number;\n /** The first day of the line item's own service window, sent together with EndOn. */\n startOn?: string | null;\n /** A negotiated total for a periodic line item that replaces the computed one, in the project's currency. */\n totalOverride?: Currency | null;\n /** SALE to sell the item, which only a physical item allows, or SERVICE to provide it as a service. */\n transactionType: TransactionType;\n /** The price of one unit for each charge, and is not sent together with FixedPrice. */\n unitPrice?: Currency | null;\n}\n\nexport interface ProjectLineItem {\n /** The day a periodic line item's charge schedule is anchored on, or null while ChargeMode is PENDING and on a milestone line item. */\n activationDate?: string | null;\n /** The identifier shared by line items that are consecutive phases of one commitment, and unique to a line item that stands alone. */\n aggregationKey?: string;\n /** The line item's single billing cadence, which predates ChargeFrequency and InvoiceFrequency. */\n billingFrequency?: BillingFrequency | null;\n /** How often a periodic line item creates a charge, and is null on a milestone line item. */\n chargeFrequency?: BillingFrequency | null;\n /** CONFIRMED when the line item's charges carry dates, or PENDING when its activation date is not yet known and they do not. */\n chargeMode?: ChargeMode;\n /** PERIODIC when charges recur at a regular frequency, or MILESTONE when each charge follows a project milestone, and is null until the line item has a billing plan. */\n chargeSchedule?: BillingSchedule | null;\n /** The line item's charges, in Sequence order. */\n charges?: Charge[];\n /** A free-form note about the line item. */\n details?: string | null;\n /** The last day of the line item's service window. */\n endOn?: string | null;\n /** The flat price when PricingMode is FIXED: the amount of each charge on a periodic line item, and the total its phases split on a milestone one. */\n fixedPrice?: Currency | null;\n /** True when any of the line item's charges is invoiced, which stops the line item from being removed. */\n hasInvoicedCharges?: boolean;\n /** The line item's unique identifier. */\n id?: string;\n /** How often a periodic line item's charges are invoiced, which is never more often than ChargeFrequency. */\n invoiceFrequency?: BillingFrequency | null;\n /** ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends, on a periodic line item. */\n invoiceMode?: BillingTiming | null;\n /** The catalog item the line item is for. */\n item?: SparseItem;\n /** The line item's key. */\n key?: string;\n /** The location the line item is for, or null when it has none. */\n location?: SparseLocationWithParent | null;\n /** The named phases of a milestone line item and each one's share of its total, or null on any other line item. */\n milestonePhases?: MetadataMilestonePhases | null;\n /** The line item's position among the line items sharing its AggregationKey, counted from 1 in order of StartOn. */\n phaseRowNumber?: number;\n /** PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price whatever the quantity, and is null until the line item has a billing plan. */\n pricingMode?: PricingMode | null;\n /** The number of units the line item covers. */\n quantity?: number | null;\n /** The first day of the line item's own service window, or null when it has no dates. */\n startOn?: string | null;\n /** A negotiated total for a periodic line item that replaces the computed one, or null to use the computed total. */\n totalOverride?: Currency | null;\n /** SALE when the item is sold, or SERVICE when it is provided as a service. */\n transactionType?: TransactionType;\n /** The price of one unit for each charge, or null when the line item is priced at a fixed price. */\n unitPrice?: Currency | null;\n}\n\nexport interface ProjectListing {\n /** The page of records. */\n results?: Project[];\n /** The number of records that match the filters, across every page. */\n totalCount?: number;\n}\n\n/** How a project relates to the customer's earlier projects when it starts. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ProjectStartClassification = \"EXPANSION\" | \"NEW_BUSINESS\" | \"RENEWAL\";\n\n/** Where a project stands against its dates, which is computed and never stored. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ProjectStatus = \"ACTIVE\" | \"DATE_RANGE_INCOMPLETE\" | \"PAST\" | \"UPCOMING\";\n\n/** A project status the project list and the fulfillment report filter by. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ProjectStatusFilter = \"ACTIVE\" | \"DATE_RANGE_INCOMPLETE\" | \"PAST\" | \"UPCOMING\";\n\n/** The condition that stops a resolution the hold's type allows from running. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type QuarantineResolutionBlockReason = \"SERIAL_ALREADY_TAKEN\";\n\n/** How a user resolved a quarantined serial. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type QuarantineResolutionKind = \"ACCEPTED_SERIAL\" | \"CORRECTED_SERIAL\" | \"CREATED_ASSET\" | \"KEPT_HARDFIN_ITEM\" | \"UPDATED_EXISTING_ASSET\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type QuarantineType = \"DUPLICATE_ALREADY_EXISTS\" | \"DUPLICATE_IN_ORDER\" | \"MISSING_SERIAL\" | \"SERIAL_PATTERN_MISMATCH\" | \"SKU_TRANSMUTATION\" | \"UNKNOWN_SERIAL\";\n\n/** The item type a request asks an item to become. Accepted in any case. The listed spelling is the one the API sends back. */\nexport type RequestedItemType = \"BULK\" | \"DEVICE\" | \"SERVICE\";\n\n/** Accepted in any case, and also as t, f, 1, 0, or 2 for all. The listed spelling is the one the API sends back. */\nexport type ScrappedState = \"all\" | \"false\" | \"true\";\n\nexport interface SharedBool {\n /** Whether the operation completed. */\n success?: boolean;\n}\n\nexport interface SharedIntegration {\n /** The Hardfin error code of the failed sync, or null when the sync did not fail. */\n errorCode?: number | null;\n /** The integrated system, such as SFDC or HUBSPOT. */\n id?: IntegrationID;\n /** Whether the last sync with the external system failed. */\n inError?: boolean;\n /** Whether a sync with the external system is pending. */\n isSyncing?: boolean;\n /** The system's display name. */\n label?: string;\n /** A URL to the linked record in the external system. */\n link?: string | null;\n /** Whether the record differs from the external system and needs a person to review it. */\n needsReview?: boolean;\n /** The kind of system, CRM or ERP. */\n type?: IntegrationCategory;\n}\n\nexport interface Shipment {\n /** When the shipment was cancelled, or null while it has not been. */\n cancelledAt?: string | null;\n /** The ID of the user who cancelled the shipment, or null while it has not been cancelled. */\n cancelledBy?: string | null;\n /** Why the shipment was cancelled, or null while it has not been. */\n cancelledReason?: string | null;\n /** Who carries the shipment, or null when no carrier is named. */\n carrier?: Carrier | null;\n /** When the shipment was created. */\n createdAt?: string;\n /** Who created the shipment. */\n createdBy?: SparsePerson;\n /** How long the shipment spent in each stage. */\n cycleTime?: ShipmentCycleTime;\n /** When the shipment arrived, or null while it has not. */\n deliveredAt?: string | null;\n /** The IANA time zone DeliveredAt was recorded in, or null when none was recorded. */\n deliveredAtTimezone?: string | null;\n /** The note written when the shipment was delivered, or null. */\n deliveryNote?: string | null;\n /** The sum of the lines' estimated values, or null when no line has an estimate. */\n estimatedTotalValue?: string | null;\n /** When the carrier now expects to deliver, or null when it says nothing. */\n eta?: string | null;\n /** The day the shipment is expected to arrive, or null when no one has said. */\n expectedDeliveredOn?: string | null;\n /** The day the shipment is expected to leave, or null when no one has said. */\n expectedShippedOn?: string | null;\n /** Where the shipment leaves from, or null when an inbound shipment names no origin. */\n fromLocation?: SparseLocationWithIntegration | null;\n /** The fulfillment order an outbound shipment fills, or null when it fills none. */\n fulfillmentOrder?: SparseFulfillment | null;\n /** The shipment's unique identifier. */\n id?: string;\n /** The shipment's line items. */\n items?: ShipmentLineItem[];\n /** The shipment's key, which the shipment endpoints take as shipmentKey. */\n key?: string;\n /** The carrier's name when Carrier is other, or null. */\n otherCarrier?: string | null;\n /** The purchase order an inbound shipment fills, or null when it fills none. */\n purchaseOrder?: SparsePurchaseOrder | null;\n /** The note written when the shipment was received, or null. */\n receiptNote?: string | null;\n /** When an inbound shipment's items were received, or null while they have not been. */\n receivedAt?: string | null;\n /** The IANA time zone ReceivedAt was recorded in, or null when none was recorded. */\n receivedAtTimezone?: string | null;\n /** The number the carrier tracks the shipment by, or null when it has none. */\n referenceNumber?: string | null;\n /** The return order an inbound shipment fills, or null when it fills none. */\n returnOrder?: SparseReturnOrder | null;\n /** The carrier's service the shipment travels on, or null when the carrier names none. */\n serviceLevelName?: string | null;\n /** The note written about the shipment itself, or null. */\n shipmentNote?: string | null;\n /** The number the shipment is known by. */\n shipmentNumber?: string;\n /** Whether the shipment is INBOUND to the organization or OUTBOUND from it. */\n shipmentType?: ShipmentType | null;\n /** When the shipment left, or null while it has not. */\n shippedAt?: string | null;\n /** The IANA time zone ShippedAt was recorded in, or null when none was recorded. */\n shippedAtTimezone?: string | null;\n /** What the shipment cost to send, or null when no cost is recorded. */\n shippingCost?: Currency | null;\n /** Where the shipment is in its life: OPEN, SHIPPED, DELIVERED, RECEIVED or CANCELLED. */\n status?: ShipmentStatus;\n /** Whether a third-party provider holds the shipment, which refuses changes made through the API. */\n thirdPartyBound?: boolean;\n /** How many days the shipment has held its status, or null once it is received or cancelled. */\n timeInStatusDays?: string | null;\n /** Where the shipment is going. */\n toLocation?: SparseLocationWithIntegration;\n /** What the shipment's assets are worth, or null when it has none to value. */\n totalValue?: string | null;\n}\n\nexport interface ShipmentCycleTime {\n /** The days from the shipment's creation to its ship time, or null while it has not shipped. */\n createdToShippedDays?: string | null;\n /** The days from the shipment's ship time to its delivery, or null while it has not been delivered. */\n shippedToDeliveredDays?: string | null;\n}\n\nexport interface ShipmentItem {\n /** The line's identifier in another system, or null when it has none. */\n externalReference?: string | null;\n /** The ID of the item the line carries. */\n itemId?: string;\n /** How many units the line ships, which an outbound shipment requires above 0 and an inbound shipment may leave null. */\n quantity?: number | null;\n /** The serial numbers of the units, for an item that is tracked by serial. */\n serials?: string[];\n}\n\nexport interface ShipmentLineItem {\n /** What the line was estimated to be worth while the shipment was open, or null when no estimate was made. */\n estimatedValue?: string | null;\n /** The line's identifier in the system that reported it, or null when it has none. */\n externalReference?: string | null;\n /** The item the line carries. */\n item?: SparseItem;\n /** The number of serial numbers in PendingSerials. */\n pendingSerialCount?: number;\n /** The serial numbers a third-party provider has reported but not yet confirmed as shipped. */\n pendingSerials?: string[];\n /** How many units the line ships, or null when the line was added without one. */\n quantity?: number | null;\n /** How many units arrived, or null until an inbound shipment is received. */\n receivedQuantity?: number | null;\n /** The number of serial numbers in Serials. */\n serialCount?: number;\n /** The serial numbers of the line's units, which is empty for an item that is not tracked by serial. */\n serials?: string[];\n /** What the line's assets are worth, or null when it has none to value. */\n value?: string | null;\n}\n\nexport interface ShipmentListing {\n /** The shipments on the page. */\n results?: Shipment[];\n /** The number of shipments the filters match, across every page. */\n totalCount?: number;\n}\n\nexport interface ShipmentReceiveItem {\n /** The line's identifier in another system, or null when it has none. */\n externalReference?: string | null;\n /** The ID of the item that arrived, which may be named once. */\n itemId?: string;\n /** How many units arrived, which is required and may be 0 for a line that did not arrive. */\n quantity?: number | null;\n /** The serial numbers of the units that arrived, for an item that is tracked by serial. */\n serials?: string[];\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ShipmentStatus = \"CANCELLED\" | \"DELIVERED\" | \"OPEN\" | \"RECEIVED\" | \"SHIPPED\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type ShipmentType = \"INBOUND\" | \"OUTBOUND\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type SortOrder = \"ASC\" | \"DESC\";\n\nexport interface SparseActiveWorkflow {\n id?: string;\n key?: string;\n name?: string;\n stages?: SparseWorkflowStage[];\n}\n\nexport interface SparseAsset {\n /** Whether the asset works, is broken, awaits review, or has been scrapped. */\n functionalStatus?: AssetFunctionalStatus;\n /** The asset's unique identifier. */\n id?: string;\n /** The day the asset entered inventory. */\n inInventoryDate?: string;\n /** Whether the asset is archived. */\n isArchived?: boolean;\n /** Whether the asset has shipped and not yet been delivered. */\n isInTransit?: boolean;\n /** The catalog item the asset is a unit of. */\n item?: SparseItem;\n /** The asset's key, which the asset endpoints take as assetKey. */\n key?: string;\n /** The asset's serial number, unique within its item. */\n serial?: string;\n}\n\nexport interface SparseCustomer {\n /** The customer's unique identifier. */\n id?: string;\n /** Whether the customer is archived. */\n isArchived?: boolean;\n /** Whether the company is a customer. */\n isCustomer?: boolean;\n /** Whether the company is a supplier. */\n isSupplier?: boolean;\n /** The customer's key, which the customer endpoints take as customerKey. */\n key?: string;\n /** The customer's display name. */\n name?: string;\n}\n\nexport interface SparseFulfillment {\n /** The number the fulfillment order is known by. */\n foNumber?: string;\n /** The fulfillment order's unique identifier. */\n id?: string;\n /** Whether a third-party provider fulfills the order. */\n isThirdPartyFulfilled?: boolean;\n /** The fulfillment order's key. */\n key?: string;\n}\n\nexport interface SparseItem {\n /** Whether each unit of the item is tracked as its own asset, which is true for a DEVICE item. */\n hasAssets?: boolean;\n /** The item's unique identifier. */\n id?: string;\n /** Whether the item is archived. */\n isArchived?: boolean;\n /** Whether the item is physical, which is true for DEVICE and BULK items. */\n isPhysical?: boolean;\n /** The item's key, which the item endpoints take as itemKey. */\n key?: string;\n /** The item's display name. */\n name?: string;\n /** Whether the item's units carry serial numbers, which is true for a DEVICE item and for a BULK item that accepts serials. */\n shouldRenderSerialFields?: boolean;\n /** The item's stock keeping unit, unique within your organization. */\n sku?: string;\n /** SERVICE for a non-physical item, DEVICE for a physical item tracked by serial number, or BULK for a part tracked by quantity. */\n type?: FrontendItemType;\n /** The unit the item's quantities are counted in. */\n unitOfMeasure?: UnitOfMeasure;\n}\n\nexport type SparseLocation = MetadataLocationSite & {\n /** The number of archived zones at a site. */\n archivedZoneCount?: number;\n /** The customer a zone is designated for, such as for reservations, provisioning or a 3PL. */\n consignee?: SparseCustomer | null;\n /** The customer the location is assigned to, which a zone reads from its parent site, or null for your organization's own locations. */\n customer?: SparseCustomer | null;\n /** A free-form description of a zone. */\n description?: string | null;\n /** The location's unique identifier. */\n id?: string;\n /** Whether Google resolved the site's address, which is always false for a zone. */\n isAddressGeocoded?: boolean;\n /** Whether the location is archived. */\n isArchived?: boolean;\n /** Whether assets at the location count as inventory for reporting. */\n isInventory?: boolean;\n /** Whether a zone sets its own isInventory rather than inheriting its parent site's. */\n isInventoryOverride?: boolean;\n /** Whether a third-party logistics (3PL) provider fulfills orders from the location. */\n isThirdPartyEnabled?: boolean;\n /** Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default. */\n isTransient?: boolean;\n /** The location's key, which the location endpoints take as locationKey. */\n key?: string;\n /** The location's display name. */\n name?: string;\n /** The 3PL provider's identifier for the location. */\n thirdPartyIdentifier?: string | null;\n /** SITE for a site, or ZONE for a zone within a site. */\n type?: LocationType;\n /** The number of zones at a site. */\n zoneCount?: number;\n /** The site's zones. */\n zones?: SparseZone[];\n};\n\nexport type SparseLocationWithIntegration = SparseLocationWithParent & {\n /** The location's links to integrated systems. */\n integrations?: SharedIntegration[];\n};\n\nexport type SparseLocationWithParent = SparseLocation & {\n /** The site a zone belongs to, or null for a site. */\n parentLocation?: SparseLocation | null;\n};\n\nexport interface SparseOrganization {\n /** The organization's ID */\n id?: string;\n /** The public identifier that can be used in URLs */\n key?: string;\n /** The name of the organization */\n name?: string;\n}\n\nexport interface SparsePerson {\n /** The person's first name. */\n firstName?: string | null;\n /** The person's unique identifier. */\n id?: string;\n /** The person's key. */\n key?: string;\n /** The person's last name. */\n lastName?: string | null;\n}\n\nexport interface SparseProject {\n /** The customer the project is for. */\n customer?: SparseCustomer | null;\n /** The day the project ends. */\n endOn?: string | null;\n /** The project's unique identifier. */\n id?: string;\n /** The project's links to integrated systems. */\n integrations?: SharedIntegration[];\n /** Whether the project is archived. */\n isArchived?: boolean;\n /** The project's key. */\n key?: string;\n /** The project's display name. */\n name?: string;\n /** The name of the project's payment term. */\n paymentTermLabel?: string | null;\n /** The customer's purchase order number, which new invoices for the project carry. */\n purchaseOrderNumber?: string | null;\n /** The day the project starts. */\n startOn?: string | null;\n /** Whether the project is upcoming, active, or past, judged from its dates. */\n status?: ProjectStatus;\n}\n\nexport interface SparsePurchaseOrder {\n /** The supplier's own number for the purchase order, or null when it has none. */\n externalPoNumber?: string | null;\n /** The purchase order's unique identifier. */\n id?: string;\n /** The purchase order's key. */\n key?: string;\n /** The number the purchase order is known by. */\n poNumber?: string;\n}\n\nexport interface SparseReturnOrder {\n /** The return order's unique identifier. */\n id?: string;\n /** The return order's key. */\n key?: string;\n /** The number the return order is known by. */\n roNumber?: string;\n}\n\nexport interface SparseShipment {\n /** When the shipment arrived, or null while it has not. */\n deliveredAt?: string | null;\n /** The shipment's unique identifier. */\n id?: string;\n /** The shipment's key. */\n key?: string;\n /** The number the shipment is known by. */\n shipmentNumber?: string;\n /** What kind of movement the shipment carries. */\n shipmentType?: string;\n /** When the shipment left, or null while it has not. */\n shippedAt?: string | null;\n}\n\nexport interface SparseWorkflowStage {\n active?: boolean;\n id?: string;\n key?: string;\n name?: string;\n order?: number;\n}\n\nexport interface SparseZone {\n /** The number of assets in the zone. */\n assetCount?: number;\n /** The customer the zone is designated for, such as for reservations, provisioning or a 3PL. */\n consignee?: SparseCustomer | null;\n /** A free-form description of the zone. */\n description?: string | null;\n /** The zone's unique identifier. */\n id?: string;\n /** Whether the zone is archived. */\n isArchived?: boolean;\n /** Whether assets in the zone count as inventory for reporting. */\n isInventory?: boolean;\n /** The zone's key. */\n key?: string;\n /** The zone's display name, unique within its site. */\n name?: string;\n}\n\nexport interface Token {\n /** When the API key was created, the application was connected, or the person signed in. */\n createdAt?: string;\n /** When the access token or session expires, or null for an API key, which does not. */\n expiresAt?: string | null;\n /** The API key's public identifier or the application's client_id, or null for a session. */\n identifier?: string | null;\n /** The API key's label or the application's name, or null when there is none. */\n label?: string | null;\n /** When the API key was last regenerated or the access token was issued, or null for a session. */\n lastRegeneratedAt?: string | null;\n /** The organization the credential acts in. */\n organization?: SparseOrganization;\n /** The person the credential acts for. */\n person?: SparsePerson;\n scopes?: string[];\n /** The kind of credential. */\n type?: CredentialType;\n}\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type TransactionType = \"SALE\" | \"SERVICE\";\n\n/** Accepted in any case, and also as t, f, 1, 0, or 2 for all. The listed spelling is the one the API sends back. */\nexport type TransientState = \"all\" | \"false\" | \"true\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type TransitStatus = \"IN_TRANSIT\" | \"IN_TRANSIT_TO_FIELD\" | \"IN_TRANSIT_TO_INVENTORY\" | \"NOT_IN_TRANSIT\";\n\nexport interface URLLink {\n /** When the link was created. */\n createdAt?: string;\n /** The URL link's unique identifier. */\n id?: string;\n /** The URL link's key, which the URL link endpoints take as linkKey. */\n key?: string;\n /** The link's display name, or null when the link shows its address instead. */\n name?: string | null;\n /** When the link was last changed. */\n updatedAt?: string;\n /** The address the link points to. */\n url?: string;\n}\n\n/** The unit a quantity is counted in, sent as its UNECE Recommendation 20 code. Accepted in any case. The listed spelling is the one the API sends back. | Value | Description | | --- | --- | | `BG` | Bag | | `BO` | Bottle | | `BX` | Box | | `C62` | Unit | | `CMK` | Square centimeter (cm2) | | `CMT` | Centimeter (cm) | | `CR` | Crate | | `CS` | Case | | `CT` | Carton | | `DMQ` | Cubic decimeter (dm3) | | `DR` | Drum | | `DZN` | Dozen (doz) | | `EA` | Each (ea) | | `EN` | Envelope | | `FOT` | Foot (ft) | | `FTK` | Square foot (ft2) | | `FTQ` | Cubic foot (ft3) | | `GLL` | Gallon (gal) | | `GRM` | Gram (g) | | `GRO` | Gross | | `H87` | Piece (pc) | | `INH` | Inch (in) | | `INK` | Square inch (in2) | | `INQ` | Cubic inch (in3) | | `KG` | Keg | | `KGM` | Kilogram (kg) | | `KMT` | Kilometer (km) | | `KT` | Kit | | `LBR` | Pound (lb) | | `LO` | Lot | | `LTR` | Liter (L) | | `MGM` | Milligram (mg) | | `MLT` | Milliliter (mL) | | `MMK` | Square millimeter (mm2) | | `MMT` | Millimeter (mm) | | `MTK` | Square meter (m2) | | `MTQ` | Cubic meter (m3) | | `MTR` | Meter (m) | | `ONZ` | Ounce (oz) | | `OZA` | Fluid ounce (fl oz) | | `PK` | Pack | | `PR` | Pair (pr) | | `PTI` | Pint (pt) | | `PX` | Pallet | | `QTI` | Quart (qt) | | `RL` | Reel | | `RO` | Roll | | `SET` | Set | | `SMI` | Mile (mi) | | `ST` | Sheet | | `STN` | Ton US (NT) | | `SV` | Skid | | `TNE` | Tonne metric (t) | | `TU` | Tube | | `YDK` | Square yard (yd2) | | `YDQ` | Cubic yard (yd3) | | `YRD` | Yard (yd) | */\nexport type UnitOfMeasure = \"BG\" | \"BO\" | \"BX\" | \"C62\" | \"CMK\" | \"CMT\" | \"CR\" | \"CS\" | \"CT\" | \"DMQ\" | \"DR\" | \"DZN\" | \"EA\" | \"EN\" | \"FOT\" | \"FTK\" | \"FTQ\" | \"GLL\" | \"GRM\" | \"GRO\" | \"H87\" | \"INH\" | \"INK\" | \"INQ\" | \"KG\" | \"KGM\" | \"KMT\" | \"KT\" | \"LBR\" | \"LO\" | \"LTR\" | \"MGM\" | \"MLT\" | \"MMK\" | \"MMT\" | \"MTK\" | \"MTQ\" | \"MTR\" | \"ONZ\" | \"OZA\" | \"PK\" | \"PR\" | \"PTI\" | \"PX\" | \"QTI\" | \"RL\" | \"RO\" | \"SET\" | \"SMI\" | \"ST\" | \"STN\" | \"SV\" | \"TNE\" | \"TU\" | \"YDK\" | \"YDQ\" | \"YRD\";\n\n/** Accepted in any case. The listed spelling is the one the API sends back. */\nexport type UsefulLifeRevisionReason = \"CHANGE_IN_USE\" | \"DAMAGE\" | \"OBSOLESCENCE\" | \"OTHER\" | \"REASSESSMENT\" | \"REFURBISHMENT\" | \"REGULATORY\";\n\nexport interface Workflow {\n /** When the workflow was created. */\n createdAt?: string;\n /** The workflow's identifier. */\n id?: string;\n /** Whether this is the organization's default workflow. */\n isDefault?: boolean;\n /** The workflow's key. */\n key?: string;\n /** The workflow's name. */\n name?: string;\n /** The stages a project on this workflow moves through, in order. */\n stages?: WorkflowStage[];\n /** When the workflow was last changed. */\n updatedAt?: string;\n}\n\nexport interface WorkflowStage {\n /** When the stage was created. */\n createdAt?: string;\n /** The stage's identifier. */\n id?: string;\n /** The number of projects on the stage. */\n inUseCount?: number;\n /** The stage's key. */\n key?: string;\n /** The stage's name. */\n name?: string;\n /** The stage's position in its workflow. */\n orderIndex?: number;\n /** When the stage was last changed. */\n updatedAt?: string;\n}\n";
3036
3106
  //#endregion
3037
3107
  //#region src/command/types.ts
3038
3108
  const typesCommand = defineCommand({
@@ -4239,7 +4309,7 @@ const REFUSED_COMMANDS = /* @__PURE__ */ new Map([
4239
4309
  /**
4240
4310
  * toParsed asks the CLI's own parser what a call would run, without running it. The server
4241
4311
  * decides from this answer and never from the words themselves, because a word such as
4242
- * --help may be a flag's value, and a flag given twice takes its last value.
4312
+ * --help may be a flag's value, and a flag given twice is a mistake the parser refuses.
4243
4313
  */
4244
4314
  function toParsed(args, commands) {
4245
4315
  let ran;
@@ -4690,14 +4760,14 @@ const commands = [
4690
4760
  queryName: "page",
4691
4761
  description: "The page to return, starting at 1",
4692
4762
  valueName: "number",
4693
- schema: z.coerce.number().int()
4763
+ schema: toNumber(z.number().int())
4694
4764
  },
4695
4765
  {
4696
4766
  name: "limit",
4697
4767
  queryName: "limit",
4698
4768
  description: "The number of records per page, from 1 to 100",
4699
4769
  valueName: "number",
4700
- schema: z.coerce.number().int().min(1).max(100)
4770
+ schema: toNumber(z.number().int().min(1).max(100))
4701
4771
  },
4702
4772
  {
4703
4773
  name: "sort-by",
@@ -4831,10 +4901,15 @@ const commands = [
4831
4901
  {
4832
4902
  name: "with-project-status",
4833
4903
  queryName: "withProjectStatus",
4834
- description: "The project assignments to list: upcoming, active, past, or none",
4904
+ description: "The project assignments to list: UPCOMING, ACTIVE, PAST, or NONE",
4835
4905
  valueName: "value",
4836
4906
  repeatable: true,
4837
- schema: z.array(z.string())
4907
+ schema: z.array(toEnum([
4908
+ "ACTIVE",
4909
+ "NONE",
4910
+ "PAST",
4911
+ "UPCOMING"
4912
+ ]))
4838
4913
  },
4839
4914
  {
4840
4915
  name: "with-owner",
@@ -4869,7 +4944,7 @@ const commands = [
4869
4944
  defineOperation({
4870
4945
  name: "create",
4871
4946
  summary: "Create asset",
4872
- example: "hardfin asset create --item-id <uuid> --serial <value>",
4947
+ example: "hardfin asset create --in-inventory-date <value> --item-id <uuid> --location-id <uuid>",
4873
4948
  method: "POST",
4874
4949
  path: "/asset",
4875
4950
  pathParameters: [],
@@ -4954,6 +5029,7 @@ const commands = [
4954
5029
  jsonPath: ["inInventoryDate"],
4955
5030
  description: "The day the asset entered inventory, which cannot be in the future",
4956
5031
  valueName: "value",
5032
+ required: true,
4957
5033
  schema: z.string()
4958
5034
  },
4959
5035
  {
@@ -4993,6 +5069,7 @@ const commands = [
4993
5069
  jsonPath: ["locationId"],
4994
5070
  description: "The ID of the location the asset enters inventory at",
4995
5071
  valueName: "uuid",
5072
+ required: true,
4996
5073
  schema: z.uuid()
4997
5074
  },
4998
5075
  {
@@ -5038,10 +5115,10 @@ const commands = [
5038
5115
  {
5039
5116
  name: "useful-life",
5040
5117
  jsonPath: ["usefulLife"],
5041
- description: "The number of months one unit is depreciated over, or null to clear it",
5118
+ description: "The number of months one unit is depreciated over, from 1 to 480, or null to clear it",
5042
5119
  valueName: "number",
5043
5120
  nullable: true,
5044
- schema: z.coerce.number().int()
5121
+ schema: toNumber(z.number().int())
5045
5122
  }
5046
5123
  ]
5047
5124
  }),
@@ -5217,7 +5294,6 @@ const commands = [
5217
5294
  jsonPath: ["serial"],
5218
5295
  description: "The asset's new serial number, which cannot be empty",
5219
5296
  valueName: "value",
5220
- nullable: true,
5221
5297
  schema: z.string()
5222
5298
  }
5223
5299
  ]
@@ -5361,10 +5437,10 @@ const commands = [
5361
5437
  {
5362
5438
  name: "useful-life",
5363
5439
  jsonPath: ["usefulLife"],
5364
- description: "The number of months one unit is depreciated over, or null to clear it",
5440
+ description: "The number of months one unit is depreciated over, from 1 to 480, or null to clear it",
5365
5441
  valueName: "number",
5366
5442
  nullable: true,
5367
- schema: z.coerce.number().int()
5443
+ schema: toNumber(z.number().int())
5368
5444
  }
5369
5445
  ]
5370
5446
  }), {
@@ -5932,13 +6008,279 @@ const commands = [
5932
6008
  description: "The asset's revised useful life in months",
5933
6009
  valueName: "number",
5934
6010
  required: true,
5935
- schema: z.coerce.number().int()
6011
+ schema: toNumber(z.number().int())
5936
6012
  }
5937
6013
  ]
5938
6014
  })]
5939
6015
  }
5940
6016
  ]
5941
6017
  },
6018
+ {
6019
+ name: "charge",
6020
+ summary: "Charge commands",
6021
+ arguments: [],
6022
+ flags: [],
6023
+ examples: [],
6024
+ subcommands: [
6025
+ defineOperation({
6026
+ name: "list",
6027
+ summary: "Get charges",
6028
+ example: "hardfin charge list --limit 10",
6029
+ method: "GET",
6030
+ path: "/charge",
6031
+ pathParameters: [],
6032
+ queryFlags: [
6033
+ {
6034
+ name: "page",
6035
+ queryName: "page",
6036
+ description: "The page to return, starting at 1",
6037
+ valueName: "number",
6038
+ schema: toNumber(z.number().int())
6039
+ },
6040
+ {
6041
+ name: "limit",
6042
+ queryName: "limit",
6043
+ description: "The number of records per page, from 1 to 100",
6044
+ valueName: "number",
6045
+ schema: toNumber(z.number().int().min(1).max(100))
6046
+ },
6047
+ {
6048
+ name: "sort-by",
6049
+ queryName: "sortBy",
6050
+ description: "The field to sort by",
6051
+ valueName: "value",
6052
+ schema: toEnum([
6053
+ "project",
6054
+ "customer",
6055
+ "label",
6056
+ "totalPrice",
6057
+ "servicePeriodStart",
6058
+ "expectedBillableDate",
6059
+ "status",
6060
+ "item"
6061
+ ])
6062
+ },
6063
+ {
6064
+ name: "sort-order",
6065
+ queryName: "sortOrder",
6066
+ description: "The sort direction",
6067
+ valueName: "value",
6068
+ schema: toEnum(["ASC", "DESC"])
6069
+ },
6070
+ {
6071
+ name: "archived",
6072
+ queryName: "archived",
6073
+ description: "Whether to return unarchived records, archived records, or all of them",
6074
+ valueName: "value",
6075
+ schema: toEnum([
6076
+ "all",
6077
+ "false",
6078
+ "true"
6079
+ ])
6080
+ },
6081
+ {
6082
+ name: "search",
6083
+ queryName: "search",
6084
+ description: "Text to find in the charge's label, its project's name, its customer's name, or its item's SKU or name, and a number also finds a charge with exactly that total price",
6085
+ valueName: "value",
6086
+ schema: z.string()
6087
+ },
6088
+ {
6089
+ name: "status",
6090
+ queryName: "status",
6091
+ description: "The one status to list: PLANNED, BILLABLE, INVOICED or CANCELLED",
6092
+ valueName: "value",
6093
+ schema: toEnum([
6094
+ "BILLABLE",
6095
+ "CANCELLED",
6096
+ "INVOICED",
6097
+ "PLANNED"
6098
+ ])
6099
+ },
6100
+ {
6101
+ name: "customers",
6102
+ queryName: "customers",
6103
+ description: "The customers whose charges to list, each named by its ID or its key",
6104
+ valueName: "value",
6105
+ repeatable: true,
6106
+ schema: z.array(z.string())
6107
+ },
6108
+ {
6109
+ name: "include-no-customer",
6110
+ queryName: "includeNoCustomer",
6111
+ description: "True to also list the charges of projects that have no customer, alongside any Customers named",
6112
+ schema: z.boolean()
6113
+ },
6114
+ {
6115
+ name: "projects",
6116
+ queryName: "projects",
6117
+ description: "The projects whose charges to list, each named by its ID or its key",
6118
+ valueName: "value",
6119
+ repeatable: true,
6120
+ schema: z.array(z.string())
6121
+ },
6122
+ {
6123
+ name: "bill-date-start",
6124
+ queryName: "billDateStart",
6125
+ description: "A day, and only charges whose ExpectedBillableDate is on or after it are listed",
6126
+ valueName: "value",
6127
+ schema: z.string()
6128
+ },
6129
+ {
6130
+ name: "bill-date-end",
6131
+ queryName: "billDateEnd",
6132
+ description: "A day, and only charges whose ExpectedBillableDate is on or before it are listed",
6133
+ valueName: "value",
6134
+ schema: z.string()
6135
+ },
6136
+ {
6137
+ name: "amount-min",
6138
+ queryName: "amountMin",
6139
+ description: "An amount, and only charges whose total price is at least it are listed",
6140
+ valueName: "value",
6141
+ schema: z.string()
6142
+ },
6143
+ {
6144
+ name: "amount-max",
6145
+ queryName: "amountMax",
6146
+ description: "An amount, and only charges whose total price is at most it are listed",
6147
+ valueName: "value",
6148
+ schema: z.string()
6149
+ },
6150
+ {
6151
+ name: "trigger-types",
6152
+ queryName: "triggerTypes",
6153
+ description: "The trigger types to list: TIME, MANUAL or EVENT",
6154
+ valueName: "value",
6155
+ repeatable: true,
6156
+ schema: z.array(toEnum([
6157
+ "EVENT",
6158
+ "MANUAL",
6159
+ "TIME"
6160
+ ]))
6161
+ }
6162
+ ],
6163
+ bodyFlags: []
6164
+ }),
6165
+ defineOperation({
6166
+ name: "cancel",
6167
+ summary: "Cancel charge",
6168
+ example: "hardfin charge cancel chrg_9kp3xv7mq2wrt5bz",
6169
+ method: "POST",
6170
+ path: "/charge/{chargeKey}/cancel",
6171
+ pathParameters: [{
6172
+ name: "chargeKey",
6173
+ description: "The key of the charge to cancel",
6174
+ required: true
6175
+ }],
6176
+ queryFlags: [],
6177
+ bodyFlags: [{
6178
+ name: "cancellation-reason",
6179
+ jsonPath: ["cancellationReason"],
6180
+ description: "Why the charge is cancelled, kept exactly as sent and 4,096 characters or less, or null for no reason",
6181
+ valueName: "value",
6182
+ nullable: true,
6183
+ schema: z.string()
6184
+ }]
6185
+ }),
6186
+ defineOperation({
6187
+ name: "mark-billable",
6188
+ summary: "Mark charge billable",
6189
+ example: "hardfin charge mark-billable chrg_9kp3xv7mq2wrt5bz --billing-eligible-date <value> --quantity <number>",
6190
+ method: "POST",
6191
+ path: "/charge/{chargeKey}/mark-billable",
6192
+ pathParameters: [{
6193
+ name: "chargeKey",
6194
+ description: "The key of the charge to mark billable",
6195
+ required: true
6196
+ }],
6197
+ queryFlags: [],
6198
+ bodyFlags: [
6199
+ {
6200
+ name: "billing-eligible-date",
6201
+ jsonPath: ["billingEligibleDate"],
6202
+ description: "The day the charge became billable, which is required and does not change its ExpectedBillableDate",
6203
+ valueName: "value",
6204
+ required: true,
6205
+ schema: z.string()
6206
+ },
6207
+ {
6208
+ name: "quantity",
6209
+ jsonPath: ["quantity"],
6210
+ description: "The number of units to bill now, from 1 to the charge's quantity, and a smaller number splits the charge in two",
6211
+ valueName: "number",
6212
+ required: true,
6213
+ schema: toNumber(z.number().int())
6214
+ },
6215
+ {
6216
+ name: "service-period-end",
6217
+ jsonPath: ["servicePeriodEnd"],
6218
+ description: "The last day of the period the charge covers, required with ServicePeriodStart",
6219
+ valueName: "value",
6220
+ nullable: true,
6221
+ schema: z.string()
6222
+ },
6223
+ {
6224
+ name: "service-period-start",
6225
+ jsonPath: ["servicePeriodStart"],
6226
+ description: "The first day of the period the charge covers, required when a milestone charge has no dates yet and ignored otherwise",
6227
+ valueName: "value",
6228
+ nullable: true,
6229
+ schema: z.string()
6230
+ },
6231
+ {
6232
+ name: "total-price-override-amount",
6233
+ jsonPath: ["totalPriceOverride", "amount"],
6234
+ description: "The value as a decimal string with two decimal places",
6235
+ valueName: "value",
6236
+ schema: z.string()
6237
+ },
6238
+ {
6239
+ name: "total-price-override-iso-code",
6240
+ jsonPath: ["totalPriceOverride", "isoCode"],
6241
+ description: "The value's ISO 4217 currency code",
6242
+ valueName: "value",
6243
+ schema: z.string()
6244
+ }
6245
+ ]
6246
+ }),
6247
+ defineOperation({
6248
+ name: "mark-not-billable",
6249
+ summary: "Mark charge not billable",
6250
+ example: "hardfin charge mark-not-billable chrg_9kp3xv7mq2wrt5bz",
6251
+ method: "POST",
6252
+ path: "/charge/{chargeKey}/mark-not-billable",
6253
+ pathParameters: [{
6254
+ name: "chargeKey",
6255
+ description: "The key of the charge to return to planned",
6256
+ required: true
6257
+ }],
6258
+ queryFlags: [],
6259
+ bodyFlags: [{
6260
+ name: "expected-billable-date",
6261
+ jsonPath: ["expectedBillableDate"],
6262
+ description: "The new day the charge is planned to become billable, or omitted to keep the day it has",
6263
+ valueName: "value",
6264
+ nullable: true,
6265
+ schema: z.string()
6266
+ }]
6267
+ }),
6268
+ defineOperation({
6269
+ name: "revert-cancellation",
6270
+ summary: "Revert charge cancellation",
6271
+ example: "hardfin charge revert-cancellation chrg_9kp3xv7mq2wrt5bz",
6272
+ method: "POST",
6273
+ path: "/charge/{chargeKey}/revert-cancellation",
6274
+ pathParameters: [{
6275
+ name: "chargeKey",
6276
+ description: "The key of the cancelled charge to restore",
6277
+ required: true
6278
+ }],
6279
+ queryFlags: [],
6280
+ bodyFlags: []
6281
+ })
6282
+ ]
6283
+ },
5942
6284
  {
5943
6285
  name: "customer",
5944
6286
  summary: "Customer commands",
@@ -5959,21 +6301,26 @@ const commands = [
5959
6301
  queryName: "page",
5960
6302
  description: "The page to return, starting at 1",
5961
6303
  valueName: "number",
5962
- schema: z.coerce.number().int()
6304
+ schema: toNumber(z.number().int())
5963
6305
  },
5964
6306
  {
5965
6307
  name: "limit",
5966
6308
  queryName: "limit",
5967
6309
  description: "The number of records per page, from 1 to 100",
5968
6310
  valueName: "number",
5969
- schema: z.coerce.number().int().min(1).max(100)
6311
+ schema: toNumber(z.number().int().min(1).max(100))
5970
6312
  },
5971
6313
  {
5972
6314
  name: "sort-by",
5973
6315
  queryName: "sortBy",
5974
6316
  description: "The field to sort by",
5975
6317
  valueName: "value",
5976
- schema: z.string()
6318
+ schema: toEnum([
6319
+ "name",
6320
+ "locationCount",
6321
+ "assetCount",
6322
+ "assetsAtLocation"
6323
+ ])
5977
6324
  },
5978
6325
  {
5979
6326
  name: "sort-order",
@@ -6011,12 +6358,16 @@ const commands = [
6011
6358
  description: "The CRM sync statuses to return: in-sync, out-of-sync, or not-linked",
6012
6359
  valueName: "value",
6013
6360
  repeatable: true,
6014
- schema: z.array(z.string())
6361
+ schema: z.array(toEnum([
6362
+ "in-sync",
6363
+ "out-of-sync",
6364
+ "not-linked"
6365
+ ]))
6015
6366
  },
6016
6367
  {
6017
6368
  name: "search",
6018
6369
  queryName: "search",
6019
- description: "Text to match against customer names",
6370
+ description: "Text to match against customer names, ignored when shorter than three characters",
6020
6371
  valueName: "value",
6021
6372
  schema: z.string()
6022
6373
  }
@@ -6224,7 +6575,6 @@ const commands = [
6224
6575
  jsonPath: ["name"],
6225
6576
  description: "The customer's display name",
6226
6577
  valueName: "value",
6227
- nullable: true,
6228
6578
  schema: z.string()
6229
6579
  }
6230
6580
  ]
@@ -6255,7 +6605,7 @@ const commands = [
6255
6605
  description: "The kind of file uploaded, which is ASSET_FILE, the only kind the API uploads",
6256
6606
  valueName: "value",
6257
6607
  required: true,
6258
- schema: z.string()
6608
+ schema: toEnum(["ASSET_FILE"])
6259
6609
  },
6260
6610
  {
6261
6611
  name: "for-entity",
@@ -6268,7 +6618,7 @@ const commands = [
6268
6618
  {
6269
6619
  name: "is-public",
6270
6620
  jsonPath: ["isPublic"],
6271
- description: "Whether any organization's API key may download the file, which is false unless sent as true",
6621
+ description: "Whether any organization's API key may download the file, sent as true or false in any case, and false when left out",
6272
6622
  schema: z.boolean()
6273
6623
  }
6274
6624
  ]
@@ -6332,14 +6682,14 @@ const commands = [
6332
6682
  queryName: "page",
6333
6683
  description: "The page to return, starting at 1",
6334
6684
  valueName: "number",
6335
- schema: z.coerce.number().int()
6685
+ schema: toNumber(z.number().int())
6336
6686
  },
6337
6687
  {
6338
6688
  name: "limit",
6339
6689
  queryName: "limit",
6340
6690
  description: "The number of records per page, from 1 to 100",
6341
6691
  valueName: "number",
6342
- schema: z.coerce.number().int().min(1).max(100)
6692
+ schema: toNumber(z.number().int().min(1).max(100))
6343
6693
  },
6344
6694
  {
6345
6695
  name: "sort-by",
@@ -6376,7 +6726,13 @@ const commands = [
6376
6726
  queryName: "excludeLinkedIntegration",
6377
6727
  description: "An integration whose already-linked items to leave out",
6378
6728
  valueName: "value",
6379
- schema: z.string()
6729
+ schema: toEnum([
6730
+ "HUBSPOT",
6731
+ "NETSUITE",
6732
+ "NONE",
6733
+ "QBO",
6734
+ "SFDC"
6735
+ ])
6380
6736
  }
6381
6737
  ],
6382
6738
  bodyFlags: []
@@ -6566,7 +6922,6 @@ const commands = [
6566
6922
  jsonPath: ["isArchived"],
6567
6923
  description: "Whether the item is archived, which cannot be null",
6568
6924
  negatable: true,
6569
- nullable: true,
6570
6925
  schema: z.boolean()
6571
6926
  },
6572
6927
  {
@@ -6574,7 +6929,6 @@ const commands = [
6574
6929
  jsonPath: ["name"],
6575
6930
  description: "The item's new display name, which cannot be empty",
6576
6931
  valueName: "value",
6577
- nullable: true,
6578
6932
  schema: z.string()
6579
6933
  },
6580
6934
  {
@@ -6582,7 +6936,6 @@ const commands = [
6582
6936
  jsonPath: ["sku"],
6583
6937
  description: "The item's new stock keeping unit, which cannot be empty and must be unique within your organization",
6584
6938
  valueName: "value",
6585
- nullable: true,
6586
6939
  schema: z.string()
6587
6940
  },
6588
6941
  {
@@ -6722,10 +7075,10 @@ const commands = [
6722
7075
  {
6723
7076
  name: "useful-life",
6724
7077
  jsonPath: ["usefulLife"],
6725
- description: "The number of months one unit is depreciated over, or null to clear it",
7078
+ description: "The number of months one unit is depreciated over, from 1 to 480, or null to clear it",
6726
7079
  valueName: "number",
6727
7080
  nullable: true,
6728
- schema: z.coerce.number().int()
7081
+ schema: toNumber(z.number().int())
6729
7082
  }
6730
7083
  ]
6731
7084
  })]
@@ -6782,7 +7135,7 @@ const commands = [
6782
7135
  valueName: "number",
6783
7136
  required: true,
6784
7137
  nullable: true,
6785
- schema: z.coerce.number().int()
7138
+ schema: toNumber(z.number().int())
6786
7139
  },
6787
7140
  {
6788
7141
  name: "section",
@@ -6791,7 +7144,7 @@ const commands = [
6791
7144
  valueName: "number",
6792
7145
  required: true,
6793
7146
  nullable: true,
6794
- schema: z.coerce.number().int()
7147
+ schema: toNumber(z.number().int())
6795
7148
  }
6796
7149
  ]
6797
7150
  }),
@@ -6816,7 +7169,6 @@ const commands = [
6816
7169
  jsonPath: ["label"],
6817
7170
  description: "The field's new display name, which cannot be empty",
6818
7171
  valueName: "value",
6819
- nullable: true,
6820
7172
  schema: z.string()
6821
7173
  }]
6822
7174
  }),
@@ -6862,14 +7214,14 @@ const commands = [
6862
7214
  queryName: "page",
6863
7215
  description: "The page to return, starting at 1",
6864
7216
  valueName: "number",
6865
- schema: z.coerce.number().int()
7217
+ schema: toNumber(z.number().int())
6866
7218
  },
6867
7219
  {
6868
7220
  name: "limit",
6869
7221
  queryName: "limit",
6870
7222
  description: "The number of records per page, from 1 to 100",
6871
7223
  valueName: "number",
6872
- schema: z.coerce.number().int().min(1).max(100)
7224
+ schema: toNumber(z.number().int().min(1).max(100))
6873
7225
  },
6874
7226
  {
6875
7227
  name: "sort-by",
@@ -6921,7 +7273,7 @@ const commands = [
6921
7273
  {
6922
7274
  name: "for-customer-ids",
6923
7275
  queryName: "forCustomerIds",
6924
- description: "The IDs of the customers whose locations to return",
7276
+ description: "The IDs of the customers whose locations to return, where ORGANIZATION stands for your organization's own locations",
6925
7277
  valueName: "value",
6926
7278
  repeatable: true,
6927
7279
  schema: z.array(z.string())
@@ -6938,7 +7290,11 @@ const commands = [
6938
7290
  description: "The CRM sync statuses to return: in-sync, out-of-sync, or not-linked",
6939
7291
  valueName: "value",
6940
7292
  repeatable: true,
6941
- schema: z.array(z.string())
7293
+ schema: z.array(toEnum([
7294
+ "in-sync",
7295
+ "out-of-sync",
7296
+ "not-linked"
7297
+ ]))
6942
7298
  }
6943
7299
  ],
6944
7300
  bodyFlags: []
@@ -6946,7 +7302,7 @@ const commands = [
6946
7302
  defineOperation({
6947
7303
  name: "create",
6948
7304
  summary: "Create location",
6949
- example: "hardfin location create",
7305
+ example: "hardfin location create --name <value> --type <value>",
6950
7306
  method: "POST",
6951
7307
  path: "/location",
6952
7308
  pathParameters: [],
@@ -7058,6 +7414,7 @@ const commands = [
7058
7414
  jsonPath: ["name"],
7059
7415
  description: "The location's display name",
7060
7416
  valueName: "value",
7417
+ required: true,
7061
7418
  schema: z.string()
7062
7419
  },
7063
7420
  {
@@ -7073,12 +7430,9 @@ const commands = [
7073
7430
  jsonPath: ["type"],
7074
7431
  description: "SITE for a site, or ZONE for a zone within a site",
7075
7432
  valueName: "value",
7433
+ required: true,
7076
7434
  nullable: true,
7077
- schema: toEnum([
7078
- "SITE",
7079
- "UNKNOWN",
7080
- "ZONE"
7081
- ])
7435
+ schema: toEnum(["SITE", "ZONE"])
7082
7436
  }
7083
7437
  ]
7084
7438
  }),
@@ -7168,7 +7522,7 @@ const commands = [
7168
7522
  {
7169
7523
  name: "consignee",
7170
7524
  jsonPath: ["consignee"],
7171
- description: "The ID of the customer a zone is designated for, such as for reservations, provisioning or a 3PL",
7525
+ description: "The ID of the customer a zone is designated for, such as for reservations, provisioning or a 3PL, which a site refuses",
7172
7526
  valueName: "uuid",
7173
7527
  nullable: true,
7174
7528
  schema: z.uuid()
@@ -7176,7 +7530,7 @@ const commands = [
7176
7530
  {
7177
7531
  name: "customer-id",
7178
7532
  jsonPath: ["customerId"],
7179
- description: "The ID of the customer to assign a site to, or null for your organization's own site",
7533
+ description: "The ID of the customer to assign a site to, or null for your organization's own site, which a zone refuses",
7180
7534
  valueName: "uuid",
7181
7535
  nullable: true,
7182
7536
  schema: z.uuid()
@@ -7184,7 +7538,7 @@ const commands = [
7184
7538
  {
7185
7539
  name: "description",
7186
7540
  jsonPath: ["description"],
7187
- description: "A free-form description of a zone",
7541
+ description: "A free-form description of a zone, which a site refuses",
7188
7542
  valueName: "value",
7189
7543
  nullable: true,
7190
7544
  schema: z.string()
@@ -7216,7 +7570,7 @@ const commands = [
7216
7570
  {
7217
7571
  name: "is-transient",
7218
7572
  jsonPath: ["isTransient"],
7219
- description: "Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default",
7573
+ description: "Whether assets make only occasional or temporary stops at the location, which hides it from location lists by default, and which a zone refuses",
7220
7574
  negatable: true,
7221
7575
  nullable: true,
7222
7576
  schema: z.boolean()
@@ -7226,7 +7580,6 @@ const commands = [
7226
7580
  jsonPath: ["name"],
7227
7581
  description: "The location's display name",
7228
7582
  valueName: "value",
7229
- nullable: true,
7230
7583
  schema: z.string()
7231
7584
  },
7232
7585
  {
@@ -7235,11 +7588,7 @@ const commands = [
7235
7588
  description: "SITE for a site, or ZONE for a zone within a site",
7236
7589
  valueName: "value",
7237
7590
  nullable: true,
7238
- schema: toEnum([
7239
- "SITE",
7240
- "UNKNOWN",
7241
- "ZONE"
7242
- ])
7591
+ schema: toEnum(["SITE", "ZONE"])
7243
7592
  }
7244
7593
  ]
7245
7594
  }),
@@ -7277,39 +7626,1912 @@ const commands = [
7277
7626
  ]
7278
7627
  },
7279
7628
  {
7280
- name: "token",
7281
- summary: "Token commands",
7629
+ name: "meta",
7630
+ summary: "Meta commands",
7282
7631
  arguments: [],
7283
7632
  flags: [],
7284
7633
  examples: [],
7285
- subcommands: [defineOperation({
7286
- name: "get",
7287
- summary: "Report the credential this CLI is calling with",
7288
- example: "hardfin token get",
7289
- method: "GET",
7290
- path: "/token",
7291
- pathParameters: [],
7292
- queryFlags: [],
7293
- bodyFlags: []
7294
- })]
7634
+ subcommands: [{
7635
+ name: "payment-terms",
7636
+ summary: "Payment terms commands",
7637
+ arguments: [],
7638
+ flags: [],
7639
+ examples: [],
7640
+ subcommands: [defineOperation({
7641
+ name: "list",
7642
+ summary: "Get payment terms",
7643
+ example: "hardfin meta payment-terms list",
7644
+ method: "GET",
7645
+ path: "/meta/payment-terms",
7646
+ pathParameters: [],
7647
+ queryFlags: [],
7648
+ bodyFlags: []
7649
+ })]
7650
+ }]
7295
7651
  },
7296
7652
  {
7297
- name: "url-link",
7298
- summary: "URL link commands",
7653
+ name: "project",
7654
+ summary: "Project commands",
7299
7655
  arguments: [],
7300
7656
  flags: [],
7301
7657
  examples: [],
7302
7658
  subcommands: [
7303
7659
  defineOperation({
7304
- name: "get",
7305
- summary: "Get URL link by key",
7306
- example: "hardfin url-link get link_7hq2mx9pcr4stz8w",
7660
+ name: "list",
7661
+ summary: "Get projects",
7662
+ example: "hardfin project list --limit 10",
7307
7663
  method: "GET",
7308
- path: "/url-link/{linkKey}",
7309
- pathParameters: [{
7310
- name: "linkKey",
7311
- description: "The URL link's key",
7312
- required: true
7664
+ path: "/project",
7665
+ pathParameters: [],
7666
+ queryFlags: [
7667
+ {
7668
+ name: "page",
7669
+ queryName: "page",
7670
+ description: "The page to return, starting at 1",
7671
+ valueName: "number",
7672
+ schema: toNumber(z.number().int())
7673
+ },
7674
+ {
7675
+ name: "limit",
7676
+ queryName: "limit",
7677
+ description: "The number of records per page, from 1 to 100",
7678
+ valueName: "number",
7679
+ schema: toNumber(z.number().int().min(1).max(100))
7680
+ },
7681
+ {
7682
+ name: "sort-by",
7683
+ queryName: "sortBy",
7684
+ description: "The field to sort by",
7685
+ valueName: "value",
7686
+ schema: toEnum([
7687
+ "name",
7688
+ "startOn",
7689
+ "endOn",
7690
+ "workflow"
7691
+ ])
7692
+ },
7693
+ {
7694
+ name: "sort-order",
7695
+ queryName: "sortOrder",
7696
+ description: "The sort direction",
7697
+ valueName: "value",
7698
+ schema: toEnum(["ASC", "DESC"])
7699
+ },
7700
+ {
7701
+ name: "archived",
7702
+ queryName: "archived",
7703
+ description: "Whether to return unarchived records, archived records, or all of them",
7704
+ valueName: "value",
7705
+ schema: toEnum([
7706
+ "all",
7707
+ "false",
7708
+ "true"
7709
+ ])
7710
+ },
7711
+ {
7712
+ name: "search",
7713
+ queryName: "search",
7714
+ description: "Text of three or more characters to find in the project's name or description, its customer's name, or the items and locations of its line items",
7715
+ valueName: "value",
7716
+ schema: z.string()
7717
+ },
7718
+ {
7719
+ name: "customer-ids",
7720
+ queryName: "customerIds",
7721
+ description: "The IDs of the customers whose projects to list",
7722
+ valueName: "uuid",
7723
+ repeatable: true,
7724
+ schema: z.array(z.uuid())
7725
+ },
7726
+ {
7727
+ name: "item-ids",
7728
+ queryName: "itemIds",
7729
+ description: "The IDs of the items whose projects to list, which are the projects with a line item for the item or holding one of its assets",
7730
+ valueName: "uuid",
7731
+ repeatable: true,
7732
+ schema: z.array(z.uuid())
7733
+ },
7734
+ {
7735
+ name: "project-ids",
7736
+ queryName: "projectIds",
7737
+ description: "The IDs of the projects to list",
7738
+ valueName: "uuid",
7739
+ repeatable: true,
7740
+ schema: z.array(z.uuid())
7741
+ },
7742
+ {
7743
+ name: "location-ids",
7744
+ queryName: "locationIds",
7745
+ description: "The IDs of the locations whose projects to list, which are the projects with a line item at the location or with it as their default location",
7746
+ valueName: "uuid",
7747
+ repeatable: true,
7748
+ schema: z.array(z.uuid())
7749
+ },
7750
+ {
7751
+ name: "statuses",
7752
+ queryName: "statuses",
7753
+ description: "The statuses to list: UPCOMING, ACTIVE, PAST, or DATE_RANGE_INCOMPLETE for a project missing a start or an end",
7754
+ valueName: "value",
7755
+ repeatable: true,
7756
+ schema: z.array(toEnum([
7757
+ "ACTIVE",
7758
+ "DATE_RANGE_INCOMPLETE",
7759
+ "PAST",
7760
+ "UPCOMING"
7761
+ ]))
7762
+ },
7763
+ {
7764
+ name: "start-by",
7765
+ queryName: "startBy",
7766
+ description: "A day, and only projects that start on or before it are listed",
7767
+ valueName: "value",
7768
+ schema: z.string()
7769
+ },
7770
+ {
7771
+ name: "end-by",
7772
+ queryName: "endBy",
7773
+ description: "A day, and only projects that end on or before it are listed",
7774
+ valueName: "value",
7775
+ schema: z.string()
7776
+ }
7777
+ ],
7778
+ bodyFlags: []
7779
+ }),
7780
+ defineOperation({
7781
+ name: "create",
7782
+ summary: "Create project",
7783
+ example: "hardfin project create --line-item aggregationKey=<value>,itemId=<value>,quantity=<value>,transactionType=<value> --name <value>",
7784
+ method: "POST",
7785
+ path: "/project",
7786
+ pathParameters: [],
7787
+ queryFlags: [],
7788
+ bodyFlags: [
7789
+ {
7790
+ name: "contract-signed-on",
7791
+ jsonPath: ["contractSignedOn"],
7792
+ description: "The day the contract was signed",
7793
+ valueName: "value",
7794
+ nullable: true,
7795
+ schema: z.string()
7796
+ },
7797
+ {
7798
+ name: "customer-id",
7799
+ jsonPath: ["customerId"],
7800
+ description: "The ID of the customer the project is for",
7801
+ valueName: "uuid",
7802
+ nullable: true,
7803
+ schema: z.uuid()
7804
+ },
7805
+ {
7806
+ name: "default-location-id",
7807
+ jsonPath: ["defaultLocationId"],
7808
+ description: "The ID of the project's default location",
7809
+ valueName: "uuid",
7810
+ nullable: true,
7811
+ schema: z.uuid()
7812
+ },
7813
+ {
7814
+ name: "description",
7815
+ jsonPath: ["description"],
7816
+ description: "The project's description",
7817
+ valueName: "value",
7818
+ nullable: true,
7819
+ schema: z.string()
7820
+ },
7821
+ {
7822
+ name: "end-on",
7823
+ jsonPath: ["endOn"],
7824
+ description: "The day the project ends",
7825
+ valueName: "value",
7826
+ nullable: true,
7827
+ schema: z.string()
7828
+ },
7829
+ {
7830
+ name: "file-ids",
7831
+ jsonPath: ["fileIds"],
7832
+ description: "The IDs of uploaded files to attach to the project",
7833
+ valueName: "uuid",
7834
+ repeatable: true,
7835
+ schema: z.array(z.uuid())
7836
+ },
7837
+ {
7838
+ name: "inherit-previous-line-items",
7839
+ jsonPath: ["inheritPreviousLineItems"],
7840
+ description: "Whether to copy the line items of the project this one renews, which applies only when PreviousProjectID is sent",
7841
+ negatable: true,
7842
+ nullable: true,
7843
+ schema: z.boolean()
7844
+ },
7845
+ {
7846
+ name: "initial-workflow-stage-id",
7847
+ jsonPath: ["initialWorkflowStageId"],
7848
+ description: "The ID of the workflow stage the project starts on, which defaults to the workflow's first stage",
7849
+ valueName: "uuid",
7850
+ nullable: true,
7851
+ schema: z.uuid()
7852
+ },
7853
+ {
7854
+ name: "install-date",
7855
+ jsonPath: ["installDate"],
7856
+ description: "The day of the installation",
7857
+ valueName: "value",
7858
+ nullable: true,
7859
+ schema: z.string()
7860
+ },
7861
+ {
7862
+ name: "line-item",
7863
+ jsonPath: ["lineItems"],
7864
+ description: "The project's line items, each an item the project sells or provides as a service. Takes activationDate=, aggregationKey=, billingFrequency=, chargeFrequency=, chargeSchedule=, details=, endOn=, fixedPrice=, fixedPrice.amount=, fixedPrice.isoCode=, id=, invoiceFrequency=, invoiceMode=, itemId=, locationId=, milestonePhases=, pricingMode=, quantity=, startOn=, totalOverride=, totalOverride.amount=, totalOverride.isoCode=, transactionType=, unitPrice=, unitPrice.amount=, unitPrice.isoCode=",
7865
+ valueName: "field=value,...",
7866
+ repeatable: true,
7867
+ element: [
7868
+ "activationDate",
7869
+ "aggregationKey",
7870
+ "billingFrequency",
7871
+ "chargeFrequency",
7872
+ "chargeSchedule",
7873
+ "details",
7874
+ "endOn",
7875
+ "fixedPrice",
7876
+ "fixedPrice.amount",
7877
+ "fixedPrice.isoCode",
7878
+ "id",
7879
+ "invoiceFrequency",
7880
+ "invoiceMode",
7881
+ "itemId",
7882
+ "locationId",
7883
+ "milestonePhases",
7884
+ "pricingMode",
7885
+ "quantity",
7886
+ "startOn",
7887
+ "totalOverride",
7888
+ "totalOverride.amount",
7889
+ "totalOverride.isoCode",
7890
+ "transactionType",
7891
+ "unitPrice",
7892
+ "unitPrice.amount",
7893
+ "unitPrice.isoCode"
7894
+ ],
7895
+ elementUuids: [
7896
+ "aggregationKey",
7897
+ "id",
7898
+ "itemId",
7899
+ "locationId"
7900
+ ],
7901
+ elementTypes: {
7902
+ "activationDate": ["string", "null"],
7903
+ "billingFrequency": ["string", "null"],
7904
+ "chargeFrequency": ["string", "null"],
7905
+ "chargeSchedule": ["string", "null"],
7906
+ "details": ["string", "null"],
7907
+ "endOn": ["string", "null"],
7908
+ "fixedPrice": ["null"],
7909
+ "id": ["string", "null"],
7910
+ "invoiceFrequency": ["string", "null"],
7911
+ "invoiceMode": ["string", "null"],
7912
+ "locationId": ["string", "null"],
7913
+ "milestonePhases": ["object", "null"],
7914
+ "pricingMode": ["string", "null"],
7915
+ "quantity": ["integer"],
7916
+ "startOn": ["string", "null"],
7917
+ "totalOverride": ["null"],
7918
+ "unitPrice": ["null"]
7919
+ },
7920
+ schema: z.array(z.string())
7921
+ },
7922
+ {
7923
+ name: "name",
7924
+ jsonPath: ["name"],
7925
+ description: "The project's name, which no other project in the organization may share",
7926
+ valueName: "value",
7927
+ required: true,
7928
+ schema: z.string()
7929
+ },
7930
+ {
7931
+ name: "previous-project-id",
7932
+ jsonPath: ["previousProjectId"],
7933
+ description: "The ID of the project this one renews",
7934
+ valueName: "uuid",
7935
+ nullable: true,
7936
+ schema: z.uuid()
7937
+ },
7938
+ {
7939
+ name: "start-on",
7940
+ jsonPath: ["startOn"],
7941
+ description: "The day the project starts",
7942
+ valueName: "value",
7943
+ nullable: true,
7944
+ schema: z.string()
7945
+ },
7946
+ {
7947
+ name: "total-contract-value-amount",
7948
+ jsonPath: ["totalContractValue", "amount"],
7949
+ description: "The value as a decimal string with two decimal places",
7950
+ valueName: "value",
7951
+ schema: z.string()
7952
+ },
7953
+ {
7954
+ name: "total-contract-value-iso-code",
7955
+ jsonPath: ["totalContractValue", "isoCode"],
7956
+ description: "The value's ISO 4217 currency code",
7957
+ valueName: "value",
7958
+ schema: z.string()
7959
+ },
7960
+ {
7961
+ name: "workflow-id",
7962
+ jsonPath: ["workflowId"],
7963
+ description: "The ID of the workflow to put the project on",
7964
+ valueName: "uuid",
7965
+ nullable: true,
7966
+ schema: z.uuid()
7967
+ }
7968
+ ]
7969
+ }),
7970
+ defineOperation({
7971
+ name: "get",
7972
+ summary: "Get project",
7973
+ example: "hardfin project get proj_7hq2lm9xcr4twz8k",
7974
+ method: "GET",
7975
+ path: "/project/{projectKey}",
7976
+ pathParameters: [{
7977
+ name: "projectKey",
7978
+ description: "The project's key",
7979
+ required: true
7980
+ }],
7981
+ queryFlags: [],
7982
+ bodyFlags: []
7983
+ }),
7984
+ defineOperation({
7985
+ name: "update",
7986
+ summary: "Patch project",
7987
+ example: "hardfin project update proj_7hq2lm9xcr4twz8k --line-item aggregationKey=<value>,itemId=<value>,quantity=<value>,transactionType=<value>",
7988
+ method: "PATCH",
7989
+ path: "/project/{projectKey}",
7990
+ pathParameters: [{
7991
+ name: "projectKey",
7992
+ description: "The project's key",
7993
+ required: true
7994
+ }],
7995
+ queryFlags: [],
7996
+ bodyFlags: [
7997
+ {
7998
+ name: "acceptance-date",
7999
+ jsonPath: ["acceptanceDate"],
8000
+ description: "The day the customer accepted the project",
8001
+ valueName: "value",
8002
+ nullable: true,
8003
+ schema: z.string()
8004
+ },
8005
+ {
8006
+ name: "billing-address",
8007
+ jsonPath: ["billingAddress"],
8008
+ description: "The billing address the project's invoices use in place of the customer's",
8009
+ valueName: "value",
8010
+ nullable: true,
8011
+ schema: z.string()
8012
+ },
8013
+ {
8014
+ name: "billing-contact-email",
8015
+ jsonPath: ["billingContactEmail"],
8016
+ description: "The billing contact email the project's invoices use in place of the customer's",
8017
+ valueName: "value",
8018
+ nullable: true,
8019
+ schema: z.string()
8020
+ },
8021
+ {
8022
+ name: "billing-contact-name",
8023
+ jsonPath: ["billingContactName"],
8024
+ description: "The billing contact name the project's invoices use in place of the customer's",
8025
+ valueName: "value",
8026
+ nullable: true,
8027
+ schema: z.string()
8028
+ },
8029
+ {
8030
+ name: "billing-contact-phone",
8031
+ jsonPath: ["billingContactPhone"],
8032
+ description: "The billing contact phone number the project's invoices use in place of the customer's",
8033
+ valueName: "value",
8034
+ nullable: true,
8035
+ schema: z.string()
8036
+ },
8037
+ {
8038
+ name: "contract-signed-on",
8039
+ jsonPath: ["contractSignedOn"],
8040
+ description: "The day the contract was signed",
8041
+ valueName: "value",
8042
+ nullable: true,
8043
+ schema: z.string()
8044
+ },
8045
+ {
8046
+ name: "customer-id",
8047
+ jsonPath: ["customerId"],
8048
+ description: "The ID of the customer the project is for",
8049
+ valueName: "uuid",
8050
+ nullable: true,
8051
+ schema: z.uuid()
8052
+ },
8053
+ {
8054
+ name: "default-location-id",
8055
+ jsonPath: ["defaultLocationId"],
8056
+ description: "The ID of the project's default location",
8057
+ valueName: "uuid",
8058
+ nullable: true,
8059
+ schema: z.uuid()
8060
+ },
8061
+ {
8062
+ name: "description",
8063
+ jsonPath: ["description"],
8064
+ description: "The project's description",
8065
+ valueName: "value",
8066
+ nullable: true,
8067
+ schema: z.string()
8068
+ },
8069
+ {
8070
+ name: "discount-amount",
8071
+ jsonPath: ["discount", "amount"],
8072
+ description: "The value as a decimal string with two decimal places",
8073
+ valueName: "value",
8074
+ schema: z.string()
8075
+ },
8076
+ {
8077
+ name: "discount-iso-code",
8078
+ jsonPath: ["discount", "isoCode"],
8079
+ description: "The value's ISO 4217 currency code",
8080
+ valueName: "value",
8081
+ schema: z.string()
8082
+ },
8083
+ {
8084
+ name: "end-on",
8085
+ jsonPath: ["endOn"],
8086
+ description: "The day the project ends",
8087
+ valueName: "value",
8088
+ nullable: true,
8089
+ schema: z.string()
8090
+ },
8091
+ {
8092
+ name: "go-live-date",
8093
+ jsonPath: ["goLiveDate"],
8094
+ description: "The day the project goes live",
8095
+ valueName: "value",
8096
+ nullable: true,
8097
+ schema: z.string()
8098
+ },
8099
+ {
8100
+ name: "install-date",
8101
+ jsonPath: ["installDate"],
8102
+ description: "The day of the installation",
8103
+ valueName: "value",
8104
+ nullable: true,
8105
+ schema: z.string()
8106
+ },
8107
+ {
8108
+ name: "is-archived",
8109
+ jsonPath: ["isArchived"],
8110
+ description: "Whether the project is archived",
8111
+ negatable: true,
8112
+ nullable: true,
8113
+ schema: z.boolean()
8114
+ },
8115
+ {
8116
+ name: "line-item",
8117
+ jsonPath: ["lineItems"],
8118
+ description: "The project's line items. Takes activationDate=, aggregationKey=, billingFrequency=, chargeFrequency=, chargeSchedule=, details=, endOn=, fixedPrice=, fixedPrice.amount=, fixedPrice.isoCode=, id=, invoiceFrequency=, invoiceMode=, itemId=, locationId=, milestonePhases=, pricingMode=, quantity=, startOn=, totalOverride=, totalOverride.amount=, totalOverride.isoCode=, transactionType=, unitPrice=, unitPrice.amount=, unitPrice.isoCode=",
8119
+ valueName: "field=value,...",
8120
+ repeatable: true,
8121
+ element: [
8122
+ "activationDate",
8123
+ "aggregationKey",
8124
+ "billingFrequency",
8125
+ "chargeFrequency",
8126
+ "chargeSchedule",
8127
+ "details",
8128
+ "endOn",
8129
+ "fixedPrice",
8130
+ "fixedPrice.amount",
8131
+ "fixedPrice.isoCode",
8132
+ "id",
8133
+ "invoiceFrequency",
8134
+ "invoiceMode",
8135
+ "itemId",
8136
+ "locationId",
8137
+ "milestonePhases",
8138
+ "pricingMode",
8139
+ "quantity",
8140
+ "startOn",
8141
+ "totalOverride",
8142
+ "totalOverride.amount",
8143
+ "totalOverride.isoCode",
8144
+ "transactionType",
8145
+ "unitPrice",
8146
+ "unitPrice.amount",
8147
+ "unitPrice.isoCode"
8148
+ ],
8149
+ elementUuids: [
8150
+ "aggregationKey",
8151
+ "id",
8152
+ "itemId",
8153
+ "locationId"
8154
+ ],
8155
+ elementTypes: {
8156
+ "activationDate": ["string", "null"],
8157
+ "billingFrequency": ["string", "null"],
8158
+ "chargeFrequency": ["string", "null"],
8159
+ "chargeSchedule": ["string", "null"],
8160
+ "details": ["string", "null"],
8161
+ "endOn": ["string", "null"],
8162
+ "fixedPrice": ["null"],
8163
+ "id": ["string", "null"],
8164
+ "invoiceFrequency": ["string", "null"],
8165
+ "invoiceMode": ["string", "null"],
8166
+ "locationId": ["string", "null"],
8167
+ "milestonePhases": ["object", "null"],
8168
+ "pricingMode": ["string", "null"],
8169
+ "quantity": ["integer"],
8170
+ "startOn": ["string", "null"],
8171
+ "totalOverride": ["null"],
8172
+ "unitPrice": ["null"]
8173
+ },
8174
+ schema: z.array(z.string())
8175
+ },
8176
+ {
8177
+ name: "memo",
8178
+ jsonPath: ["memo"],
8179
+ description: "The memo new invoices for the project carry",
8180
+ valueName: "value",
8181
+ nullable: true,
8182
+ schema: z.string()
8183
+ },
8184
+ {
8185
+ name: "name",
8186
+ jsonPath: ["name"],
8187
+ description: "The project's new name, which no other project in the organization may share",
8188
+ valueName: "value",
8189
+ nullable: true,
8190
+ schema: z.string()
8191
+ },
8192
+ {
8193
+ name: "payment-term",
8194
+ jsonPath: ["paymentTerm"],
8195
+ description: "The project's payment term, named by the ID or the label the payment term list returns",
8196
+ valueName: "value",
8197
+ nullable: true,
8198
+ schema: z.string()
8199
+ },
8200
+ {
8201
+ name: "previous-project-id",
8202
+ jsonPath: ["previousProjectId"],
8203
+ description: "The ID of the project this one renews",
8204
+ valueName: "uuid",
8205
+ nullable: true,
8206
+ schema: z.uuid()
8207
+ },
8208
+ {
8209
+ name: "purchase-order-number",
8210
+ jsonPath: ["purchaseOrderNumber"],
8211
+ description: "The customer's purchase order number, which new invoices for the project carry",
8212
+ valueName: "value",
8213
+ nullable: true,
8214
+ schema: z.string()
8215
+ },
8216
+ {
8217
+ name: "site-visit-date",
8218
+ jsonPath: ["siteVisitDate"],
8219
+ description: "The day of the site visit",
8220
+ valueName: "value",
8221
+ nullable: true,
8222
+ schema: z.string()
8223
+ },
8224
+ {
8225
+ name: "start-on",
8226
+ jsonPath: ["startOn"],
8227
+ description: "The day the project starts",
8228
+ valueName: "value",
8229
+ nullable: true,
8230
+ schema: z.string()
8231
+ },
8232
+ {
8233
+ name: "total-contract-value-amount",
8234
+ jsonPath: ["totalContractValue", "amount"],
8235
+ description: "The value as a decimal string with two decimal places",
8236
+ valueName: "value",
8237
+ schema: z.string()
8238
+ },
8239
+ {
8240
+ name: "total-contract-value-iso-code",
8241
+ jsonPath: ["totalContractValue", "isoCode"],
8242
+ description: "The value's ISO 4217 currency code",
8243
+ valueName: "value",
8244
+ schema: z.string()
8245
+ },
8246
+ {
8247
+ name: "training-date",
8248
+ jsonPath: ["trainingDate"],
8249
+ description: "The day of the training",
8250
+ valueName: "value",
8251
+ nullable: true,
8252
+ schema: z.string()
8253
+ },
8254
+ {
8255
+ name: "workflow-id",
8256
+ jsonPath: ["workflowId"],
8257
+ description: "The ID of the workflow to put the project on",
8258
+ valueName: "uuid",
8259
+ nullable: true,
8260
+ schema: z.uuid()
8261
+ },
8262
+ {
8263
+ name: "workflow-stage-id",
8264
+ jsonPath: ["workflowStageId"],
8265
+ description: "The ID of the workflow stage to move the project to, which has to belong to the project's workflow",
8266
+ valueName: "uuid",
8267
+ nullable: true,
8268
+ schema: z.uuid()
8269
+ }
8270
+ ]
8271
+ }),
8272
+ {
8273
+ name: "line-item",
8274
+ summary: "Line item commands",
8275
+ arguments: [],
8276
+ flags: [],
8277
+ examples: [],
8278
+ subcommands: [defineOperation({
8279
+ name: "update",
8280
+ summary: "Patch project line item",
8281
+ example: "hardfin project line-item update proj_7hq2lm9xcr4twz8k ppb_4tn8wq2zkv7mx9cr --charge isCustomModified=<value>,label=<value>,pricingMode=<value>,quantity=<value>,sequence=<value>,status=<value>,triggerType=<value> --milestone-phases-entry name=<value>,percentage=<value>",
8282
+ method: "PATCH",
8283
+ path: "/project/{projectKey}/line-item/{lineItemKey}",
8284
+ pathParameters: [{
8285
+ name: "projectKey",
8286
+ description: "The key of the project the line item belongs to",
8287
+ required: true
8288
+ }, {
8289
+ name: "lineItemKey",
8290
+ description: "The key of the line item to update",
8291
+ required: true
8292
+ }],
8293
+ queryFlags: [],
8294
+ bodyFlags: [
8295
+ {
8296
+ name: "activation-date",
8297
+ jsonPath: ["activationDate"],
8298
+ description: "The day a periodic line item's charge schedule is anchored on",
8299
+ valueName: "value",
8300
+ nullable: true,
8301
+ schema: z.string()
8302
+ },
8303
+ {
8304
+ name: "billing-frequency",
8305
+ jsonPath: ["billingFrequency"],
8306
+ description: "The line item's single billing cadence",
8307
+ valueName: "value",
8308
+ nullable: true,
8309
+ schema: toEnum([
8310
+ "ANNUALLY",
8311
+ "BIENNIALLY",
8312
+ "BIWEEKLY",
8313
+ "DAILY",
8314
+ "MONTHLY",
8315
+ "ONCE",
8316
+ "QUADRENNIALLY",
8317
+ "QUARTERLY",
8318
+ "QUINQUENNIALLY",
8319
+ "SEMIANNUALLY",
8320
+ "TRIENNIALLY",
8321
+ "WEEKLY"
8322
+ ])
8323
+ },
8324
+ {
8325
+ name: "charge-frequency",
8326
+ jsonPath: ["chargeFrequency"],
8327
+ description: "How often a periodic line item creates a charge, and is refused unless ChargeSchedule is PERIODIC",
8328
+ valueName: "value",
8329
+ nullable: true,
8330
+ schema: toEnum([
8331
+ "ANNUALLY",
8332
+ "BIENNIALLY",
8333
+ "BIWEEKLY",
8334
+ "DAILY",
8335
+ "MONTHLY",
8336
+ "ONCE",
8337
+ "QUADRENNIALLY",
8338
+ "QUARTERLY",
8339
+ "QUINQUENNIALLY",
8340
+ "SEMIANNUALLY",
8341
+ "TRIENNIALLY",
8342
+ "WEEKLY"
8343
+ ])
8344
+ },
8345
+ {
8346
+ name: "charge-mode",
8347
+ jsonPath: ["chargeMode"],
8348
+ description: "CONFIRMED when ActivationDate is sent, or PENDING when it is null, and a MILESTONE line item is CONFIRMED with no ActivationDate",
8349
+ valueName: "value",
8350
+ nullable: true,
8351
+ schema: toEnum(["CONFIRMED", "PENDING"])
8352
+ },
8353
+ {
8354
+ name: "charge-schedule",
8355
+ jsonPath: ["chargeSchedule"],
8356
+ description: "PERIODIC when charges recur at a regular frequency, or MILESTONE when each charge follows a project milestone",
8357
+ valueName: "value",
8358
+ nullable: true,
8359
+ schema: toEnum(["MILESTONE", "PERIODIC"])
8360
+ },
8361
+ {
8362
+ name: "charge",
8363
+ jsonPath: ["charges"],
8364
+ description: "The line item's whole charge list, which replaces the charges it has, or omitted to leave them as they are. Takes expectedBillableDate=, id=, isCustomModified=, label=, pricingMode=, quantity=, sequence=, servicePeriodEnd=, servicePeriodStart=, status=, totalPrice.amount=, totalPrice.isoCode=, triggerType=, unitPrice=, unitPrice.amount=, unitPrice.isoCode=",
8365
+ valueName: "field=value,...",
8366
+ repeatable: true,
8367
+ element: [
8368
+ "expectedBillableDate",
8369
+ "id",
8370
+ "isCustomModified",
8371
+ "label",
8372
+ "pricingMode",
8373
+ "quantity",
8374
+ "sequence",
8375
+ "servicePeriodEnd",
8376
+ "servicePeriodStart",
8377
+ "status",
8378
+ "totalPrice.amount",
8379
+ "totalPrice.isoCode",
8380
+ "triggerType",
8381
+ "unitPrice",
8382
+ "unitPrice.amount",
8383
+ "unitPrice.isoCode"
8384
+ ],
8385
+ elementUuids: ["id"],
8386
+ elementTypes: {
8387
+ "expectedBillableDate": ["string", "null"],
8388
+ "id": ["string", "null"],
8389
+ "isCustomModified": ["boolean"],
8390
+ "quantity": ["integer"],
8391
+ "sequence": ["integer"],
8392
+ "servicePeriodEnd": ["string", "null"],
8393
+ "servicePeriodStart": ["string", "null"],
8394
+ "unitPrice": ["null"]
8395
+ },
8396
+ schema: z.array(z.string())
8397
+ },
8398
+ {
8399
+ name: "details",
8400
+ jsonPath: ["details"],
8401
+ description: "A free-form note about the line item, 65,536 characters or less",
8402
+ valueName: "value",
8403
+ nullable: true,
8404
+ schema: z.string()
8405
+ },
8406
+ {
8407
+ name: "fixed-price-amount",
8408
+ jsonPath: ["fixedPrice", "amount"],
8409
+ description: "The value as a decimal string with two decimal places",
8410
+ valueName: "value",
8411
+ schema: z.string()
8412
+ },
8413
+ {
8414
+ name: "fixed-price-iso-code",
8415
+ jsonPath: ["fixedPrice", "isoCode"],
8416
+ description: "The value's ISO 4217 currency code",
8417
+ valueName: "value",
8418
+ schema: z.string()
8419
+ },
8420
+ {
8421
+ name: "generate",
8422
+ jsonPath: ["generate"],
8423
+ description: "True to replace the line item's charges with the schedule its billing plan produces, and is not sent together with Charges",
8424
+ negatable: true,
8425
+ schema: z.boolean()
8426
+ },
8427
+ {
8428
+ name: "invoice-frequency",
8429
+ jsonPath: ["invoiceFrequency"],
8430
+ description: "How often a periodic line item's charges are invoiced, which is never more often than ChargeFrequency",
8431
+ valueName: "value",
8432
+ nullable: true,
8433
+ schema: toEnum([
8434
+ "ANNUALLY",
8435
+ "BIENNIALLY",
8436
+ "BIWEEKLY",
8437
+ "DAILY",
8438
+ "MONTHLY",
8439
+ "ONCE",
8440
+ "QUADRENNIALLY",
8441
+ "QUARTERLY",
8442
+ "QUINQUENNIALLY",
8443
+ "SEMIANNUALLY",
8444
+ "TRIENNIALLY",
8445
+ "WEEKLY"
8446
+ ])
8447
+ },
8448
+ {
8449
+ name: "invoice-mode",
8450
+ jsonPath: ["invoiceMode"],
8451
+ description: "ADVANCE to invoice a period before it starts, or ARREARS to invoice it after it ends, and is refused unless ChargeSchedule is PERIODIC",
8452
+ valueName: "value",
8453
+ nullable: true,
8454
+ schema: toEnum(["ADVANCE", "ARREARS"])
8455
+ },
8456
+ {
8457
+ name: "item-id",
8458
+ jsonPath: ["itemId"],
8459
+ description: "The catalog item the line item is for",
8460
+ valueName: "uuid",
8461
+ nullable: true,
8462
+ schema: z.uuid()
8463
+ },
8464
+ {
8465
+ name: "location-id",
8466
+ jsonPath: ["locationId"],
8467
+ description: "The location the line item is for",
8468
+ valueName: "uuid",
8469
+ nullable: true,
8470
+ schema: z.uuid()
8471
+ },
8472
+ {
8473
+ name: "milestone-phases-entry",
8474
+ jsonPath: ["milestonePhases", "entries"],
8475
+ description: "The phases, in order",
8476
+ valueName: "name=,percentage=",
8477
+ repeatable: true,
8478
+ element: ["name", "percentage"],
8479
+ elementTypes: { "percentage": ["string", "null"] },
8480
+ schema: z.array(z.string())
8481
+ },
8482
+ {
8483
+ name: "milestone-phases-mode",
8484
+ jsonPath: ["milestonePhases", "mode"],
8485
+ description: "PERCENTAGE, the only way a phase's share is expressed",
8486
+ valueName: "value",
8487
+ schema: z.string()
8488
+ },
8489
+ {
8490
+ name: "pricing-mode",
8491
+ jsonPath: ["pricingMode"],
8492
+ description: "PER_UNIT to charge the unit price for each unit, or FIXED to charge the fixed price whatever the quantity",
8493
+ valueName: "value",
8494
+ nullable: true,
8495
+ schema: toEnum(["FIXED", "PER_UNIT"])
8496
+ },
8497
+ {
8498
+ name: "quantity",
8499
+ jsonPath: ["quantity"],
8500
+ description: "The number of units the line item covers, which is zero or more",
8501
+ valueName: "number",
8502
+ nullable: true,
8503
+ schema: toNumber(z.number().int())
8504
+ },
8505
+ {
8506
+ name: "total-override-amount",
8507
+ jsonPath: ["totalOverride", "amount"],
8508
+ description: "The value as a decimal string with two decimal places",
8509
+ valueName: "value",
8510
+ schema: z.string()
8511
+ },
8512
+ {
8513
+ name: "total-override-iso-code",
8514
+ jsonPath: ["totalOverride", "isoCode"],
8515
+ description: "The value's ISO 4217 currency code",
8516
+ valueName: "value",
8517
+ schema: z.string()
8518
+ },
8519
+ {
8520
+ name: "transaction-type",
8521
+ jsonPath: ["transactionType"],
8522
+ description: "SALE to sell the item, which only a physical item allows, or SERVICE to provide it as a service",
8523
+ valueName: "value",
8524
+ nullable: true,
8525
+ schema: toEnum(["SALE", "SERVICE"])
8526
+ },
8527
+ {
8528
+ name: "unit-price-amount",
8529
+ jsonPath: ["unitPrice", "amount"],
8530
+ description: "The value as a decimal string with two decimal places",
8531
+ valueName: "value",
8532
+ schema: z.string()
8533
+ },
8534
+ {
8535
+ name: "unit-price-iso-code",
8536
+ jsonPath: ["unitPrice", "isoCode"],
8537
+ description: "The value's ISO 4217 currency code",
8538
+ valueName: "value",
8539
+ schema: z.string()
8540
+ }
8541
+ ]
8542
+ }), {
8543
+ name: "charges",
8544
+ summary: "Charges commands",
8545
+ arguments: [],
8546
+ flags: [],
8547
+ examples: [],
8548
+ subcommands: [defineOperation({
8549
+ name: "list",
8550
+ summary: "Get project line item charges",
8551
+ example: "hardfin project line-item charges list proj_7hq2lm9xcr4twz8k ppb_4tn8wq2zkv7mx9cr",
8552
+ method: "GET",
8553
+ path: "/project/{projectKey}/line-item/{lineItemKey}/charges",
8554
+ pathParameters: [{
8555
+ name: "projectKey",
8556
+ description: "The key of the project the line item belongs to",
8557
+ required: true
8558
+ }, {
8559
+ name: "lineItemKey",
8560
+ description: "The key of the line item whose charges to return",
8561
+ required: true
8562
+ }],
8563
+ queryFlags: [],
8564
+ bodyFlags: []
8565
+ })]
8566
+ }]
8567
+ }
8568
+ ]
8569
+ },
8570
+ {
8571
+ name: "shipment",
8572
+ summary: "Shipment commands",
8573
+ arguments: [],
8574
+ flags: [],
8575
+ examples: [],
8576
+ subcommands: [
8577
+ defineOperation({
8578
+ name: "list",
8579
+ summary: "List shipments",
8580
+ example: "hardfin shipment list --limit 10",
8581
+ method: "GET",
8582
+ path: "/shipment",
8583
+ pathParameters: [],
8584
+ queryFlags: [
8585
+ {
8586
+ name: "page",
8587
+ queryName: "page",
8588
+ description: "The page to return, starting at 1",
8589
+ valueName: "number",
8590
+ schema: toNumber(z.number().int())
8591
+ },
8592
+ {
8593
+ name: "limit",
8594
+ queryName: "limit",
8595
+ description: "The number of records per page, from 1 to 100",
8596
+ valueName: "number",
8597
+ schema: toNumber(z.number().int().min(1).max(100))
8598
+ },
8599
+ {
8600
+ name: "sort-by",
8601
+ queryName: "sortBy",
8602
+ description: "The field to sort by",
8603
+ valueName: "value",
8604
+ schema: toEnum([
8605
+ "shipmentNumber",
8606
+ "shippingCostAmount",
8607
+ "totalValue",
8608
+ "status"
8609
+ ])
8610
+ },
8611
+ {
8612
+ name: "sort-order",
8613
+ queryName: "sortOrder",
8614
+ description: "The sort direction",
8615
+ valueName: "value",
8616
+ schema: toEnum(["ASC", "DESC"])
8617
+ },
8618
+ {
8619
+ name: "archived",
8620
+ queryName: "archived",
8621
+ description: "Whether to return unarchived records, archived records, or all of them",
8622
+ valueName: "value",
8623
+ schema: toEnum([
8624
+ "all",
8625
+ "false",
8626
+ "true"
8627
+ ])
8628
+ },
8629
+ {
8630
+ name: "status",
8631
+ queryName: "status",
8632
+ description: "The one status to list: OPEN, SHIPPED, DELIVERED, RECEIVED or CANCELLED",
8633
+ valueName: "value",
8634
+ schema: toEnum([
8635
+ "CANCELLED",
8636
+ "DELIVERED",
8637
+ "OPEN",
8638
+ "RECEIVED",
8639
+ "SHIPPED"
8640
+ ])
8641
+ },
8642
+ {
8643
+ name: "shipment-type",
8644
+ queryName: "shipmentType",
8645
+ description: "The one direction to list: INBOUND or OUTBOUND",
8646
+ valueName: "value",
8647
+ schema: toEnum(["INBOUND", "OUTBOUND"])
8648
+ },
8649
+ {
8650
+ name: "search",
8651
+ queryName: "search",
8652
+ description: "Text to find in the shipment's number, its order numbers, its reference number, its locations' names, or its items' names and SKUs",
8653
+ valueName: "value",
8654
+ schema: z.string()
8655
+ },
8656
+ {
8657
+ name: "fo-numbers",
8658
+ queryName: "foNumbers",
8659
+ description: "The fulfillment order numbers whose shipments to list",
8660
+ valueName: "value",
8661
+ repeatable: true,
8662
+ schema: z.array(z.string())
8663
+ },
8664
+ {
8665
+ name: "po-numbers",
8666
+ queryName: "poNumbers",
8667
+ description: "The purchase order numbers whose shipments to list",
8668
+ valueName: "value",
8669
+ repeatable: true,
8670
+ schema: z.array(z.string())
8671
+ },
8672
+ {
8673
+ name: "ro-numbers",
8674
+ queryName: "roNumbers",
8675
+ description: "The return order numbers whose shipments to list",
8676
+ valueName: "value",
8677
+ repeatable: true,
8678
+ schema: z.array(z.string())
8679
+ },
8680
+ {
8681
+ name: "location-ids",
8682
+ queryName: "locationIds",
8683
+ description: "The IDs of locations, and only shipments leaving from or going to one of them are listed",
8684
+ valueName: "uuid",
8685
+ repeatable: true,
8686
+ schema: z.array(z.uuid())
8687
+ },
8688
+ {
8689
+ name: "from-location-ids",
8690
+ queryName: "fromLocationIds",
8691
+ description: "The IDs of locations, and shipments leaving from one of them are listed",
8692
+ valueName: "uuid",
8693
+ repeatable: true,
8694
+ schema: z.array(z.uuid())
8695
+ },
8696
+ {
8697
+ name: "to-location-ids",
8698
+ queryName: "toLocationIds",
8699
+ description: "The IDs of locations, and shipments going to one of them are listed",
8700
+ valueName: "uuid",
8701
+ repeatable: true,
8702
+ schema: z.array(z.uuid())
8703
+ },
8704
+ {
8705
+ name: "from-customer-ids",
8706
+ queryName: "fromCustomerIds",
8707
+ description: "The IDs of customers, and shipments leaving from a location assigned to one of them are listed",
8708
+ valueName: "uuid",
8709
+ repeatable: true,
8710
+ schema: z.array(z.uuid())
8711
+ },
8712
+ {
8713
+ name: "to-customer-ids",
8714
+ queryName: "toCustomerIds",
8715
+ description: "The IDs of customers, and shipments going to a location assigned to one of them are listed",
8716
+ valueName: "uuid",
8717
+ repeatable: true,
8718
+ schema: z.array(z.uuid())
8719
+ },
8720
+ {
8721
+ name: "from-location-company-types",
8722
+ queryName: "fromLocationCompanyTypes",
8723
+ description: "The kind of site listed shipments leave from, a CUSTOMER site or one of the organization's own MANUFACTURER sites, and naming both filters nothing",
8724
+ valueName: "value",
8725
+ repeatable: true,
8726
+ schema: z.array(toEnum(["CUSTOMER", "MANUFACTURER"]))
8727
+ },
8728
+ {
8729
+ name: "to-location-company-types",
8730
+ queryName: "toLocationCompanyTypes",
8731
+ description: "The kind of site listed shipments go to, a CUSTOMER site or one of the organization's own MANUFACTURER sites, and naming both filters nothing",
8732
+ valueName: "value",
8733
+ repeatable: true,
8734
+ schema: z.array(toEnum(["CUSTOMER", "MANUFACTURER"]))
8735
+ }
8736
+ ],
8737
+ bodyFlags: []
8738
+ }),
8739
+ defineOperation({
8740
+ name: "create",
8741
+ summary: "Create shipment",
8742
+ example: "hardfin shipment create --item externalReference=<value>,itemId=<value>,quantity=<value>,serials=<value> --shipment-type <value> --to-location-id <uuid>",
8743
+ method: "POST",
8744
+ path: "/shipment",
8745
+ pathParameters: [],
8746
+ queryFlags: [],
8747
+ bodyFlags: [
8748
+ {
8749
+ name: "carrier",
8750
+ jsonPath: ["carrier"],
8751
+ description: "Who carries the shipment, or null when no carrier is named",
8752
+ valueName: "value",
8753
+ nullable: true,
8754
+ schema: toEnum([
8755
+ "airterra",
8756
+ "apc_postal",
8757
+ "apg",
8758
+ "aramex",
8759
+ "asendia_us",
8760
+ "australia_post",
8761
+ "axlehire",
8762
+ "better_trucks",
8763
+ "borderguru",
8764
+ "boxberry",
8765
+ "bring",
8766
+ "canada_post",
8767
+ "cdl",
8768
+ "chronopost",
8769
+ "colissimo",
8770
+ "collect_plus",
8771
+ "correios_br",
8772
+ "correos_espana",
8773
+ "couriersplease",
8774
+ "deutsche_post",
8775
+ "dhl_benelux",
8776
+ "dhl_ecommerce",
8777
+ "dhl_express",
8778
+ "dhl_germany",
8779
+ "dhl_germany_c2c",
8780
+ "dpd_de",
8781
+ "dpd_uk",
8782
+ "estafeta",
8783
+ "fastway_australia",
8784
+ "fedex",
8785
+ "globegistics",
8786
+ "gls_us",
8787
+ "gophr",
8788
+ "gso",
8789
+ "hermes_germany_b2c",
8790
+ "hermes_uk",
8791
+ "hongkong_post",
8792
+ "la_poste",
8793
+ "lasership",
8794
+ "lso",
8795
+ "mondial_relay",
8796
+ "new_zealand_post",
8797
+ "nippon_express",
8798
+ "ontrac",
8799
+ "orangeds",
8800
+ "other",
8801
+ "parcel",
8802
+ "parcelforce",
8803
+ "passport",
8804
+ "pcf",
8805
+ "pitney_bowes",
8806
+ "poste_italiane",
8807
+ "posti",
8808
+ "purolator",
8809
+ "royal_mail",
8810
+ "royal_mail_sf",
8811
+ "rr_donnelley",
8812
+ "russian_post",
8813
+ "sendle",
8814
+ "shippo",
8815
+ "skypostal",
8816
+ "stuart",
8817
+ "swyft",
8818
+ "uds",
8819
+ "ups",
8820
+ "usps",
8821
+ "veho",
8822
+ "x_delivery",
8823
+ "yodel"
8824
+ ])
8825
+ },
8826
+ {
8827
+ name: "delivered-at",
8828
+ jsonPath: ["deliveredAt"],
8829
+ description: "When the shipment arrived, which cannot be before ShippedAt, or null while it has not",
8830
+ valueName: "value",
8831
+ nullable: true,
8832
+ schema: z.string()
8833
+ },
8834
+ {
8835
+ name: "delivered-at-timezone",
8836
+ jsonPath: ["deliveredAtTimezone"],
8837
+ description: "The IANA time zone DeliveredAt is recorded in",
8838
+ valueName: "value",
8839
+ nullable: true,
8840
+ schema: z.string()
8841
+ },
8842
+ {
8843
+ name: "expected-delivered-on",
8844
+ jsonPath: ["expectedDeliveredOn"],
8845
+ description: "The day the shipment is expected to arrive, which on an inbound shipment cannot be before ExpectedShippedOn",
8846
+ valueName: "value",
8847
+ nullable: true,
8848
+ schema: z.string()
8849
+ },
8850
+ {
8851
+ name: "expected-shipped-on",
8852
+ jsonPath: ["expectedShippedOn"],
8853
+ description: "The day the shipment is expected to leave",
8854
+ valueName: "value",
8855
+ nullable: true,
8856
+ schema: z.string()
8857
+ },
8858
+ {
8859
+ name: "from-location-id",
8860
+ jsonPath: ["fromLocationId"],
8861
+ description: "The ID of the location the shipment leaves from, which an outbound shipment requires",
8862
+ valueName: "uuid",
8863
+ nullable: true,
8864
+ schema: z.uuid()
8865
+ },
8866
+ {
8867
+ name: "fulfillment-order-number",
8868
+ jsonPath: ["fulfillmentOrderNumber"],
8869
+ description: "The number of the fulfillment order an outbound shipment fills, or null for none",
8870
+ valueName: "value",
8871
+ nullable: true,
8872
+ schema: z.string()
8873
+ },
8874
+ {
8875
+ name: "item",
8876
+ jsonPath: ["items"],
8877
+ description: "The shipment's line items, from 1 to 100 of them",
8878
+ valueName: "externalReference=,itemId=,quantity=,serials=",
8879
+ repeatable: true,
8880
+ required: true,
8881
+ element: [
8882
+ "externalReference",
8883
+ "itemId",
8884
+ "quantity",
8885
+ "serials"
8886
+ ],
8887
+ elementUuids: ["itemId"],
8888
+ elementTypes: {
8889
+ "externalReference": ["string", "null"],
8890
+ "quantity": ["integer", "null"],
8891
+ "serials": ["array"]
8892
+ },
8893
+ elementLists: ["serials"],
8894
+ schema: z.array(z.string())
8895
+ },
8896
+ {
8897
+ name: "other-carrier",
8898
+ jsonPath: ["otherCarrier"],
8899
+ description: "The carrier's name when Carrier is other",
8900
+ valueName: "value",
8901
+ nullable: true,
8902
+ schema: z.string()
8903
+ },
8904
+ {
8905
+ name: "purchase-order-number",
8906
+ jsonPath: ["purchaseOrderNumber"],
8907
+ description: "The number of the purchase order an inbound shipment fills, or null for none",
8908
+ valueName: "value",
8909
+ nullable: true,
8910
+ schema: z.string()
8911
+ },
8912
+ {
8913
+ name: "reference-number",
8914
+ jsonPath: ["referenceNumber"],
8915
+ description: "The number the carrier tracks the shipment by, or null when it has none",
8916
+ valueName: "value",
8917
+ nullable: true,
8918
+ schema: z.string()
8919
+ },
8920
+ {
8921
+ name: "return-order-number",
8922
+ jsonPath: ["returnOrderNumber"],
8923
+ description: "The number of the return order an inbound shipment fills, or null for none",
8924
+ valueName: "value",
8925
+ nullable: true,
8926
+ schema: z.string()
8927
+ },
8928
+ {
8929
+ name: "shipment-note",
8930
+ jsonPath: ["shipmentNote"],
8931
+ description: "A note about the shipment",
8932
+ valueName: "value",
8933
+ nullable: true,
8934
+ schema: z.string()
8935
+ },
8936
+ {
8937
+ name: "shipment-type",
8938
+ jsonPath: ["shipmentType"],
8939
+ description: "Whether the shipment is INBOUND to the organization or OUTBOUND from it",
8940
+ valueName: "value",
8941
+ required: true,
8942
+ schema: toEnum(["INBOUND", "OUTBOUND"])
8943
+ },
8944
+ {
8945
+ name: "shipped-at",
8946
+ jsonPath: ["shippedAt"],
8947
+ description: "When the shipment left, or null while it has not",
8948
+ valueName: "value",
8949
+ nullable: true,
8950
+ schema: z.string()
8951
+ },
8952
+ {
8953
+ name: "shipped-at-timezone",
8954
+ jsonPath: ["shippedAtTimezone"],
8955
+ description: "The IANA time zone ShippedAt is recorded in",
8956
+ valueName: "value",
8957
+ nullable: true,
8958
+ schema: z.string()
8959
+ },
8960
+ {
8961
+ name: "shipping-cost-amount",
8962
+ jsonPath: ["shippingCost", "amount"],
8963
+ description: "The value as a decimal string with two decimal places",
8964
+ valueName: "value",
8965
+ schema: z.string()
8966
+ },
8967
+ {
8968
+ name: "shipping-cost-iso-code",
8969
+ jsonPath: ["shippingCost", "isoCode"],
8970
+ description: "The value's ISO 4217 currency code",
8971
+ valueName: "value",
8972
+ schema: z.string()
8973
+ },
8974
+ {
8975
+ name: "to-location-id",
8976
+ jsonPath: ["toLocationId"],
8977
+ description: "The ID of the location the shipment is going to",
8978
+ valueName: "uuid",
8979
+ required: true,
8980
+ schema: z.uuid()
8981
+ }
8982
+ ]
8983
+ }),
8984
+ defineOperation({
8985
+ name: "get",
8986
+ summary: "Get shipment",
8987
+ example: "hardfin shipment get shp_2wn8kq4lxp7rtz3m",
8988
+ method: "GET",
8989
+ path: "/shipment/{shipmentKey}",
8990
+ pathParameters: [{
8991
+ name: "shipmentKey",
8992
+ description: "The shipment's key",
8993
+ required: true
8994
+ }],
8995
+ queryFlags: [],
8996
+ bodyFlags: []
8997
+ }),
8998
+ defineOperation({
8999
+ name: "update",
9000
+ summary: "Update shipment",
9001
+ example: "hardfin shipment update shp_2wn8kq4lxp7rtz3m --item externalReference=<value>,itemId=<value>,quantity=<value>,serials=<value>",
9002
+ method: "PATCH",
9003
+ path: "/shipment/{shipmentKey}",
9004
+ pathParameters: [{
9005
+ name: "shipmentKey",
9006
+ description: "The shipment's key",
9007
+ required: true
9008
+ }],
9009
+ queryFlags: [],
9010
+ bodyFlags: [
9011
+ {
9012
+ name: "carrier",
9013
+ jsonPath: ["carrier"],
9014
+ description: "Who carries the shipment, or null when no carrier is named",
9015
+ valueName: "value",
9016
+ nullable: true,
9017
+ schema: toEnum([
9018
+ "airterra",
9019
+ "apc_postal",
9020
+ "apg",
9021
+ "aramex",
9022
+ "asendia_us",
9023
+ "australia_post",
9024
+ "axlehire",
9025
+ "better_trucks",
9026
+ "borderguru",
9027
+ "boxberry",
9028
+ "bring",
9029
+ "canada_post",
9030
+ "cdl",
9031
+ "chronopost",
9032
+ "colissimo",
9033
+ "collect_plus",
9034
+ "correios_br",
9035
+ "correos_espana",
9036
+ "couriersplease",
9037
+ "deutsche_post",
9038
+ "dhl_benelux",
9039
+ "dhl_ecommerce",
9040
+ "dhl_express",
9041
+ "dhl_germany",
9042
+ "dhl_germany_c2c",
9043
+ "dpd_de",
9044
+ "dpd_uk",
9045
+ "estafeta",
9046
+ "fastway_australia",
9047
+ "fedex",
9048
+ "globegistics",
9049
+ "gls_us",
9050
+ "gophr",
9051
+ "gso",
9052
+ "hermes_germany_b2c",
9053
+ "hermes_uk",
9054
+ "hongkong_post",
9055
+ "la_poste",
9056
+ "lasership",
9057
+ "lso",
9058
+ "mondial_relay",
9059
+ "new_zealand_post",
9060
+ "nippon_express",
9061
+ "ontrac",
9062
+ "orangeds",
9063
+ "other",
9064
+ "parcel",
9065
+ "parcelforce",
9066
+ "passport",
9067
+ "pcf",
9068
+ "pitney_bowes",
9069
+ "poste_italiane",
9070
+ "posti",
9071
+ "purolator",
9072
+ "royal_mail",
9073
+ "royal_mail_sf",
9074
+ "rr_donnelley",
9075
+ "russian_post",
9076
+ "sendle",
9077
+ "shippo",
9078
+ "skypostal",
9079
+ "stuart",
9080
+ "swyft",
9081
+ "uds",
9082
+ "ups",
9083
+ "usps",
9084
+ "veho",
9085
+ "x_delivery",
9086
+ "yodel"
9087
+ ])
9088
+ },
9089
+ {
9090
+ name: "delivered-at",
9091
+ jsonPath: ["deliveredAt"],
9092
+ description: "When the shipment arrived, which cannot be before ShippedAt",
9093
+ valueName: "value",
9094
+ nullable: true,
9095
+ schema: z.string()
9096
+ },
9097
+ {
9098
+ name: "delivered-at-timezone",
9099
+ jsonPath: ["deliveredAtTimezone"],
9100
+ description: "The IANA time zone DeliveredAt is recorded in",
9101
+ valueName: "value",
9102
+ nullable: true,
9103
+ schema: z.string()
9104
+ },
9105
+ {
9106
+ name: "delivery-note",
9107
+ jsonPath: ["deliveryNote"],
9108
+ description: "The note written when the shipment was delivered",
9109
+ valueName: "value",
9110
+ nullable: true,
9111
+ schema: z.string()
9112
+ },
9113
+ {
9114
+ name: "expected-delivered-on",
9115
+ jsonPath: ["expectedDeliveredOn"],
9116
+ description: "The day the shipment is expected to arrive, which on an inbound shipment cannot be before ExpectedShippedOn",
9117
+ valueName: "value",
9118
+ nullable: true,
9119
+ schema: z.string()
9120
+ },
9121
+ {
9122
+ name: "expected-shipped-on",
9123
+ jsonPath: ["expectedShippedOn"],
9124
+ description: "The day the shipment is expected to leave",
9125
+ valueName: "value",
9126
+ nullable: true,
9127
+ schema: z.string()
9128
+ },
9129
+ {
9130
+ name: "from-location-id",
9131
+ jsonPath: ["fromLocationId"],
9132
+ description: "The ID of the location the shipment leaves from, which an outbound shipment cannot clear",
9133
+ valueName: "uuid",
9134
+ nullable: true,
9135
+ schema: z.uuid()
9136
+ },
9137
+ {
9138
+ name: "fulfillment-order-number",
9139
+ jsonPath: ["fulfillmentOrderNumber"],
9140
+ description: "The number of the fulfillment order an outbound shipment fills, or null for none",
9141
+ valueName: "value",
9142
+ nullable: true,
9143
+ schema: z.string()
9144
+ },
9145
+ {
9146
+ name: "item",
9147
+ jsonPath: ["items"],
9148
+ description: "The 1 to 100 line items that replace the shipment's, where a line already on the shipment keeps its quantity when sent without one",
9149
+ valueName: "externalReference=,itemId=,quantity=,serials=",
9150
+ repeatable: true,
9151
+ element: [
9152
+ "externalReference",
9153
+ "itemId",
9154
+ "quantity",
9155
+ "serials"
9156
+ ],
9157
+ elementUuids: ["itemId"],
9158
+ elementTypes: {
9159
+ "externalReference": ["string", "null"],
9160
+ "quantity": ["integer", "null"],
9161
+ "serials": ["array"]
9162
+ },
9163
+ elementLists: ["serials"],
9164
+ schema: z.array(z.string())
9165
+ },
9166
+ {
9167
+ name: "other-carrier",
9168
+ jsonPath: ["otherCarrier"],
9169
+ description: "The carrier's name when Carrier is other",
9170
+ valueName: "value",
9171
+ nullable: true,
9172
+ schema: z.string()
9173
+ },
9174
+ {
9175
+ name: "purchase-order-number",
9176
+ jsonPath: ["purchaseOrderNumber"],
9177
+ description: "The number of the purchase order an inbound shipment fills, or null for none",
9178
+ valueName: "value",
9179
+ nullable: true,
9180
+ schema: z.string()
9181
+ },
9182
+ {
9183
+ name: "receipt-note",
9184
+ jsonPath: ["receiptNote"],
9185
+ description: "The note written when the shipment was received",
9186
+ valueName: "value",
9187
+ nullable: true,
9188
+ schema: z.string()
9189
+ },
9190
+ {
9191
+ name: "reference-number",
9192
+ jsonPath: ["referenceNumber"],
9193
+ description: "The number the carrier tracks the shipment by, or null when it has none",
9194
+ valueName: "value",
9195
+ nullable: true,
9196
+ schema: z.string()
9197
+ },
9198
+ {
9199
+ name: "return-order-number",
9200
+ jsonPath: ["returnOrderNumber"],
9201
+ description: "The number of the return order an inbound shipment fills, or null for none",
9202
+ valueName: "value",
9203
+ nullable: true,
9204
+ schema: z.string()
9205
+ },
9206
+ {
9207
+ name: "shipment-note",
9208
+ jsonPath: ["shipmentNote"],
9209
+ description: "A note about the shipment",
9210
+ valueName: "value",
9211
+ nullable: true,
9212
+ schema: z.string()
9213
+ },
9214
+ {
9215
+ name: "shipped-at",
9216
+ jsonPath: ["shippedAt"],
9217
+ description: "When the shipment left, or null while it has not",
9218
+ valueName: "value",
9219
+ nullable: true,
9220
+ schema: z.string()
9221
+ },
9222
+ {
9223
+ name: "shipped-at-timezone",
9224
+ jsonPath: ["shippedAtTimezone"],
9225
+ description: "The IANA time zone ShippedAt is recorded in",
9226
+ valueName: "value",
9227
+ nullable: true,
9228
+ schema: z.string()
9229
+ },
9230
+ {
9231
+ name: "shipping-cost-amount",
9232
+ jsonPath: ["shippingCost", "amount"],
9233
+ description: "The value as a decimal string with two decimal places",
9234
+ valueName: "value",
9235
+ schema: z.string()
9236
+ },
9237
+ {
9238
+ name: "shipping-cost-iso-code",
9239
+ jsonPath: ["shippingCost", "isoCode"],
9240
+ description: "The value's ISO 4217 currency code",
9241
+ valueName: "value",
9242
+ schema: z.string()
9243
+ },
9244
+ {
9245
+ name: "to-location-id",
9246
+ jsonPath: ["toLocationId"],
9247
+ description: "The ID of the location the shipment is going to, which cannot be cleared",
9248
+ valueName: "uuid",
9249
+ nullable: true,
9250
+ schema: z.uuid()
9251
+ }
9252
+ ]
9253
+ }),
9254
+ defineOperation({
9255
+ name: "cancel",
9256
+ summary: "Cancel shipment",
9257
+ example: "hardfin shipment cancel shp_2wn8kq4lxp7rtz3m --reason <value>",
9258
+ method: "POST",
9259
+ path: "/shipment/{shipmentKey}/cancel",
9260
+ pathParameters: [{
9261
+ name: "shipmentKey",
9262
+ description: "The shipment's key",
9263
+ required: true
9264
+ }],
9265
+ queryFlags: [],
9266
+ bodyFlags: [{
9267
+ name: "reason",
9268
+ jsonPath: ["reason"],
9269
+ description: "Why the shipment is cancelled, which is required",
9270
+ valueName: "value",
9271
+ required: true,
9272
+ schema: z.string()
9273
+ }, {
9274
+ name: "remove-linked-shipping-cost",
9275
+ jsonPath: ["removeLinkedShippingCost"],
9276
+ description: "True to also remove the shipping cost recorded for the shipment",
9277
+ negatable: true,
9278
+ schema: z.boolean()
9279
+ }]
9280
+ }),
9281
+ defineOperation({
9282
+ name: "deliver",
9283
+ summary: "Mark shipment as delivered",
9284
+ example: "hardfin shipment deliver shp_2wn8kq4lxp7rtz3m --delivered-at <value> --delivery-location-id <uuid>",
9285
+ method: "POST",
9286
+ path: "/shipment/{shipmentKey}/deliver",
9287
+ pathParameters: [{
9288
+ name: "shipmentKey",
9289
+ description: "The shipment's key",
9290
+ required: true
9291
+ }],
9292
+ queryFlags: [],
9293
+ bodyFlags: [
9294
+ {
9295
+ name: "delivered-at",
9296
+ jsonPath: ["deliveredAt"],
9297
+ description: "When the shipment arrived",
9298
+ valueName: "value",
9299
+ required: true,
9300
+ schema: z.string()
9301
+ },
9302
+ {
9303
+ name: "delivered-at-timezone",
9304
+ jsonPath: ["deliveredAtTimezone"],
9305
+ description: "The IANA time zone DeliveredAt is recorded in",
9306
+ valueName: "value",
9307
+ nullable: true,
9308
+ schema: z.string()
9309
+ },
9310
+ {
9311
+ name: "delivery-location-id",
9312
+ jsonPath: ["deliveryLocationId"],
9313
+ description: "The ID of the location the shipment was delivered to",
9314
+ valueName: "uuid",
9315
+ required: true,
9316
+ schema: z.uuid()
9317
+ },
9318
+ {
9319
+ name: "delivery-note",
9320
+ jsonPath: ["deliveryNote"],
9321
+ description: "A note about the delivery",
9322
+ valueName: "value",
9323
+ nullable: true,
9324
+ schema: z.string()
9325
+ }
9326
+ ]
9327
+ }),
9328
+ defineOperation({
9329
+ name: "receive",
9330
+ summary: "Mark inbound shipment as received",
9331
+ example: "hardfin shipment receive shp_2wn8kq4lxp7rtz3m --item externalReference=<value>,itemId=<value>,quantity=<value>,serials=<value> --receive-location-id <uuid> --received-at <value>",
9332
+ method: "POST",
9333
+ path: "/shipment/{shipmentKey}/receive",
9334
+ pathParameters: [{
9335
+ name: "shipmentKey",
9336
+ description: "The shipment's key",
9337
+ required: true
9338
+ }],
9339
+ queryFlags: [],
9340
+ bodyFlags: [
9341
+ {
9342
+ name: "item",
9343
+ jsonPath: ["items"],
9344
+ description: "What arrived on each line",
9345
+ valueName: "externalReference=,itemId=,quantity=,serials=",
9346
+ repeatable: true,
9347
+ element: [
9348
+ "externalReference",
9349
+ "itemId",
9350
+ "quantity",
9351
+ "serials"
9352
+ ],
9353
+ elementUuids: ["itemId"],
9354
+ elementTypes: {
9355
+ "externalReference": ["string", "null"],
9356
+ "quantity": ["integer", "null"],
9357
+ "serials": ["array"]
9358
+ },
9359
+ elementLists: ["serials"],
9360
+ schema: z.array(z.string())
9361
+ },
9362
+ {
9363
+ name: "receipt-note",
9364
+ jsonPath: ["receiptNote"],
9365
+ description: "A note about the receipt",
9366
+ valueName: "value",
9367
+ nullable: true,
9368
+ schema: z.string()
9369
+ },
9370
+ {
9371
+ name: "receive-location-id",
9372
+ jsonPath: ["receiveLocationId"],
9373
+ description: "The ID of the location the items were received at",
9374
+ valueName: "uuid",
9375
+ required: true,
9376
+ schema: z.uuid()
9377
+ },
9378
+ {
9379
+ name: "received-at",
9380
+ jsonPath: ["receivedAt"],
9381
+ description: "When the items were received",
9382
+ valueName: "value",
9383
+ required: true,
9384
+ schema: z.string()
9385
+ },
9386
+ {
9387
+ name: "received-at-timezone",
9388
+ jsonPath: ["receivedAtTimezone"],
9389
+ description: "The IANA time zone ReceivedAt is recorded in",
9390
+ valueName: "value",
9391
+ nullable: true,
9392
+ schema: z.string()
9393
+ }
9394
+ ]
9395
+ }),
9396
+ defineOperation({
9397
+ name: "ship",
9398
+ summary: "Mark outbound shipment as shipped",
9399
+ example: "hardfin shipment ship shp_2wn8kq4lxp7rtz3m --item externalReference=<value>,itemId=<value>,quantity=<value>,serials=<value> --ship-location-id <uuid> --shipped-at <value>",
9400
+ method: "POST",
9401
+ path: "/shipment/{shipmentKey}/ship",
9402
+ pathParameters: [{
9403
+ name: "shipmentKey",
9404
+ description: "The shipment's key",
9405
+ required: true
9406
+ }],
9407
+ queryFlags: [],
9408
+ bodyFlags: [
9409
+ {
9410
+ name: "item",
9411
+ jsonPath: ["items"],
9412
+ description: "What left on each line, with the serial numbers of the units tracked by serial",
9413
+ valueName: "externalReference=,itemId=,quantity=,serials=",
9414
+ repeatable: true,
9415
+ element: [
9416
+ "externalReference",
9417
+ "itemId",
9418
+ "quantity",
9419
+ "serials"
9420
+ ],
9421
+ elementUuids: ["itemId"],
9422
+ elementTypes: {
9423
+ "externalReference": ["string", "null"],
9424
+ "quantity": ["integer", "null"],
9425
+ "serials": ["array"]
9426
+ },
9427
+ elementLists: ["serials"],
9428
+ schema: z.array(z.string())
9429
+ },
9430
+ {
9431
+ name: "ship-location-id",
9432
+ jsonPath: ["shipLocationId"],
9433
+ description: "The ID of the location the shipment left from",
9434
+ valueName: "uuid",
9435
+ required: true,
9436
+ schema: z.uuid()
9437
+ },
9438
+ {
9439
+ name: "shipment-note",
9440
+ jsonPath: ["shipmentNote"],
9441
+ description: "A note about the shipment",
9442
+ valueName: "value",
9443
+ nullable: true,
9444
+ schema: z.string()
9445
+ },
9446
+ {
9447
+ name: "shipped-at",
9448
+ jsonPath: ["shippedAt"],
9449
+ description: "When the shipment left",
9450
+ valueName: "value",
9451
+ required: true,
9452
+ schema: z.string()
9453
+ },
9454
+ {
9455
+ name: "shipped-at-timezone",
9456
+ jsonPath: ["shippedAtTimezone"],
9457
+ description: "The IANA time zone ShippedAt is recorded in",
9458
+ valueName: "value",
9459
+ nullable: true,
9460
+ schema: z.string()
9461
+ },
9462
+ {
9463
+ name: "shipping-cost-amount",
9464
+ jsonPath: ["shippingCost", "amount"],
9465
+ description: "The value as a decimal string with two decimal places",
9466
+ valueName: "value",
9467
+ schema: z.string()
9468
+ },
9469
+ {
9470
+ name: "shipping-cost-iso-code",
9471
+ jsonPath: ["shippingCost", "isoCode"],
9472
+ description: "The value's ISO 4217 currency code",
9473
+ valueName: "value",
9474
+ schema: z.string()
9475
+ }
9476
+ ]
9477
+ }),
9478
+ {
9479
+ name: "tracking",
9480
+ summary: "Tracking commands",
9481
+ arguments: [],
9482
+ flags: [],
9483
+ examples: [],
9484
+ subcommands: [defineOperation({
9485
+ name: "list",
9486
+ summary: "Get shipment tracking events",
9487
+ example: "hardfin shipment tracking list shp_2wn8kq4lxp7rtz3m",
9488
+ method: "GET",
9489
+ path: "/shipment/{shipmentKey}/tracking",
9490
+ pathParameters: [{
9491
+ name: "shipmentKey",
9492
+ description: "The shipment's key",
9493
+ required: true
9494
+ }],
9495
+ queryFlags: [],
9496
+ bodyFlags: []
9497
+ })]
9498
+ }
9499
+ ]
9500
+ },
9501
+ {
9502
+ name: "token",
9503
+ summary: "Token commands",
9504
+ arguments: [],
9505
+ flags: [],
9506
+ examples: [],
9507
+ subcommands: [defineOperation({
9508
+ name: "get",
9509
+ summary: "Report the credential this CLI is calling with",
9510
+ example: "hardfin token get",
9511
+ method: "GET",
9512
+ path: "/token",
9513
+ pathParameters: [],
9514
+ queryFlags: [],
9515
+ bodyFlags: []
9516
+ })]
9517
+ },
9518
+ {
9519
+ name: "url-link",
9520
+ summary: "URL link commands",
9521
+ arguments: [],
9522
+ flags: [],
9523
+ examples: [],
9524
+ subcommands: [
9525
+ defineOperation({
9526
+ name: "get",
9527
+ summary: "Get URL link by key",
9528
+ example: "hardfin url-link get link_7hq2mx9pcr4stz8w",
9529
+ method: "GET",
9530
+ path: "/url-link/{linkKey}",
9531
+ pathParameters: [{
9532
+ name: "linkKey",
9533
+ description: "The URL link's key",
9534
+ required: true
7313
9535
  }],
7314
9536
  queryFlags: [],
7315
9537
  bodyFlags: []
@@ -7329,16 +9551,15 @@ const commands = [
7329
9551
  bodyFlags: [{
7330
9552
  name: "name",
7331
9553
  jsonPath: ["name"],
7332
- description: "The link's display name, or null to show the address instead",
9554
+ description: "The link's display name, or null to show the address instead, and an update sends it, url, or both",
7333
9555
  valueName: "value",
7334
9556
  nullable: true,
7335
9557
  schema: z.string()
7336
9558
  }, {
7337
9559
  name: "url",
7338
9560
  jsonPath: ["url"],
7339
- description: "The address the link points to, which cannot be empty or null",
9561
+ description: "The address the link points to, which cannot be empty, and an update sends it, name, or both",
7340
9562
  valueName: "value",
7341
- nullable: true,
7342
9563
  schema: z.string()
7343
9564
  }]
7344
9565
  }),
@@ -7357,6 +9578,36 @@ const commands = [
7357
9578
  bodyFlags: []
7358
9579
  })
7359
9580
  ]
9581
+ },
9582
+ {
9583
+ name: "workflow",
9584
+ summary: "Workflow commands",
9585
+ arguments: [],
9586
+ flags: [],
9587
+ examples: [],
9588
+ subcommands: [defineOperation({
9589
+ name: "list",
9590
+ summary: "Get workflows",
9591
+ example: "hardfin workflow list",
9592
+ method: "GET",
9593
+ path: "/workflow",
9594
+ pathParameters: [],
9595
+ queryFlags: [],
9596
+ bodyFlags: []
9597
+ }), defineOperation({
9598
+ name: "get",
9599
+ summary: "Get workflow",
9600
+ example: "hardfin workflow get wrkfl_6wqmaf1pp98jevep",
9601
+ method: "GET",
9602
+ path: "/workflow/{workflowKey}",
9603
+ pathParameters: [{
9604
+ name: "workflowKey",
9605
+ description: "The workflow's key",
9606
+ required: true
9607
+ }],
9608
+ queryFlags: [],
9609
+ bodyFlags: []
9610
+ })]
7360
9611
  }
7361
9612
  ],
7362
9613
  apiCommand,
@@ -7464,5 +9715,5 @@ async function toReported(error, isJSON, resolved, level = "error") {
7464
9715
  //#endregion
7465
9716
  export { toCli, toParseExitCode, toReported, wasReportAttempted, writeCrash };
7466
9717
 
7467
- //# sourceMappingURL=program-CkKf46kC.js.map
7468
- //# debugId=d29068e8-3e79-5da9-aa3a-0c5201101ca3
9718
+ //# sourceMappingURL=program-DW6GS9xO.js.map
9719
+ //# debugId=980cc947-6ea9-593a-bdbf-bc8ecfc40c65