This is an automated email from the ASF dual-hosted git repository.

ocket8888 pushed a commit to branch master
in repository 
https://gitbox.apache.org/repos/asf/trafficcontrol-trafficops-types.git

commit cab0353fc63a7fe23a93d5ae62b99bf6e7826922
Author: ocket8888 <[email protected]>
AuthorDate: Sat Apr 23 01:44:14 2022 -0600

    Add the first batch of source files
    
    (copied in from TPv2/the docs overview pages/"API Next" document)
---
 src/about.ts             |  17 ++
 src/acme.ts              |  10 +
 src/alert.ts             |  30 ++
 src/cache.group.ts       | 157 ++++++++++
 src/cdn.ts               |  25 ++
 src/delivery.service.ts  | 756 +++++++++++++++++++++++++++++++++++++++++++++++
 src/division.ts          |  40 +++
 src/index.ts             |  75 +++++
 src/invalidation.ts      |  65 ++++
 src/iso.ts               |  44 +++
 src/login.ts             |  47 +++
 src/logs.ts              |  66 +++++
 src/parameter.ts         |  36 +++
 src/physical.location.ts |  86 ++++++
 src/plugin.ts            |  10 +
 src/profile.ts           |  96 ++++++
 src/server.ts            | 301 +++++++++++++++++++
 src/stats.ts             |  67 +++++
 src/status.ts            |  25 ++
 src/type.ts              |  29 ++
 src/user.ts              | 232 +++++++++++++++
 src/vault.ts             |  19 ++
 22 files changed, 2233 insertions(+)

