0

List Record Types

by
Published today

List every record type exposed by the SuiteTalk REST record API (the metadata catalog), including custom records.

Script netsuite Verified

The script

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

3
const percentEncode = (s: string) =>
4
  encodeURIComponent(s).replace(
5
    /[!'()*]/g,
6
    (c) => "%" + c.charCodeAt(0).toString(16).toUpperCase()
7
  )
8

9
function restBase(auth: RT.Netsuite) {
10
  return `https://${auth.account_id.trim().toLowerCase()}.suitetalk.api.netsuite.com/services/rest`
11
}
12

13
// Bearer when an OAuth 2.0 token is set, otherwise TBA (OAuth 1.0a HMAC-SHA256).
14
async function authHeader(auth: RT.Netsuite, method: string, url: URL) {
15
  if (auth.token !== undefined && auth.token !== "") {
16
    return `Bearer ${auth.token}`
17
  }
18
  // Re-serialize the query with %20 instead of '+' for spaces so the URL on
19
  // the wire matches the form the signature base string encodes
20
  url.search = [...url.searchParams.entries()]
21
    .map(([k, v]) => `${percentEncode(k)}=${percentEncode(v)}`)
22
    .join("&")
23
  const nonce = Array.from(crypto.getRandomValues(new Uint8Array(16)), (b) =>
24
    b.toString(16).padStart(2, "0")
25
  ).join("")
26
  const timestamp = Math.floor(Date.now() / 1000).toString()
27
  const oauthParams: [string, string][] = [
28
    ["oauth_consumer_key", auth.consumer_key ?? ""],
29
    ["oauth_nonce", nonce],
30
    ["oauth_signature_method", "HMAC-SHA256"],
31
    ["oauth_timestamp", timestamp],
32
    ["oauth_token", auth.token_id ?? ""],
33
    ["oauth_version", "1.0"],
34
  ]
35
  const sortedParams = [...url.searchParams.entries(), ...oauthParams]
36
    .map(([k, v]) => [percentEncode(k), percentEncode(v)])
37
    .sort(([ak, av], [bk, bv]) =>
38
      ak === bk ? (av < bv ? -1 : 1) : ak < bk ? -1 : 1
39
    )
40
    .map(([k, v]) => `${k}=${v}`)
41
    .join("&")
42
  const baseString = [
43
    method.toUpperCase(),
44
    percentEncode(`${url.protocol}//${url.host}${url.pathname}`),
45
    percentEncode(sortedParams),
46
  ].join("&")
47
  const key = await crypto.subtle.importKey(
48
    "raw",
49
    new TextEncoder().encode(
50
      `${percentEncode(auth.consumer_secret ?? "")}&${percentEncode(auth.token_secret ?? "")}`
51
    ),
52
    { name: "HMAC", hash: "SHA-256" },
53
    false,
54
    ["sign"]
55
  )
56
  const signature = btoa(
57
    String.fromCharCode(
58
      ...new Uint8Array(
59
        await crypto.subtle.sign(
60
          "HMAC",
61
          key,
62
          new TextEncoder().encode(baseString)
63
        )
64
      )
65
    )
66
  )
67
  const realm = auth.account_id.trim().toUpperCase().replace(/-/g, "_")
68
  return `OAuth realm="${realm}", oauth_consumer_key="${percentEncode(auth.consumer_key ?? "")}", oauth_token="${percentEncode(auth.token_id ?? "")}", oauth_signature_method="HMAC-SHA256", oauth_timestamp="${timestamp}", oauth_nonce="${nonce}", oauth_version="1.0", oauth_signature="${percentEncode(signature)}"`
69
}
70

71
/**
72
 * List Record Types
73
 * List every record type exposed by the SuiteTalk REST record API (the metadata catalog), including custom records.
74
 */
75
export async function main(auth: RT.Netsuite) {
76
  const url = new URL(`${restBase(auth)}/record/v1/metadata-catalog`)
77
  const response = await fetch(url, {
78
    headers: {
79
      Authorization: await authHeader(auth, "GET", url),
80
      Accept: "application/json",
81
    },
82
  })
83
  if (!response.ok) {
84
    throw new Error(`${response.status} ${await response.text()}`)
85
  }
86
  return await response.json()
87
}
88