0

Get table

by
Published today

Read one page of any IP Fabric technology table with chosen columns, filters, sort and snapshot.

Script ip_fabric Verified

The script

Submitted by hugo989 Typescript (fetch-only)
Verified 6 hours ago
1
//native
2

3
/**
4
 * Get table
5
 * Read one page of any IP Fabric technology table (e.g. tables/inventory/devices, tables/interfaces/transceivers/inventory) with chosen columns, filters, sort and snapshot (a snapshot id, $last, $prev or $lastLocked; default $last; "none" for tables that take no snapshot). Returns the rows, the table metadata and next_start (null on the last page).
6
 */
7
export async function main(
8
  auth: RT.IpFabric,
9
  table_path: string,
10
  columns: string[],
11
  filters: { [key: string]: any } | undefined,
12
  snapshot: string | undefined,
13
  sort_column: string | undefined,
14
  sort_order: "asc" | "desc" | undefined,
15
  attribute_filters: { [key: string]: any } | undefined,
16
  limit: number | undefined,
17
  start: number | undefined
18
) {
19
  // Accept "tables/x", "/tables/x" or a pasted "/api/v7.2/tables/x".
20
  const path = table_path
21
    .trim()
22
    .replace(/^\/+/, "")
23
    .replace(/^api\/(v[^/]+\/)?/, "")
24
  const pageLimit = limit || 100
25
  const pageStart = start || 0
26

27
  const payload: { [key: string]: any } = {
28
    columns,
29
    filters: filters ?? {},
30
    pagination: { limit: pageLimit, start: pageStart },
31
  }
32
  // Some tables (settings, tables/management/snapshots) take no snapshot.
33
  if (snapshot !== "none") {
34
    // The SDK maps "$lastlocked" to the canonical "$lastLocked".
35
    payload.snapshot =
36
      snapshot?.toLowerCase() === "$lastlocked"
37
        ? "$lastLocked"
38
        : snapshot || "$last"
39
  }
40
  if (sort_column) {
41
    payload.sort = { column: sort_column, order: sort_order || "asc" }
42
  }
43
  if (attribute_filters != null && Object.keys(attribute_filters).length > 0) {
44
    payload.attributeFilters = attribute_filters
45
  }
46

47
  const version = (auth.api_version ?? "").trim()
48
  // Same normalization as the official SDK: "7.2" / "v7.2" -> v7.2, "7" -> v7.0.
49
  const match = version.match(/^v?(\d+)(?:\.(\d+))?/)
50
  if (version && !match) {
51
    throw new Error(
52
      `api_version "${version}" is not valid, use v#.# (e.g. v7.2)`
53
    )
54
  }
55
  const prefix = match ? `api/v${match[1]}.${match[2] ?? "0"}/` : "api/"
56
  const base = auth.base_url.replace(/\/*$/, "/")
57
  const url = new URL(`${prefix}${path}`, base)
58
  // Stay under tables/: a "../" path would POST to another endpoint (e.g. start a discovery).
59
  if (!url.pathname.startsWith(new URL(`${prefix}tables/`, base).pathname)) {
60
    throw new Error(
61
      `table_path must be a technology table under tables/, got "${table_path}"`
62
    )
63
  }
64

65
  const response = await fetch(url, {
66
    method: "POST",
67
    headers: {
68
      "X-API-Token": auth.token,
69
      "Content-Type": "application/json",
70
      Accept: "application/json",
71
    },
72
    body: JSON.stringify(payload),
73
  })
74

75
  if (!response.ok) {
76
    throw new Error(`${response.status} ${await response.text()}`)
77
  }
78

79
  const result = (await response.json()) as {
80
    data: { [key: string]: any }[]
81
    _meta: { [key: string]: any }
82
  }
83
  return {
84
    ...result,
85
    next_start:
86
      result.data.length === pageLimit ? pageStart + result.data.length : null,
87
  }
88
}
89