1 | |
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 | |
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 | |
33 | if (snapshot !== "none") { |
34 | |
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 | |
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 | |
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 |
|