diff --git a/src/about.ts b/src/about.ts
new file mode 100644
index 0000000..b7c4e1e
--- /dev/null
+++ b/src/about.ts
@@ -0,0 +1,17 @@
+/** Represents the response to a request made to the /about API endpoint. */
+export interface About {
+       commitHash?: string;
+       commits?: string;
+       goVersion?: string;
+       name?: string;
+       release: string;
+       /* eslint-disable @typescript-eslint/naming-convention */
+       RPMVersion?: string;
+       Version?: string;
+       /* eslint-enable @typescript-eslint/naming-convention */
+}
+
+/** SystemInfo represents a response from /system/info. */
+export interface SystemInfo {
+       [parameter: string]: string;
+}
diff --git a/src/acme.ts b/src/acme.ts
new file mode 100644
index 0000000..c86ffa9
--- /dev/null
+++ b/src/acme.ts
@@ -0,0 +1,10 @@
+/**
+ * ACMEAccount represents an ACME account as required by and given in requests
+ * to and responses from /acme_accounts.
+ */
+export interface ACMEAccount {
+       email: string;
+       privateKey: string;
+       provider: string;
+       uri: string;
+}
diff --git a/src/alert.ts b/src/alert.ts
new file mode 100644
index 0000000..943b266
--- /dev/null
+++ b/src/alert.ts
@@ -0,0 +1,30 @@
+/** The allowed/known "level"s of Traffic Ops API Alerts. */
+export const enum AlertLevel {
+       /** An error occurred, and the request could not be fulfilled. */
+       ERROR = "error",
+       /** Informative alert, not indicative of success or failure. */
+       INFO = "info",
+       /** The request succeeded, and the Alert text describes the action 
taken. */
+       SUCCESS = "success",
+       /** The request may have succeeded, but the user should be aware of 
something. */
+       WARNING = "warning"
+}
+
+/**
+ * An Alert is some human-readable notification sent back from the Traffic Ops
+ * API for the user, in addition to a response object where applicable.
+ */
+export interface Alert {
+       level: AlertLevel;
+       text: string;
+}
+
+/**
+ * Gets the text of any and all error-level Alerts.
+ *
+ * @param as Alerts to check for errors.
+ * @returns The `text` of each error-level Alert found in `as`.
+ */
+export function errors(as: Array<Alert>): Array<string> {
+       return as.filter(a=>a.level===AlertLevel.ERROR).map(a=>a.text);
+}
diff --git a/src/cache.group.ts b/src/cache.group.ts
new file mode 100644
index 0000000..a121c60
--- /dev/null
+++ b/src/cache.group.ts
@@ -0,0 +1,157 @@
+/** Represents an ASN in an API response. */
+export interface ResponseASN {
+       asn: number;
+       cachegroup: string;
+       cachegroupId: number;
+       readonly id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+}
+
+/** Represents an ASN in an API request. */
+export interface RequestASN {
+       asn: number;
+       cachegroupId: number;
+}
+
+/** Represents, generically, an ASN in the context of a request or response. */
+export type ASN = RequestASN | ResponseASN;
+
+/**
+ * LocalizationMethod values are those allowed in the 'localizationMethods' of
+ * `CacheGroup`s.
+ */
+export const enum LocalizationMethod {
+       /** Coverage Zone file lookup. */
+       CZ = "CZ",
+       /** Deep Coverage Zone file lookup. */
+       DEEP_CZ = "DEEP_CZ",
+       /** Geographic database search. */
+       GEO = "GEO"
+}
+
+/**
+ * Converts a LocalizationMethod to a human-readable string.
+ *
+ * @param l The LocalizationMethod to convert.
+ * @returns A textual representation of 'l'.
+ */
+export function localizationMethodToString(l: LocalizationMethod): string {
+       switch (l) {
+               case LocalizationMethod.CZ:
+                       return "Coverage Zone File";
+               case LocalizationMethod.DEEP_CZ:
+                       return "Deep Coverage Zone File";
+               case LocalizationMethod.GEO:
+                       return "Geo-IP Database";
+       }
+}
+
+/**
+ * Represents a Cache Group as required by the Traffic Ops API in requests.
+ */
+export interface RequestCacheGroup {
+       fallbacks?: Array<string> | null;
+       fallbackToClosest?: boolean | null;
+       /**
+        * Note that leaving latitude and longitude null or undefined **will 
break
+        * things**.
+        *
+        * See https://github.com/apache/trafficcontrol/issues/6378
+        */
+       latitude?: number | null;
+       localizationMethods?: Array<LocalizationMethod> | null;
+       /**
+        * Note that leaving latitude and longitude null or undefined **will 
break
+        * things**.
+        *
+        * See https://github.com/apache/trafficcontrol/issues/6378
+        */
+       longitude?: number | null;
+       name: string;
+       parentCacheGroupId?: number | null;
+       secondaryParentId?: number | null;
+       shortName: string;
+       typeId: number;
+}
+
+/**
+ * The basic properties common to Cache Groups in all responses.
+ */
+interface ResponseCacheGroupBase {
+       fallbacks: Array<string>;
+       fallbackToClosest: boolean;
+       readonly id: number;
+       lastUpdated: Date;
+       latitude: number | null;
+       localizationMethods: Array<LocalizationMethod>;
+       longitude: number | null;
+       name: string;
+       shortName: string;
+       typeId: number;
+       typeName: string;
+}
+
+/**
+ * A Cache Group with a parent. All related fields are guaranteed to be
+ * non-null.
+ */
+interface ResponseCacheGroupWithParent extends ResponseCacheGroupBase {
+       parentCacheGroupId: number;
+       parentCacheGroupName: string;
+}
+
+/**
+ * A Cache Group with no parent. All related fields are guaranteed to be null.
+ */
+interface ResponseCacheGroupWithoutParent extends ResponseCacheGroupBase {
+       parentCacheGroupId: null;
+       parentCacheGroupName: null;
+}
+
+/**
+ * A Cache Group with a secondary parent. All related fields are guaranteed to
+ * be non-null.
+ */
+interface ResponseCacheGroupWithSecondaryParent extends ResponseCacheGroupBase 
{
+       secondaryParentId: number;
+       secondaryParentName: string;
+}
+
+/**
+ * A Cache Group without a secondary parent. All related fields are guaranteed
+ * to be null.
+ */
+interface ResponseCacheGroupWithoutSecondaryParent extends 
ResponseCacheGroupBase {
+       secondaryParentId: null;
+       secondaryParentName: null;
+}
+
+/** A Cache Group with a parent but no secondary parent. */
+type ResponseCacheGroupWithParentButNotSecondary = 
ResponseCacheGroupWithParent & ResponseCacheGroupWithoutSecondaryParent;
+/** A Cache Group with both a parent and a secondary parent. */
+type ResponseCacheGroupWithParentAndSecondary = ResponseCacheGroupWithParent & 
ResponseCacheGroupWithSecondaryParent;
+/** A Cache Group with a secondary parent but no parent. */
+type ResponseCacheGroupWithSecondaryButNotParent = 
ResponseCacheGroupWithoutParent & ResponseCacheGroupWithSecondaryParent;
+/** A Cache Group with neither a parent nor a secondary parent. */
+type ResponseCacheGroupWithoutParentOrSecondary = 
ResponseCacheGroupWithoutParent & ResponseCacheGroupWithoutSecondaryParent;
+
+/**
+ * Represents a Cache Group as returned by the Traffic Ops API in responses.
+ */
+export type ResponseCacheGroup = ResponseCacheGroupWithParentButNotSecondary |
+ResponseCacheGroupWithParentAndSecondary |
+ResponseCacheGroupWithSecondaryButNotParent |
+ResponseCacheGroupWithoutParentOrSecondary;
+
+/**
+ * Represents a Cache Group.
+ *
+ * Refer to 
https://traffic-control-cdn.readthedocs.io/en/latest/overview/cache_groups.html
+ */
+export type CacheGroup = RequestCacheGroup | ResponseCacheGroup;
diff --git a/src/cdn.ts b/src/cdn.ts
new file mode 100644
index 0000000..c7d5220
--- /dev/null
+++ b/src/cdn.ts
@@ -0,0 +1,25 @@
+/**
+ * Represents a CDN as required by the Traffic Ops API in requests.
+ */
+export interface RequestCDN {
+       /** Whether or not DNSSEC is enabled within this CDN. */
+       dnssecEnabled: boolean;
+       /** The Top-Level Domain within which the CDN operates. */
+       domainName:    string;
+       /** The name of the CDN. */
+       name:          string;
+}
+
+/**
+ * Represents a CDN as returned by the Traffic Ops API in responses.
+ */
+export interface ResponseCDN {
+       dnssecEnabled: boolean;
+       domainName: string;
+       readonly id: number;
+       lastUpdated: Date;
+       name: string;
+}
+
+/** Represents a CDN. */
+export type CDN = RequestCDN | ResponseCDN;
diff --git a/src/delivery.service.ts b/src/delivery.service.ts
new file mode 100644
index 0000000..7ebd6d0
--- /dev/null
+++ b/src/delivery.service.ts
@@ -0,0 +1,756 @@
+/**
+ * Represents the `geoLimit` field of a Delivery Service
+ */
+export const enum GeoLimit {
+       /**
+        * No geographic limiting is to be done.
+        */
+       NONE = 0,
+       /**
+        * Only clients found in a Coverage Zone File may be permitted access.
+        */
+       CZF_ONLY = 1,
+       /**
+        * Only clients found in a Coverage Zone File OR can be geo-located 
within a
+        * set of country codes may be permitted access.
+        */
+       CZF_AND_COUNTRY_CODES = 2
+}
+
+/**
+ * Defines the supported Geograhic IP mapping database providers and their
+ * respective magic number identifiers.
+ */
+export const enum GeoProvider {
+       /** The standard database used for geo-location. */
+       MAX_MIND = 0,
+       /** An alternative database with dubious support. */
+       NEUSTAR = 1
+}
+
+/**
+ * Represents a single entry in a Delivery Service's `matchList` field.
+ */
+export interface DeliveryServiceMatch {
+       /** A regular expression matching on something depending on the 'type'. 
*/
+       pattern: string;
+       /**
+        * The number in the set of the expression, which has vague but 
incredibly
+        * important meaning.
+        */
+       setNumber: number;
+       /**
+        * The type of match which determines how it's used.
+        */
+       type: string;
+}
+
+/**
+ * Represents the allowed routing protocols and their respective magic number
+ * identifiers.
+ */
+export const enum Protocol {
+       /** Serve HTTP traffic only. */
+       HTTP = 0,
+       /** Serve HTTPS traffic only. */
+       HTTPS = 1,
+       /** Serve both HTTPS and HTTP traffic. */
+       HTTP_AND_HTTPS = 2,
+       /** Redirect HTTP requests to HTTPS URLs and serve HTTPS traffic 
normally. */
+       HTTP_TO_HTTPS = 3
+}
+
+/**
+ * Converts Protocols to a textual representation.
+ *
+ * @param p The Protocol to convert.
+ * @returns A string representation of 'p', or 'UNKNOWN' if 'p' was 
unrecognized.
+ */
+export function protocolToString(p: Protocol): string {
+       switch (p) {
+               case Protocol.HTTP:
+                       return "Serve only unsecured HTTP requests";
+               case Protocol.HTTPS:
+                       return "Serve only secured HTTPS requests";
+               case Protocol.HTTP_AND_HTTPS:
+                       return "Serve both unsecured HTTP requests and secured 
HTTPS requests";
+               case Protocol.HTTP_TO_HTTPS:
+                       return "Serve secured HTTPS requests normally, but 
redirect unsecured HTTP requests to use HTTPS";
+       }
+}
+
+/**
+ * Represents the allowed values of the `qstringIgnore` field of a
+ * `DeliveryService`.
+ */
+export const enum QStringHandling {
+       /** Use the query string in the cache key and pass in upstream 
requests. */
+       USE = 0,
+       /**
+        * Don't use the query string in the cache key but do pass it in 
upstream
+        * requests.
+        */
+       IGNORE = 1,
+       /**
+        * Neither use the query string in the cache key nor pass it in upstream
+        * requests.
+        */
+       DROP = 2
+}
+
+/**
+ * Converts a QStringHandling to a textual representation.
+ *
+ * @param q The QStringHandling to convert.
+ * @returns A string representation of 'q'.
+ */
+export function qStringHandlingToString(q: QStringHandling): string {
+       switch (q) {
+               case QStringHandling.USE:
+                       return "Use the query parameter string when deciding if 
a URL is cached, and pass it in upstream requests to the" +
+                               " Mid-tier/origin";
+               case QStringHandling.IGNORE:
+                       return "Do not use the query parameter string when 
deciding if a URL is cached, but do pass it in upstream requests to the" +
+                               " Mid-tier/origin";
+               case QStringHandling.DROP:
+                       return "Immediately strip URLs of their query parameter 
strings before checking cached objects or making upstream requests";
+       }
+}
+
+/**
+ * Represents the allowed values of the `rangeRequestHandling` field of a
+ * `Delivery Service`.
+ */
+export const enum RangeRequestHandling {
+       /** Range requests will not be cached. */
+       NONE = 0,
+       /**
+        * The entire object will be fetched in the background to be cached, 
with
+        * the requested range served when it becomes available.
+        */
+       BACKGROUND_FETCH = 1,
+       /**
+        * Cache range requests like any other request.
+        */
+       CACHE_RANGE_REQUESTS = 2
+}
+
+/**
+ * Converts a RangeRequestHandling to a textual representation.
+ *
+ * @param r The RangeRequestHandling to convert.
+ * @returns A string representation of 'r'.
+ */
+export function rangeRequestHandlingToString(r: RangeRequestHandling): string {
+       switch (r) {
+               case RangeRequestHandling.NONE:
+                       return "Do not cache Range requests";
+               case RangeRequestHandling.BACKGROUND_FETCH:
+                       return "Use the background_fetch plugin to serve Range 
requests while quietly caching the entire object";
+               case RangeRequestHandling.CACHE_RANGE_REQUESTS:
+                       return "Use the cache_range_requests plugin to directly 
cache object ranges";
+       }
+}
+
+/**
+ * The basic set of Delivery Service properties without being more specific as
+ * to the routing type, as they are given in requests.
+ */
+interface RequestDeliveryServiceBase {
+       /** Whether or not the Delivery Service is actively routed. */
+       active: boolean;
+       /** Whether or not anonymization services are blocked. */
+       anonymousBlockingEnabled?: number | null;
+       /**
+        * @deprecated This field no longer works and is subject to removal in 
the
+        * future.
+        */
+       cacheurl: string | null;
+       /** The TTL of DNS responses from the Traffic Router, in seconds. */
+       ccrDnsTtl?: number | null;
+       /** The ID of the CDN to which the Delivery Service belongs. */
+       cdnId: number;
+       /** A sample path which may be requested to ensure the origin is 
working. */
+       checkPath?: string | null;
+       /**
+        * A set of the query parameters that are important for Traffic Router 
to
+        * consider when performing "consistent hashing".
+        */
+       consistentHashQueryParams?: Array<string> | null;
+       /**
+        * A regular expression used to extract request path fragments for use 
as
+        * keys in "consistent hashing" for routing purposes.
+        */
+       consistentHashRegex?: string | null;
+       /** Whether or not to use "deep caching". */
+       deepCachingType?: "ALWAYS" | "NEVER" | null;
+       /** A human-friendly name for the Delivery Service. */
+       displayName: string;
+       /** An FQDN to use for DNS-routed bypass scenarios. */
+       dnsBypassCname?: string | null;
+       /** An IPv4 address to use for DNS-routed bypass scenarios. */
+       dnsBypassIp?: string | null;
+       /** An IPv6 address to use for DNS-routed bypass scenarios. */
+       dnsBypassIp6?: string | null;
+       /** The TTL of DNS responses served in bypass scenarios. */
+       dnsBypassTtl?: string | null;
+       /** The Delivery Service's DSCP. */
+       dscp: number;
+       ecsEnabled?: boolean | null;
+       /** Extra header rewrite text used at the Edge tier. */
+       edgeHeaderRewrite?: string | null;
+       firstHeaderRewrite?: string | null;
+       fqPacingRate?: number | null;
+       /**
+        * Describes limitation of content availability based on geographic
+        * location.
+        */
+       geoLimit: GeoLimit;
+       /**
+        * The countries from which content access is allowed in the event that
+        * geographic limiting is taking place with a setting that allows for
+        * specific country codes to access content.
+        */
+       geoLimitCountries?: string | null;
+       /**
+        * A URL to which to re-direct users who are blocked because of
+        * geographic-based access limiting
+        */
+       geoLimitRedirectUrl?: string | null;
+       /**
+        * The provider of the IP-address-to-geographic-location database.
+        */
+       geoProvider: GeoProvider;
+       /**
+        * The globally allowed maximum megabits per second to be served for the
+        * Delivery Service.
+        */
+       globalMaxMbps?: number | null;
+       /**
+        * The globally allowed maximum transactions per second to be served 
for the
+        * Delivery Service.
+        */
+       globalMaxTps?: number | null;
+       /** A URL to be used in HTTP-routed bypass scenarios. */
+       httpBypassFqdn: string | null;
+       /**
+        * A URL from which information about a Delivery Service may be 
obtained.
+        * Historically, this has been used to link to the support ticket that
+        * requested the Delivery Service's creation.
+        */
+       infoUrl: string | null;
+       /** The number of caches across which to spread content. */
+       initialDispersion?: number | null;
+       innerHeaderRewrite?: string | null;
+       /** Whether or not routing of IPv6 clients should be supported. */
+       ipv6RoutingEnabled?: boolean | null;
+       lastHeaderRewrite?: string | null;
+       /** Whether or not logging should be enabled for the Delivery Service. 
*/
+       logsEnabled: boolean;
+       /** A textual description of arbitrary length. */
+       longDesc?: string | null;
+       /**
+        * A textual description of arbitrary length.
+        *
+        * @deprecated This has been removed in the latest API version.
+        */
+       longDesc1?: string | null;
+       /**
+        * A textual description of arbitrary length.
+        *
+        * @deprecated This has been removed in the latest API version.
+        */
+       longDesc2?: string | null;
+       /**
+        * Sets the maximum number of answers Traffic Router may provide in a 
single
+        * DNS response for this Delivery Service.
+        */
+       maxDnsAnswers?: number | null;
+       /**
+        * The maximum number of connections that cache servers are allowed to 
open
+        * to the Origin(s).
+        *
+        * @default 0
+        */
+       maxOriginConnections?: number | null;
+       /**
+        * The maximum size (in bytes) of the request header that is allowed for
+        * this Delivery Service.
+        *
+        * @since 3.1
+        * @default 0
+        */
+       maxRequestHeaderBytes?: number | null;
+       /** Extra header rewrite text to be used at the Mid-tier. */
+       midHeaderRewrite?: string | null;
+       /** The latitude that should be used when geo-location of a client 
fails. */
+       missLat?: number | null;
+       /** The longitude that should be used when geo-location of a client 
fails.*/
+       missLong?: number | null;
+       /** Whether or not Multi-Site Origin is in use. */
+       multiSiteOrigin?: boolean | null;
+       /** The URL of the Origin server, which I think means nothing for MSO. 
*/
+       orgServerFqdn?: string | null;
+       /** A string used to shield the Origin, somehow. */
+       originShield?: string | null;
+       /**
+        * An integral, unique identifer for the Profile used by the Delivery
+        * Service.
+        */
+       profileId?: number | null;
+       /** The protocols served by the Delivery Service. */
+       protocol?: Protocol | null;
+       /**
+        * How query strings ought to be handled by cache servers serving 
content
+        * for this Delivery Service.
+        */
+       qstringIgnore?: QStringHandling | null;
+       /**
+        * How HTTP Range requests ought to be handled by cache servers serving
+        * content for this Delivery Service.
+        */
+       rangeRequestHandling?: RangeRequestHandling | null;
+       rangeSliceBlockSize?: null | number;
+       /** Some raw text to be inserted into regex_remap.config. */
+       regexRemap?: string | null;
+       /** Whether or not regional geo-blocking should be used. */
+       regionalGeoBlocking: boolean;
+       /** Some raw text to be inserted into remap.config. */
+       remapText: string | null;
+       /**
+        * The lowest-level DNS label used in URLs for the Delivery Service.
+        *
+        * @default "cdn"
+        */
+       routingName?: string | null;
+       serviceCategory?: string | null;
+       /**
+        * Whether or not responses from the cache servers for this Delivery
+        * Service's content will be signed.
+        */
+       signed?: boolean | null;
+       /**
+        * The algorithm used to sign responses from the cache servers for this
+        * Delivery Service's content.
+        */
+       signingAlgorithm?: "url_sig" | "uri_signing" | null;
+       /** The generation of SSL key used by this Delivery Service. */
+       sslKeyVersion?: number | null;
+       /**
+        * An integral, unique identifier for the Tenant to whom this Delivery
+        * Service belongs.
+        */
+       tenantId: number;
+       topology?: string | null;
+       /**
+        * HTTP headers that should be logged from client requests by Traffic
+        * Router.
+        */
+       trRequestHeaders?: string | null;
+       /** Extra HTTP headers that Traffic Router should provide in responses. 
*/
+       trResponseHeaders?: string | null;
+       /** The integral, unique identifier of the type of the Delivery 
Service. */
+       typeId: number;
+       /** The second-lowest-level DNS label used in the Delivery Service's 
URLs.*/
+       xmlId: string;
+}
+
+/**
+ * Represents an HTTP-type Delivery Service in the context of a request.
+ *
+ * Note that since Type is utterly determined by `typeId`, it's not possible to
+ * know without communicating with the server in some way whether or not any
+ * given object is actually HTTP-typed.
+ */
+export interface RequestHTTPDeliveryService extends RequestDeliveryServiceBase 
{
+       /** The number of caches across which to spread content. */
+       initialDispersion: number;
+       /** Whether or not routing of IPv6 clients should be supported. */
+       ipv6RoutingEnabled: boolean;
+       /** The latitude that should be used when geo-location of a client 
fails. */
+       missLat: number;
+       /** The longitude that should be used when geo-location of a client 
fails.*/
+       missLong: number;
+       /** Whether or not Multi-Site Origin is in use. */
+       multiSiteOrigin: boolean;
+       /** The URL of the Origin server, which I think means nothing for MSO. 
*/
+       orgServerFqdn: string;
+       /** The protocols served by the Delivery Service. */
+       protocol: Protocol;
+       /**
+        * How query strings ought to be handled by cache servers serving 
content
+        * for this Delivery Service.
+        */
+       qstringIgnore: QStringHandling;
+       /**
+        * How HTTP Range requests ought to be handled by cache servers serving
+        * content for this Delivery Service.
+        */
+       rangeRequestHandling: RangeRequestHandling;
+}
+
+/**
+ * Represents a DNS-type Delivery Service in the context of a request.
+ *
+ * Note that since Type is utterly determined by `typeId`, it's not possible to
+ * know without communicating with the server in some way whether or not any
+ * given object is actually DNS-typed.
+ */
+export interface RequestDNSDeliveryService extends RequestDeliveryServiceBase {
+       /** Whether or not routing of IPv6 clients should be supported. */
+       ipv6RoutingEnabled: boolean;
+       /** The latitude that should be used when geo-location of a client 
fails. */
+       missLat: number;
+       /** The longitude that should be used when geo-location of a client 
fails.*/
+       missLong: number;
+       /** Whether or not Multi-Site Origin is in use. */
+       multiSiteOrigin: boolean;
+       /** The URL of the Origin server, which I think means nothing for MSO. 
*/
+       orgServerFqdn: string;
+       /** The protocols served by the Delivery Service. */
+       protocol: Protocol;
+       /**
+        * How query strings ought to be handled by cache servers serving 
content
+        * for this Delivery Service.
+        */
+       qstringIgnore: QStringHandling;
+       /**
+        * How HTTP Range requests ought to be handled by cache servers serving
+        * content for this Delivery Service.
+        */
+       rangeRequestHandling: RangeRequestHandling;
+}
+
+/**
+ * Represents a STEERING-type Delivery Service in the context of a request.
+ *
+ * Note that since Type is utterly determined by `typeId`, it's not possible to
+ * know without communicating with the server in some way whether or not any
+ * given object is actually STEERING-typed.
+ */
+export type RequestSteeringDeliveryService = RequestDeliveryServiceBase;
+
+/**
+ * Represents an ANY_MAP-type Delivery Service in the context of a request.
+ *
+ * Note that since Type is utterly determined by `typeId`, it's not possible to
+ * know without communicating with the server in some way whether or not any
+ * given object is actually ANY_MAP-typed.
+ */
+export type RequestAnyMapDeliveryService = RequestDeliveryServiceBase;
+
+/**
+ * Represents a Delivery Service as required by the Traffic Ops API in 
requests.
+ */
+export type RequestDeliveryService = RequestHTTPDeliveryService | 
RequestDNSDeliveryService | RequestSteeringDeliveryService | 
RequestAnyMapDeliveryService;
+
+/**
+ * The basic set of Delivery Service properties without being more specific as
+ * to the routing type, as they are found in responses.
+ */
+interface ResponseDeliveryServiceBase {
+       /** Whether or not the Delivery Service is actively routed. */
+       active: boolean;
+       /** Whether or not anonymization services are blocked. */
+       anonymousBlockingEnabled: boolean;
+       /**
+        * @deprecated This field no longer works and is subject to removal in 
the
+        * future.
+        */
+       cacheurl: string | null;
+       /** The TTL of DNS responses from the Traffic Router, in seconds. */
+       ccrDnsTtl: number | null;
+       /** The ID of the CDN to which the Delivery Service belongs. */
+       cdnId: number;
+       /**
+        * The Name of the CDN to which the Delivery Service belongs.
+        *
+        * This is null in response to PUT or POST requests where it was null or
+        * unspecified in the response.
+        */
+       cdnName: string | null;
+       /** A sample path which may be requested to ensure the origin is 
working. */
+       checkPath: string | null;
+       /**
+        * A set of the query parameters that are important for Traffic Router 
to
+        * consider when performing "consistent hashing".
+        */
+       consistentHashQueryParams: null | [string, ...Array<string>];
+       /**
+        * A regular expression used to extract request path fragments for use 
as
+        * keys in "consistent hashing" for routing purposes.
+        */
+       consistentHashRegex: string | null;
+       /** Whether or not to use "deep caching". */
+       deepCachingType: "ALWAYS" | "NEVER";
+       /** A human-friendly name for the Delivery Service. */
+       displayName: string;
+       /** An FQDN to use for DNS-routed bypass scenarios. */
+       dnsBypassCname: string | null;
+       /** An IPv4 address to use for DNS-routed bypass scenarios. */
+       dnsBypassIp: string | null;
+       /** An IPv6 address to use for DNS-routed bypass scenarios. */
+       dnsBypassIp6: string | null;
+       /** The TTL of DNS responses served in bypass scenarios. */
+       dnsBypassTtl: number | null;
+       /** The Delivery Service's DSCP. */
+       dscp: number;
+       ecsEnabled: boolean;
+       /** Extra header rewrite text used at the Edge tier. */
+       edgeHeaderRewrite: string | null;
+       /**
+        * A list of the URLs which may be used to request Delivery Service 
content.
+        *
+        * These are generated on-the-fly by Traffic Ops based on the structure 
of
+        * the given Delivery Service - as such, they cannot be directly 
modified.
+        */
+       readonly exampleURLs: readonly string[];
+       firstHeaderRewrite: string | null;
+       fqPacingRate: number;
+       /**
+        * Describes limitation of content availability based on geographic
+        * location.
+        */
+       geoLimit: GeoLimit;
+       /**
+        * The countries from which content access is allowed in the event that
+        * geographic limiting is taking place with a setting that allows for
+        * specific country codes to access content.
+        */
+       geoLimitCountries: string | null;
+       /**
+        * A URL to which to re-direct users who are blocked because of
+        * geographic-based access limiting
+        */
+       geoLimitRedirectURL: string | null;
+       /**
+        * The provider of the IP-address-to-geographic-location database.
+        */
+       geoProvider: GeoProvider;
+       /**
+        * The globally allowed maximum megabits per second to be served for the
+        * Delivery Service.
+        */
+       globalMaxMbps: number | null;
+       /**
+        * The globally allowed maximum transactions per second to be served 
for the
+        * Delivery Service.
+        */
+       globalMaxTps: number | null;
+       /** A URL to be used in HTTP-routed bypass scenarios. */
+       httpBypassFqdn: string | null;
+       /** An integral, unique identifier for the Delivery Service. */
+       readonly id: number;
+       /**
+        * A URL from which information about a Delivery Service may be 
obtained.
+        * Historically, this has been used to link to the support ticket that
+        * requested the Delivery Service's creation.
+        */
+       infoUrl: string | null;
+       /** The number of caches across which to spread content. */
+       initialDispersion: number;
+       innerHeaderRewrite: string | null;
+       /** Whether or not routing of IPv6 clients should be supported. */
+       ipv6RoutingEnabled: boolean;
+       lastHeaderRewrite: string | null;
+       /** When the Delivery Service was last updated via the API. */
+       lastUpdated: Date;
+       /** Whether or not logging should be enabled for the Delivery Service. 
*/
+       logsEnabled: boolean;
+       /** A textual description of arbitrary length. */
+       longDesc: string | null;
+       /**
+        * A textual description of arbitrary length.
+        *
+        * @deprecated This has been removed in the latest API version.
+        */
+       longDesc1?: string;
+       /**
+        * A textual description of arbitrary length.
+        *
+        * @deprecated This has been removed in the latest API version.
+        */
+       longDesc2?: string;
+       /**
+        * A list of regular expressions for routing purposes which should not 
ever
+        * be modified by hand.
+        */
+       matchList: Array<DeliveryServiceMatch>;
+       /**
+        * Sets the maximum number of answers Traffic Router may provide in a 
single
+        * DNS response for this Delivery Service.
+        */
+       maxDnsAnswers: number | null;
+       /**
+        * The maximum number of connections that cache servers are allowed to 
open
+        * to the Origin(s).
+        */
+       maxOriginConnections: number;
+       /**
+        * The maximum size (in bytes) of the request header that is allowed for
+        * this Delivery Service.
+        *
+        * @since 3.1
+        */
+       maxRequestHeaderBytes: number;
+       /** Extra header rewrite text to be used at the Mid-tier. */
+       midHeaderRewrite: string | null;
+       /** The latitude that should be used when geo-location of a client 
fails. */
+       missLat: number;
+       /** The longitude that should be used when geo-location of a client 
fails.*/
+       missLong: number;
+       /** Whether or not Multi-Site Origin is in use. */
+       multiSiteOrigin: boolean;
+       /** A string used to shield the Origin, somehow. */
+       originShield: string | null;
+       /** The URL of the Origin server, which I think means nothing for MSO. 
*/
+       orgServerFqdn: string;
+       /** The protocols served by the Delivery Service. */
+       protocol: Protocol;
+       /**
+        * How query strings ought to be handled by cache servers serving 
content
+        * for this Delivery Service.
+        */
+       qstringIgnore: QStringHandling;
+       /**
+        * How HTTP Range requests ought to be handled by cache servers serving
+        * content for this Delivery Service.
+        */
+       rangeRequestHandling: RangeRequestHandling;
+       rangeSliceBlockSize: null | number;
+       /** Some raw text to be inserted into regex_remap.config. */
+       regexRemap: string | null;
+       /** Whether or not regional geo-blocking should be used. */
+       regionalGeoBlocking: boolean;
+       /** Some raw text to be inserted into remap.config. */
+       remapText: string | null;
+       /** The lowest-level DNS label used in URLs for the Delivery Service. */
+       routingName: string;
+       serviceCategory: string | null;
+       /**
+        * Whether or not responses from the cache servers for this Delivery
+        * Service's content will be signed.
+        */
+       signed: boolean;
+       /**
+        * The algorithm used to sign responses from the cache servers for this
+        * Delivery Service's content.
+        */
+       signingAlgorithm: "url_sig" | "uri_signing";
+       /** The generation of SSL key used by this Delivery Service. */
+       sslKeyVersion: number | null;
+       /** The name of the Tenant to whom this Delivery Service belongs. */
+       tenant: string;
+       /**
+        * An integral, unique identifier for the Tenant to whom this Delivery
+        * Service belongs.
+        */
+       tenantId: number;
+       topology: string | null;
+       /** Extra HTTP headers that Traffic Router should provide in responses. 
*/
+       trResponseHeaders: string | null;
+       /**
+        * HTTP headers that should be logged from client requests by Traffic
+        * Router.
+        */
+       trRequestHeaders: string | null;
+       /** The type of the Delivery Service. */
+       type: string;
+       /** The integral, unique identifier of the type of the Delivery 
Service. */
+       typeId: number;
+       /** The second-lowest-level DNS label used in the Delivery Service's 
URLs.*/
+       xmlId: string;
+}
+
+/**
+ * A Delivery Service with a Profile. If a Delivery Service has a Profile, all
+ * of the related properties are guaranteed to be non-null in responses.
+ */
+interface ResponseDeliveryServiceWithProfile extends 
ResponseDeliveryServiceBase {
+       /** A description of the Profile used by the Delivery Service 
(read-only) */
+       profileDescription: string;
+       /**
+        * An integral, unique identifer for the Profile used by the Delivery
+        * Service.
+        */
+       profileId: number;
+       /** The name of the Profile used by the Delivery Service. */
+       profileName: string;
+}
+
+/**
+ * A Delivery Service with a Profile. If a Delivery Service does not has a
+ * Profile, all of the related properties are guaranteed to be null in
+ * responses.
+ */
+interface ResponseDeliveryServiceWithoutProfile extends 
ResponseDeliveryServiceBase {
+       /** A description of the Profile used by the Delivery Service 
(read-only) */
+       profileDescription: null;
+       /**
+        * An integral, unique identifer for the Profile used by the Delivery
+        * Service.
+        */
+       profileId: null;
+       /** The name of the Profile used by the Delivery Service. */
+       profileName: null;
+}
+
+/**
+ * Represents a Delivery Service as returned by the Traffic Ops API in
+ * responses.
+ */
+export type ResponseDeliveryService = ResponseDeliveryServiceWithProfile | 
ResponseDeliveryServiceWithoutProfile;
+
+/**
+ * Represents a Delivery Service.
+ */
+export type DeliveryService = RequestDeliveryService | ResponseDeliveryService;
+
+/**
+ * Determines if the Delivery Service is a candidate for bypassing.
+ *
+ * @param ds The Delivery Service to check.
+ * @returns `true` if it can have bypass settings, `false` otherwise.
+ */
+export function bypassable(ds: DeliveryService): boolean {
+       if (!Object.prototype.hasOwnProperty.call(ds, "type")) {
+               return false;
+       }
+
+       switch ((ds as ResponseDeliveryService).type) {
+               case "HTTP":
+               case "HTTP_LIVE":
+               case "HTTP_LIVE_NATNL":
+               case "DNS":
+               case "DNS_LIVE":
+               case "DNS_LIVE_NATNL":
+                       return true;
+               default:
+                       return false;
+       }
+}
+
+/**
+ * DSCapacity represents a response from the API to a request for the capacity
+ * of a Delivery Service.
+ */
+export interface DSCapacity {
+       availablePercent: number;
+       maintenancePercent: number;
+       unavailablePercent: number;
+       utilizedPercent: number;
+}
+
+/**
+ * DSHealth represents a response from the API to a request for the health of a
+ * Delivery Service.
+ */
+export interface DSHealth {
+       cachegroups: Array<{
+               name: string;
+               offline: number;
+               online: number;
+       }>;
+       totalOnline: number;
+       totalOffline: number;
+}
diff --git a/src/division.ts b/src/division.ts
new file mode 100644
index 0000000..cdc25e0
--- /dev/null
+++ b/src/division.ts
@@ -0,0 +1,40 @@
+/**
+ * Represents a Division as required by the Traffic Ops API in requests.
+ */
+export interface RequestDivision {
+       name: string;
+}
+
+/**
+ * Represents a Division as returned by the Traffic Ops API in responses.
+ */
+export interface ResponseDivision {
+       readonly id: number;
+       lastUpdated: Date;
+       name: string;
+}
+
+/** Representns a Division. */
+export type Division = RequestDivision | ResponseDivision;
+
+/**
+ * Represents a Region as required by the Traffic Ops API in requests.
+ */
+export interface RequestRegion {
+       division: number;
+       name: string;
+}
+
+/**
+ * Represents a Region as returned by the Traffic Ops API in responses.
+ */
+export interface ResponseRegion {
+       division: number;
+       divisionName: string;
+       readonly id: number;
+       lastUpdated: Date;
+       name: string;
+}
+
+/** Represents a Region. */
+export type Region = RequestRegion | ResponseRegion;
diff --git a/src/index.ts b/src/index.ts
new file mode 100644
index 0000000..c1edef1
--- /dev/null
+++ b/src/index.ts
@@ -0,0 +1,75 @@
+export * from "./about";
+export * from "./acme";
+export * from "./alert";
+export * from "./cache.group";
+export * from "./cdn";
+export * from "./delivery.service";
+export * from "./division";
+export * from "./invalidation";
+export * from "./iso";
+export * from "./login";
+export * from "./logs";
+export * from "./parameter";
+export * from "./physical.location";
+export * from "./plugin";
+export * from "./profile";
+export * from "./server";
+export * from "./stats";
+export * from "./status";
+export * from "./type";
+export * from "./user";
+export * from "./vault";
+
+import type { Alert } from "./alert";
+
+/**
+ * Represents a version of the Traffic Ops API for which this library was made.
+ */
+interface VersionType  {
+       /** The major API version number. */
+       readonly major: number;
+       /** The minor API version number. */
+       readonly minor: number;
+       toString(): string;
+       /**
+        * Whether the API version is unstable. This will be `false` until the 
API
+        * has been included in a release in which it was not labelled as
+        * "unstable".
+        */
+       readonly unstable: boolean;
+}
+
+/**
+ * The version of the Traffic Ops API for which this library was made.
+ *
+ * In general, this is roughly the same as the library package version. 
However,
+ * the Traffic Ops API does not include patch-level numbering - which is good,
+ * because it allows this package to use those for bugfixes.
+ */
+export const VERSION: VersionType = {
+       major: 3,
+       minor: 1,
+       toString() {
+               return `${this.major}.${this.minor}`;
+       },
+       unstable: false
+};
+
+/**
+ * (Nearly) All responses from the Traffic Ops API conform to this interface.
+ */
+export interface APIResponse<T> {
+       alerts?: Array<Alert>;
+       response: T;
+       summary?: {
+               count: number;
+       };
+}
+
+/**
+ * Represents a response from /ping - the *entire* response, as it isn't an
+ * APIResponse.
+ */
+export interface PingResponse {
+       ping: "pong";
+}
diff --git a/src/invalidation.ts b/src/invalidation.ts
new file mode 100644
index 0000000..80b05f0
--- /dev/null
+++ b/src/invalidation.ts
@@ -0,0 +1,65 @@
+/** JobType enumerates the valid types of Job. */
+export const enum JobType {
+       /** Content Invalidation Request. */
+       PURGE = "PURGE"
+}
+
+/**
+ * InvalidationJob objects represent periods of time over which specific 
objects
+ * may not be cached.
+ */
+export interface ResponseInvalidationJob {
+       /**
+        * A regular expression that matches content to be "invalidated" or
+        * "revalidated".
+        */
+       assetURL: string;
+       /**
+        * The name of the user that created the Job.
+        */
+       createdBy: string;
+       /** The XMLID of the Delivery Service within which the Job will 
operate. */
+       deliveryService: string;
+       /** An integral, unique identifier for this Job. */
+       readonly id: number;
+       /** The type of Job. */
+       keyword: JobType;
+       /**
+        * though not enforced by the API (or database), this should ALWAYS 
have the
+        * format 'TTL:nh', describing the job's TTL in hours (`n` can be any
+        * integer value > 0).
+        */
+       parameters: string;
+       /**
+        * The time at which the Job is scheduled to start.
+        */
+       startTime: Date;
+}
+
+/**
+ * A NewInvalidationJob is the data structure used to request creation of a new
+ * content invalidation job through the API.
+ */
+export interface RequestInvalidationJob {
+       /**
+        * This may be either the ID or the XMLID of the Delivery Service to 
which
+        * the Job will apply.
+        */
+       deliveryService: number | string;
+       /**
+        * The effective starting date/time for the Job.
+        */
+       startTime: Date | string;
+       /**
+        * A pattern that matches content to be invalidated.
+        */
+       regex: string;
+       /**
+        * Either the number of hours or a "duration string" describing for how
+        * long the Job will remain in effect.
+        */
+       ttl: number | string;
+}
+
+/** Represents a content invalidation job. */
+export type InvalidationJob = RequestInvalidationJob | ResponseInvalidationJob;
diff --git a/src/iso.ts b/src/iso.ts
new file mode 100644
index 0000000..fb17d39
--- /dev/null
+++ b/src/iso.ts
@@ -0,0 +1,44 @@
+/** The basic fields common to all ISO request bodies. */
+interface ISOFields {
+       disk: string;
+       domainName: string;
+       hostName: string;
+       interfaceMtu: number;
+       interfaceName?: string | null;
+       ip6Address?: string | null;
+       ip6Gateway?: string | null;
+       osVersionsDir: string;
+       rootPass: string;
+}
+
+/**
+ * An ISO generation request. If DHCP isn't used, network information must be
+ * manually supplied.
+ */
+interface ISORequestDHCP extends ISOFields {
+       dhcp: "no";
+       ipAddress: string;
+       ipGateway: string;
+       ipNetmask: string;
+}
+
+/**
+ * An ISO generation request. If DHCP is used, network inforation need not be
+ * supplied.
+ */
+interface ISORequestNonDHCP extends ISOFields {
+       dhcp: "yes";
+}
+
+/**
+ * Represents a request to the `/isos` endpoint of the Traffic Ops API.
+ */
+export type ISORequest = ISORequestDHCP | ISORequestNonDHCP;
+
+/**
+ * Represents a response from the Traffic Ops API to a request made to its
+ * `/osversions` endpoint.
+ */
+export interface OSVersions {
+       [osversion: string]: string;
+}
diff --git a/src/login.ts b/src/login.ts
new file mode 100644
index 0000000..3483865
--- /dev/null
+++ b/src/login.ts
@@ -0,0 +1,47 @@
+/**
+ * The standard, traditional body of a login request.
+ */
+export interface LoginRequest {
+       /** The user's password. */
+       p: string;
+       /** The user's username. */
+       u: string;
+}
+
+/**
+ * The body of a login request submitted through the `/user/login/oauth`
+ * endpoint of the Traffic Ops API.
+ */
+export interface OAuthLoginRequest {
+       authCodeTokenUrl: string;
+       code: string;
+       clientId: string;
+       redirectUri: string;
+}
+
+/**
+ * The body of a login request submitted through the `/user/login/token`
+ * endpoint of the Traffic Ops API.
+ */
+export interface TokenLoginRequest {
+       /** The user's authentication token. */
+       t: string;
+}
+
+/**
+ * The body of a password reset request submitted through the
+ * `/user/reset_password` endpoint of the Traffic Ops API.
+ */
+export interface ResetPasswordRequest {
+       email: `${string}@${string}.${string}`;
+}
+
+/**
+ * The body of a new user registration request submitted through the
+ * `/users/register` endpoint of the Traffic Ops API.
+ */
+export interface RegistrationRequest {
+       email: `${string}@${string}.${string}`;
+       role: number;
+       tenantId: number;
+}
diff --git a/src/logs.ts b/src/logs.ts
new file mode 100644
index 0000000..f467162
--- /dev/null
+++ b/src/logs.ts
@@ -0,0 +1,66 @@
+/**
+ * Represents a single Traffic Ops ChangeLog entry as returned by the `/logs`
+ * endpoint of its API.
+ */
+export interface Log {
+       readonly id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       /**
+        * @deprecated This field has no further use, and is subject to removal 
in
+        * the future.
+        */
+       level: "APICHANGE";
+       message: string;
+       /**
+        * @deprecated This cannot be populated, and so should always be 
considered
+        * null, and is subject to removal in the future.
+        */
+       readonly ticketNum: number | null;
+       user: string;
+}
+
+/**
+ * Converts a changelog entry to a string, suitable for use as a line in a
+ * logfile.
+ *
+ * @example
+ * const l = {
+ *     id: 1,
+ *     lastUpdated: new Date(0),
+ *     level: "APICHANGE",
+ *     message: "a message",
+ *     ticketNum: 2,
+ *     user: me
+ * }
+ *
+ * console.log(logEntryToString(l));
+ * // Output:
+ * // #1 1970-01-01T00:00:00.000Z: me via APICHANGE (From Ticket #2): a message
+ *
+ * @param log The Log entry being formatted.
+ * @returns A string representation of `log`.
+ */
+export function logEntryToString(log: Log): string {
+       const {id, lastUpdated, level, message, ticketNum, user} = log;
+
+       let ret = `#${id} ${lastUpdated.toISOString()}: ${user} via ${level}`;
+       if (ticketNum !== null) {
+               ret += ` (From Ticket #${ticketNum})`;
+       }
+
+       return `${ret}: ${message}`;
+}
+
+/**
+ * Represents the response from the Traffic Ops API to a request made to its
+ * `/logs/newcount` endpoint.
+ */
+export interface NewLogCount {
+       newLogcount: number;
+}
diff --git a/src/parameter.ts b/src/parameter.ts
new file mode 100644
index 0000000..0e749cd
--- /dev/null
+++ b/src/parameter.ts
@@ -0,0 +1,36 @@
+/**
+ * A RequestParameter is a Parameter as given in PUT and POST requests to
+ * /parameters.
+ */
+export interface RequestParameter {
+       configFile: string;
+       name: string;
+       secure: boolean;
+       value: string;
+}
+
+/**
+ * A ResponseParameter is a Parameter as given by Traffic Ops in its API
+ * responses.
+ */
+export interface ResponseParameter {
+       configFile: string;
+       readonly id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       name: string;
+       profiles: Array<string>;
+       secure: boolean;
+       value: string;
+}
+
+/**
+ * A Parameter generically represents a Parameter, either in request format or
+ * response format.
+ */
+export type Parameter = RequestParameter | ResponseParameter;
diff --git a/src/physical.location.ts b/src/physical.location.ts
new file mode 100644
index 0000000..6eb4b45
--- /dev/null
+++ b/src/physical.location.ts
@@ -0,0 +1,86 @@
+/**
+ * Represents a Physical Location as returned by the Traffic Ops API in
+ * responses.
+ */
+export interface ResponsePhysicalLocation {
+       /** The Physical Location’s street address. */
+       address: string;
+       /** The name of the city in which the Physical Location lies. */
+       city: string;
+       /** Any and all human-readable comments. */
+       comments: string | null;
+       /** The email address of the Physical Location’s poc. */
+       email: string | null;
+       /** An integral, unique identifier for the Physical Location. */
+       id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       /** The name of the Physical Location. */
+       name: string;
+       /** A phone number where the the Physical Location’s poc might be 
reached. */
+       phone: string | null;
+       /** The name of a “point of contact” for the Physical Location. */
+       poc: string | null;
+       /**
+        * The name of the region within which the Physical Location lies.
+        *
+        * This will be `null` in responses to PUT or POST requests which didn't
+        * specify it, or which explicitly specified it as `null`.
+        */
+       region: string | null;
+       /**
+        * An integral, unique identifier for the region within which the 
Physical
+        * Location lies.
+        */
+       regionId: number;
+       /** An abbreviation of the name. */
+       shortName: string;
+       /**
+        * An abbreviation (usually) of the name of the state or province within
+        * which this Physical Location lies.
+        */
+       state: string;
+       /** The zip code of the Physical Location. */
+       zip: string;
+}
+
+/**
+ * Represents a Physical Location as required by the Traffic Ops API in
+ * requests.
+ */
+export interface RequestPhysicalLocation {
+       /** The Physical Location’s street address. */
+       address: string;
+       /** The name of the city in which the Physical Location lies. */
+       city: string;
+       /** Any and all human-readable comments. */
+       comments?: string | null;
+       /** The email address of the Physical Location’s poc. */
+       email?: string | null;
+       /** The name of the Physical Location. */
+       name: string;
+       /** A phone number where the the Physical Location’s poc might be 
reached. */
+       phone?: string | null;
+       /** The name of a “point of contact” for the Physical Location. */
+       poc?: string | null;
+       /**
+        * An integral, unique identifier for the region within which the 
Physical
+        * Location lies.
+        */
+       regionId: number;
+       /**
+        * An abbreviation (usually) of the name of the state or province within
+        * which this Physical Location lies.
+        */
+       state: string;
+       /** The zip code of the Physical Location. */
+       zip: string;
+}
+
+/** Represents a Physical Location. */
+export type PhysicalLocation = ResponsePhysicalLocation | 
RequestPhysicalLocation;
diff --git a/src/plugin.ts b/src/plugin.ts
new file mode 100644
index 0000000..7df1df7
--- /dev/null
+++ b/src/plugin.ts
@@ -0,0 +1,10 @@
+/**
+ * Represents a Traffic Ops plugin as reported by the `/plugins` API endpoint.
+ *
+ * Plugins cannot be modified through the API.
+ */
+export interface TOPlugin {
+       readonly description: string;
+       readonly name: string;
+       readonly version: string;
+}
diff --git a/src/profile.ts b/src/profile.ts
new file mode 100644
index 0000000..803dd58
--- /dev/null
+++ b/src/profile.ts
@@ -0,0 +1,96 @@
+/** ProfileTypes are the valid `type`s of Profiles. */
+export const enum ProfileType {
+       /**
+        * A Profile for a cache server (edge-tier or mid-tier). Grove cache
+        * servers, though, should use GROVE_PROFILE instead.
+        */
+       ATS_PROFILE = "ATS_PROFILE",
+       /** A Profile for a Traffic Router server. */
+       TR_PROFILE = "TR_PROFILE",
+       /** A Profile for a Traffic Monitor server. */
+       TM_PROFILE = "TM_PROFILE",
+       /** A Profile for a Traffic Stats server. */
+       TS_PROFILE = "TS_PROFILE",
+       /** A Profile for a Traffic Portal server. */
+       TP_PROFILE = "TP_PROFILE",
+       /** A Profile for an InfluxDB instance/server. */
+       INFLUXDB_PROFILE = "INFLUXDB_PROFILE",
+       /**
+        * A Profile for a Riak KV server.
+        *
+        * @deprecated Riak KV as a back-end for Traffic Vault is deprecated.
+        */
+       RIAK_PROFILE = "RIAK_PROFILE",
+       /** A Profile for a Splunk server. */
+       SPLUNK_PROFILE = "SPLUNK_PROFILE",
+       /** A Profile used by Delivery Services, rather than servers. */
+       DS_PROFILE = "DS_PROFILE",
+       /** A Profile used by Origins and/or origin servers. */
+       ORG_PROFILE = "ORG_PROFILE",
+       /** A Profile for Kafka servers. */
+       KAFKA_PROFILE = "KAFKA_PROFILE",
+       /** A Profile for Logstash servers. */
+       LOGSTASH_PROFILE = "LOGSTASH_PROFILE",
+       /** A Profile for ElasticSearch servers. */
+       ES_PROFILE = "ES_PROFILE",
+       /** A Profile for any server that doesn't have a more specific Profile 
type. */
+       UNK_PROFILE = "UNK_PROFILE",
+       /** A Profile for Grove cache servers. */
+       GROVE_PROFILE = "GROVE_PROFILE"
+}
+
+/**
+ * In responses from certain endpoints, Profiles include these custom
+ * representations of their assigned Parameters.
+ */
+interface ResponseProfileParameter {
+       configFile: string;
+       id: number;
+       lastUpdated: null;
+       name: string;
+       profiles: null;
+       secure: boolean;
+       value: string;
+}
+
+/** A ResponseProfile is a Profile as given by Traffic Ops in API responses. */
+export interface ResponseProfile {
+       cdn: number;
+       /**
+        * This is null in responses to PUT or POST requests where 'cdnName' was
+        * not given.
+        */
+       cdnName: string | null;
+       description: string;
+       id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       name: string;
+       /**
+        * This only appears when a response array contains exactly one Profile,
+        * and when that Profile has at least one assigned Parameter.
+        */
+       params?: [ResponseProfileParameter, ...ResponseProfileParameter[]];
+       routingDisabled: boolean;
+       type: ProfileType;
+}
+
+/** RequestProfile is a Profile as required in requests by the Traffic Ops 
API. */
+export interface RequestProfile {
+       cdn: number;
+       description: string;
+       name: string;
+       routingDisabled: boolean;
+       type: ProfileType;
+}
+
+/**
+ * A Profile represents, generically, a Profile in the context of either a
+ * request to or a response from the Traffic Ops API.
+ */
+export type Profile = RequestProfile | ResponseProfile;
diff --git a/src/server.ts b/src/server.ts
new file mode 100644
index 0000000..f06d9ea
--- /dev/null
+++ b/src/server.ts
@@ -0,0 +1,301 @@
+/**
+ * This file is for modeling and functionality related to Server objects
+ */
+
+/** IPAddress is a single IP address of a single network interface of a 
server. */
+export interface IPAddress {
+       /** The actual IP address. */
+       address: string;
+       /** The IP address of a gateway for this IP, if one exists/is known. */
+       gateway: string | null;
+       /** Whether or not this IP address is responsible for serving ATC 
traffic. */
+       serviceAddress: boolean;
+}
+
+/** Interface is a server's network interface. */
+export interface Interface {
+       /** The IP addresses assigned to this network interface. */
+       ipAddresses: Array<IPAddress>;
+       /** The maximum bandwidth for considering the server healthy, if any. */
+       maxBandwidth: number | null;
+       /**
+        * Whether or not the Traffic Monitor should consider this network 
interface
+        * in health calculations.
+        */
+       monitor: boolean;
+       /** The maximum transmission unit of the network interface, if known. */
+       mtu: number | null;
+       /** The name of the network interface in the `/dev` directory. */
+       name: string;
+}
+
+/**
+ * Searches a collection of IPAddresses exhaustively for service addresses.
+ *
+ * @param ips The IPAddresses to search.
+ * @returns A tuple of the found IPv4 and IPv6 addresses, each being `null` if
+ * not found.
+ */
+function exhaustiveServiceAddresses(ips: Array<IPAddress>): [IPAddress | null, 
IPAddress | null] {
+       let ipv4 = null;
+       let ipv6 = null;
+       for (const ip of ips) {
+               if (ip.serviceAddress) {
+                       if (ip.address.includes(":")) {
+                               if (ipv6 !== null) {
+                                       throw new Error(`found two IPv6 service 
addresses: '${ipv6.address}' and '${ip.address}'`);
+                               }
+                               ipv6 = ip;
+                       } else if (ipv4 !== null) {
+                               throw new Error(`found two IPv4 service 
addresses: '${ipv4.address}' and '${ip.address}'`);
+                       } else {
+                               ipv4 = ip;
+                       }
+               }
+       }
+       return [ipv4, ipv6];
+}
+
+/**
+ * Searches for service IP Addresses in the given collection, traversing the
+ * list as little as possible to find a valid set.
+ * @param ips The collection of IPs to search.
+ * @returns A tuple of the found IPv4 and IPv6 addresses, each being `null` if
+ * not found.
+ */
+function inexhaustiveServiceAddresses(ips: Array<IPAddress>): [IPAddress | 
null, IPAddress | null] {
+       let ipv4 = null;
+       let ipv6 = null;
+       for (const ip of ips) {
+               if (ip.serviceAddress) {
+                       if (ip.address.includes(":")) {
+                               if (ipv6 !== null) {
+                                       throw new Error(`found two IPv6 service 
addresses: '${ipv6.address}' and '${ip.address}'`);
+                               }
+                               ipv6 = ip;
+                       } else if (ipv4 !== null) {
+                               throw new Error(`found two IPv4 service 
addresses: '${ipv4.address}' and '${ip.address}'`);
+                       } else {
+                               ipv4 = ip;
+                       }
+               }
+               if (ipv4 !== null && ipv6 !== null) {
+                       break;
+               }
+       }
+       return [ipv4, ipv6];
+}
+
+/**
+ * Extracts the "service" address of an {@link IPAddress} collection or
+ * {@link Interface}.
+ *
+ * @param inf The interface or raw list of IP addresses from which to extract
+ * service addresses.
+ * @param exhaustive If `true`, the function will check for service addresses
+ * exhaustively. When this is `false`, the function returns as soon as it finds
+ * one service address per address family - essentially assuming that there are
+ * no duplicates. Exhaustive searches will ensure there is no more than one
+ * service address per family by checking the entire collection.
+ * @returns A tuple of the IPv4 service address of the interface (or `null` if
+ * it doesn't have one) and the IPv6 service address of the interface (or 
`null`
+ * if it doesn't have one). Note that this function does not check for the case
+ * when a collection of IPs has no service addresses - it is up to the caller 
to
+ * recognize that a return value of `[null, null]` indicates an invalid
+ * collection.
+ * @throws {Error} When more than one service address is found for a single
+ * address family.
+ */
+export function serviceAddresses(inf: Interface | Array<IPAddress>, exhaustive 
= false): [ipv4Address: IPAddress | null, ipv6Address: IPAddress | null] {
+       const arr = inf instanceof Array ? inf : inf.ipAddresses;
+       if (exhaustive) {
+               return exhaustiveServiceAddresses(arr);
+       }
+       return inexhaustiveServiceAddresses(arr);
+}
+
+/**
+ * Represents a nebulous "server" object as returned by Traffic Ops in
+ * responses.
+ */
+export interface ResponseServer {
+       /** The Cache Group to which the server belongs. */
+       cachegroup: string;
+       /**
+        * The integral, unique identifier of the Cache Group to which the 
server
+        * belongs.
+        */
+       cachegroupId: number;
+       /**
+        * The integral, unique identifier of the CDN to which the server 
belongs.
+        */
+       cdnId: number;
+       /** The name of the CDN to which the server belongs. */
+       cdnName: string;
+       /**
+        * The servers FQDN without its hostname - e.g. 'apache.org' from
+        * 'trafficcontrol.apache.org'.
+        */
+       domainName: string;
+       /**
+        * Legacy field with no purpose.
+        *
+        * @deprecated This field has no purpose and is subject to removal in 
the
+        * future.
+        */
+       guid: number | null;
+       /**
+        * The server's hostname, e.g. 'trafficcontrol' from
+        * 'trafficcontrol.apache.org'.
+        */
+       hostName: string;
+       /** The port used to serve HTTPS responses, if any. */
+       httpsPort: number | null;
+       /** An integral, unique identifier for this Server. */
+       readonly id: number;
+       /** The IP address of the Server's ILO interface. */
+       iloIpAddress: string | null;
+       /** The IP address of the gateway to the Server's ILO interface. */
+       iloIpGateway: string | null;
+       /**
+        * A netmask that describes the subnet allocated to the Server's ILO
+        * interface.
+        */
+       iloIpNetmask: string | null;
+       /** The Server's ILO interface's password. */
+       iloPassword: string | null;
+       /** The Server's ILO interface's root user's name. */
+       iloUsername: string | null;
+       /** The Server's network interfaces. */
+       interfaces: Array<Interface>;
+       /** The date/time at which the Server was last updated. */
+       lastUpdated: Date;
+       /** The IP address of the server's management interface. */
+       mgmtIpAddress: string | null;
+       /** The IP address of the gateway to the Server's management interface. 
*/
+       mgmtIpGateway: string | null;
+       /**
+        * The netmask that describes the subnet allocated to the Server's
+        * management interface.
+        */
+       mgmtIpNetmask: string | null;
+       /** The reason the Server has been taken out of service. */
+       offlineReason: string | null;
+       /** The physical location in which the Server resides. */
+       physLocation: string;
+       /**
+        * An integral, unique identifier for the physical location in which the
+        * Server resides.
+        */
+       physLocationId: number;
+       /** The Profile used by the Server. */
+       profile: string;
+       /**
+        * A description of the Profile used by the Server.
+        *
+        * @deprecated Future representations of Server objects will drop the
+        * Profile description entirely, as it's trivially deduced from Profile
+        * identity.
+        */
+       profileDesc: string;
+       /**
+        * An integral, unique identifier for the Profile used by the Server.
+        *
+        * @deprecated In the latest API version, a server's Profile is 
identified
+        * only by name, not unique, integral identifier.
+        */
+       profileId: number;
+       /** Whether or not revalidations are pending for this Server. */
+       revalPending: boolean;
+       /**
+        * Legacy field with no purpose.
+        *
+        * @deprecated This field has no purpose and is subject to removal in 
the
+        * future.
+        */
+       rack: string | null;
+       /** The hostname of the router that routes to this Server. */
+       routerHostName: string | null;
+       /** The... name... of the port... used by the Server's router?? */
+       routerPortName: string | null;
+       /** The Server's status. */
+       status: string;
+       /** An integral, unique, identifier for the Server's Status. */
+       statusId: number;
+       /** The time at which the server's status was last updated. */
+       statusLastUpdated: Date | null;
+       /** The port on which the Server listens for incoming TCP connections. 
*/
+       tcpPort: number | null;
+       /** The type of the Server. */
+       type: string;
+       /** An integral, unique identifier for the Type of this Server. */
+       typeId: number;
+       /** Whether or not this Server has updates pending. */
+       updPending: boolean;
+       /**
+        * The string used by Traffic Router for consistent hashing to this 
Server.
+        *
+        * This is generated for the server upon its creation, and cannot be
+        * modified afterwards.
+        */
+       readonly xmppId: string;
+       /** legacy field with no purpose. */
+       xmppPasswd?: string | null;
+}
+
+/**
+ * Servercheck models the data returned by the /servercheck API endpoint.
+ */
+export interface Servercheck {
+       /** contains the server's Status */
+       adminState: string;
+       /** the name of the Cache Group to which the server belongs */
+       cacheGroup: string;
+       /**
+        * Checks emulates a map of check names to their numbers. All values are
+        * numbers, but some may express boolean concepts; for example, the ORT
+        * check uses 1 to represent "true" and any other value indicates 
"false".
+        */
+       checks?: Record<string, number>;
+       /** the server's hostname */
+       hostName: string;
+       /** the server's ID */
+       id: number;
+       /** the name of the server's Profile */
+       profile: string;
+       /** whether or not the server has pending revalidations */
+       revalPending: boolean;
+       /** the name of the server's Type */
+       type: string;
+       /** whether or not the server has updates pending */
+       updPending: boolean;
+}
+
+/**
+ * Builds a true Map from the Servercheck's "checks" property.
+ *
+ * @param srv The Servercheck to convert.
+ * @returns A map of servercheck check names to their values.
+ */
+export function checkMap(srv: Servercheck): Map<string, number | boolean> {
+       const ret = new Map();
+       if (!srv.checks) {
+               return ret;
+       }
+       for (const [key, value] of Object.entries(srv.checks)) {
+               switch (key) {
+                       case "ILO":
+                       case "10G":
+                       case "FQDN":
+                       case "DSCP":
+                       case "10G6":
+                       case "MTU":
+                               ret.set(key, value === 1);
+                               break;
+                       default:
+                               ret.set(key, value);
+                               break;
+               }
+       }
+       return ret;
+}
diff --git a/src/stats.ts b/src/stats.ts
new file mode 100644
index 0000000..3d0752e
--- /dev/null
+++ b/src/stats.ts
@@ -0,0 +1,67 @@
+/** CacheStatsSeries is a set of data collected by Traffic Stats. */
+export interface CacheStatsSeries {
+       columns: ["time", "sum_count"];
+       count: number;
+       name: `${"bandwidth" | "connections" | "maxkbps"}.cdn.1min`;
+       /**
+        * Each first tuple element is actually a string that represents a
+        * date/time, in a custom format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       values: Array<[Date, number | null]>;
+}
+
+/** CacheStatsSummary is a summary of some statistics set. */
+export interface CacheStatsSummary {
+       average: number;
+       count: number;
+       fifthPercentile: number;
+       max: number;
+       min: number;
+       ninetyEightPercentile: number;
+       ninetyFifthPercentile: number;
+}
+
+/** Represents a response from /cache_stats.*/
+export interface CacheStats {
+       /**
+        * This will be excluded if the 'exclude' query string parameter was
+        * "series" **or** if there were no data points for the requested data 
set.
+        */
+       series?: CacheStatsSeries;
+       /**
+        * This will be excluded **only** if the 'exclude' query string 
parameter
+        * was "summary".
+        */
+       summary?: CacheStatsSummary;
+}
+
+/**
+ * CurrentStats represents a response from the `/current_stats` Traffic Ops API
+ * endpoint.
+ */
+export interface CurrentStats {
+       /**
+        * Each entry in the `currentStats` array reports the recorded stats 
for the
+        * named CDN. The last entry is always the total across all CDNs, and
+        * doesn't report capacity. The first entry is *usually* the special ALL
+        * CDN, which - wherever it does appear - will always have `null` for 
all
+        * its stats.
+        */
+       currentStats: [
+               ...Array<
+               {
+                       bandwidth: number | null;
+                       capacity: number | null;
+                       cdn: string;
+                       connections: number | null;
+               }
+               >,
+               {
+                       bandwidth: number | null;
+                       cdn: "total";
+                       connections: number | null;
+               }
+       ];
+}
diff --git a/src/status.ts b/src/status.ts
new file mode 100644
index 0000000..dbc025a
--- /dev/null
+++ b/src/status.ts
@@ -0,0 +1,25 @@
+/** ResponseStatus represents a Status as returned in responses from the API. 
*/
+export interface ResponseStatus {
+       description: string | null;
+       id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       name: string;
+}
+
+/** RequestStatus represents a Status as used in requests to the API. */
+export interface RequestStatus {
+       description?: string | null;
+       name: string;
+}
+
+/**
+ * Status generically represents a Status in the context of an API request or
+ * response.
+ */
+export type Status = ResponseStatus | RequestStatus;
diff --git a/src/type.ts b/src/type.ts
new file mode 100644
index 0000000..7b11fa4
--- /dev/null
+++ b/src/type.ts
@@ -0,0 +1,29 @@
+/**
+ * TypeFromResponse represents a Type as shown in the responses from the API.
+ *
+ * This breaks the naming convention used in the rest of this library because
+ * ResponseType is already a global type in browsers and NodeJS.
+ */
+export interface TypeFromResponse {
+       description: string;
+       id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       name: string;
+       useInTable: string;
+}
+
+/** RequestType represents a Type as given in requests to the API. */
+export interface RequestType {
+       description: string;
+       name: string;
+       useInTable: string;
+}
+
+/** Type generically represents a Type in the context of an API request or 
response.  */
+export type Type = TypeFromResponse | RequestType;
diff --git a/src/user.ts b/src/user.ts
new file mode 100644
index 0000000..7950f25
--- /dev/null
+++ b/src/user.ts
@@ -0,0 +1,232 @@
+/**
+ * PostRequestUser is a user as it appears in a POST request to /users.
+ * This is subtly different from a user as required in other contexts. For more
+ * information, see apache/trafficcontrol#6299.
+ */
+export interface PostRequestUser {
+       addressLine1?: string | null;
+       addressLine2?: string | null;
+       city?: string | null;
+       company?: string | null;
+       confirmLocalPasswd: string;
+       country?: string | null;
+       email: `${string}@${string}.${string}`;
+       fullName: string;
+       /** @deprecated This has no purpose and should never be used. */
+       gid?: number | null;
+       localPasswd: string;
+       newUser?: boolean | null;
+       phoneNumber?: string | null;
+       postalCode?: string | null;
+       publicSshKey?: string | null;
+       role: number;
+       stateOrProvince?: string | null;
+       tenantId?: never;
+       tenantID: number;
+       /** @deprecated This has no purpose and should never be used. */
+       uid?: number | null;
+       username: string;
+}
+
+/**
+ * Represents a user in a PUT request where the user's password is *not* being
+ * changed.
+ */
+interface PutRequestNotChangingPasswordUser {
+       addressLine1?: string | null;
+       addressLine2?: string | null;
+       city?: string | null;
+       company?: string | null;
+       country?: string | null;
+       email: `${string}@${string}.${string}`;
+       fullName: string;
+       /** @deprecated This has no purpose and should never be used. */
+       gid?: number | null;
+       newUser?: boolean | null;
+       phoneNumber?: string | null;
+       postalCode?: string | null;
+       publicSshKey?: string | null;
+       role: number;
+       stateOrProvince?: string | null;
+       tenantId?: never;
+       tenantID: number;
+       /** @deprecated This has no purpose and should never be used. */
+       uid?: number | null;
+       username: string;
+}
+
+/**
+ * PostRequestUser is a user as it appears in a POST request to /users.
+ * This is subtly different from a user as required in other contexts. For more
+ * information, see apache/trafficcontrol#6299.
+ */
+export type PutRequestUser = PostRequestUser | 
PutRequestNotChangingPasswordUser;
+
+/** Groups the fields common to responses from /users in all contexts. */
+interface ResponseUser {
+       addressLine1: string | null;
+       addressLine2: string | null;
+       city: string | null;
+       company: string | null;
+       country: string | null;
+       email: `${string}@${string}.${string}`;
+       fullName: string;
+       /** @deprecated This has no purpose and should never be used. */
+       gid: number | null;
+       id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       newUser: boolean | null;
+       phoneNumber: string | null;
+       postalCode: string | null;
+       publicSshKey: string | null;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       registrationSent?: null | Date;
+       role: number;
+       stateOrProvince: null;
+       tenant: string;
+       tenantID?: never;
+       tenantId: number;
+       /** @deprecated This has no purpose and should never be used. */
+       uid: number | null;
+       username: string;
+}
+
+/** Represents a response from /users to a PUT or POST request. */
+export interface PutOrPostResponseUser extends ResponseUser {
+       /**
+        * This appears only in response to POST requests, or to PUT requests 
where
+        * the user's password was changed.
+        */
+       confirmLocalPasswd?: string;
+       rolename?: never;
+       roleName: string;
+}
+
+/** Represents a response from /users to a GET request. */
+export interface GetResponseUser extends ResponseUser {
+       confirmLocalPasswd?: never;
+       rolename: string;
+       roleName?: never;
+}
+
+/**
+ * User generically represents a user in the context of a PUT, POST, or GET
+ * request or response to/from /users.
+ */
+export type User = PutRequestUser | PostRequestUser | PutOrPostResponseUser | 
GetResponseUser;
+
+/**
+ * ResponseCurrentUser represents a response from /user/current.
+ */
+export interface ResponseCurrentUser {
+       addressLine1: string | null;
+       addressLine2: string | null;
+       city: string | null;
+       company: string | null;
+       country: string | null;
+       email: `${string}@${string}.${string}`;
+       fullName: string;
+       gid: number | null;
+       id: number;
+       /**
+        * This is actually a string that represents a date/time, in a custom
+        * format. Refer to
+        * [the Traffic Ops API 
documentation](https://traffic-control-cdn.readthedocs.io/en/latest/api/index.html#traffic-ops-s-custom-date-time-format)
+        * for details.
+        */
+       lastUpdated: Date;
+       localUser: boolean;
+       newUser: boolean;
+       phoneNumber: string | null;
+       postalCode: string | null;
+       publicSshKey: string | null;
+       role: number;
+       rolename?: never;
+       roleName: string;
+       stateOrProvince: string | null;
+       tenant: string;
+       tenantId: number;
+       uid: number | null;
+       username: string;
+}
+
+/**
+ * Currently, a request to /user/current has no properties. This bug is tracked
+ * by apache/trafficcontrol#6367.
+ */
+export interface RequestCurrentUser {
+       addressLine1?: string | null;
+       addressLine2?: string | null;
+       city?: string | null;
+       company?: string | null;
+       country?: string | null;
+       /**
+        * Note that while this is allowed to be null or undefined, it will 
**not**
+        * be allowed to be either of those things as a property of a
+        * {@link PostRequestUser} nor as a property of a {@link 
PutRequestUser}.
+        * This means that setting it as such can cause problems for future 
requests
+        * and should be avoided whenever possible.
+        */
+       email?: string | null;
+       /**
+        * Note that while this is allowed to be null or undefined, it will 
**not**
+        * be allowed to be either of those things as a property of a
+        * {@link PostRequestUser} nor as a property of a {@link 
PutRequestUser}.
+        * This means that setting it as such can cause problems for future 
requests
+        * and should be avoided whenever possible.
+        */
+       fullName?: string | null;
+       /**
+        * @deprecated This serves no purpose and is subject to removal in the
+        * future.
+        */
+       gid?: string | null;
+       localUser?: boolean | null;
+       newUser?: boolean | null;
+       phoneNumber?: string | null;
+       postalCode?: string | null;
+       publicSshKey?: string | null;
+       /**
+        * Unlike in virtually every other context, this is allowed to be 
`null` or
+        * undefined. In that case, it has the meaning "leave this unchanged" 
rather
+        * than setting it to `null` as with most other properties.
+        */
+       role?: number | null;
+       stateOrProvince?: string | null;
+       /**
+        * Unlike in virtually every other context, this is allowed to be 
`null` or
+        * undefined. In that case, it has the meaning "leave this unchanged" 
rather
+        * than setting it to `null` as with most other properties.
+        */
+       tenantId?: number | null;
+       tenantID?: never;
+       /**
+        * @deprecated This serves no purpose and is subject to removal in the
+        * future.
+        */
+       uid?: string | null;
+       /**
+        * Unlike in virtually every other context, this is allowed to be 
`null` or
+        * undefined. In that case, it has the meaning "leave this unchanged" 
rather
+        * than setting it to `null` as with most other properties.
+        */
+       username?: never;
+}
+
+/**
+ * CurrentUser generically represents a "current user" representation in the
+ * context of either a request or response. This differs from a "user" in a few
+ * key ways as tracked by apache/trafficcontrol#6299.
+ */
+export type CurrentUser = ResponseCurrentUser | RequestCurrentUser;
diff --git a/src/vault.ts b/src/vault.ts
new file mode 100644
index 0000000..9fc84f9
--- /dev/null
+++ b/src/vault.ts
@@ -0,0 +1,19 @@
+/**
+ * The type of a response from the `vault/ping` endpoint of the Traffic Ops 
API.
+ */
+export interface VaultPing {
+       status: string;
+       server: string;
+}
+
+/**
+ * The type of a response from the `vault/bucket/{{bucket}}/key/{{key}}/values`
+ * endpoint of the Traffic Ops API.
+ *
+ * @deprecated This representation is extremely tightly coupled with the
+ * deprecated Riak backend Traffic Vault provider, and has been removed from 
the
+ * latest API version.
+ */
+export interface BucketValues {
+       [bucket: string]: unknown;
+}

Reply via email to