//native
/**
* Get table
* 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).
*/
export async function main(
auth: RT.IpFabric,
table_path: string,
columns: string[],
filters: { [key: string]: any } | undefined,
snapshot: string | undefined,
sort_column: string | undefined,
sort_order: "asc" | "desc" | undefined,
attribute_filters: { [key: string]: any } | undefined,
limit: number | undefined,
start: number | undefined
) {
// Accept "tables/x", "/tables/x" or a pasted "/api/v7.2/tables/x".
const path = table_path
.trim()
.replace(/^\/+/, "")
.replace(/^api\/(v[^/]+\/)?/, "")
const pageLimit = limit || 100
const pageStart = start || 0
const payload: { [key: string]: any } = {
columns,
filters: filters ?? {},
pagination: { limit: pageLimit, start: pageStart },
}
// Some tables (settings, tables/management/snapshots) take no snapshot.
if (snapshot !== "none") {
// The SDK maps "$lastlocked" to the canonical "$lastLocked".
payload.snapshot =
snapshot?.toLowerCase() === "$lastlocked"
? "$lastLocked"
: snapshot || "$last"
}
if (sort_column) {
payload.sort = { column: sort_column, order: sort_order || "asc" }
}
if (attribute_filters != null && Object.keys(attribute_filters).length > 0) {
payload.attributeFilters = attribute_filters
}
const version = (auth.api_version ?? "").trim()
// Same normalization as the official SDK: "7.2" / "v7.2" -> v7.2, "7" -> v7.0.
const match = version.match(/^v?(\d+)(?:\.(\d+))?/)
if (version && !match) {
throw new Error(
`api_version "${version}" is not valid, use v#.# (e.g. v7.2)`
)
}
const prefix = match ? `api/v${match[1]}.${match[2] ?? "0"}/` : "api/"
const base = auth.base_url.replace(/\/*$/, "/")
const url = new URL(`${prefix}${path}`, base)
// Stay under tables/: a "../" path would POST to another endpoint (e.g. start a discovery).
if (!url.pathname.startsWith(new URL(`${prefix}tables/`, base).pathname)) {
throw new Error(
`table_path must be a technology table under tables/, got "${table_path}"`
)
}
const response = await fetch(url, {
method: "POST",
headers: {
"X-API-Token": auth.token,
"Content-Type": "application/json",
Accept: "application/json",
},
body: JSON.stringify(payload),
})
if (!response.ok) {
throw new Error(`${response.status} ${await response.text()}`)
}
const result = (await response.json()) as {
data: { [key: string]: any }[]
_meta: { [key: string]: any }
}
return {
...result,
next_start:
result.data.length === pageLimit ? pageStart + result.data.length : null,
}
}
Submitted by hugo989 6 hours ago