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 bae46c61b3ded6d30ca2ef01a61a24decdb7f9ee
Author: ocket8888 <[email protected]>
AuthorDate: Wed Apr 27 20:29:27 2022 -0600

    Finish out typings
---
 dist/acme.d.ts              |   4 +
 dist/cache.group.d.ts       |  23 ++++-
 dist/cdn.d.ts               |   9 +-
 dist/delivery.service.d.ts  | 107 ++++++++++++++++++---
 dist/division.d.ts          |   4 +-
 dist/index.d.ts             |  16 +++-
 dist/index.js               |  14 ++-
 dist/logs.d.ts              |   2 +-
 dist/physical.location.d.ts |   2 +-
 dist/profile.d.ts           |  84 +++++++++++++++-
 dist/server.d.ts            |  81 +++++++++++++++-
 dist/server.js              |   4 +-
 dist/stats.d.ts             |  58 +++++++++++
 dist/stats.js               |   4 +-
 dist/status.d.ts            |   6 +-
 dist/type.d.ts              |   4 +-
 dist/user.d.ts              |  41 +++++++-
 dist/user.js                |   4 +-
 package.json                |   2 +-
 src/acme.ts                 |   8 ++
 src/cache.group.ts          |  56 ++++++++++-
 src/cdn.ts                  |  14 ++-
 src/delivery.service.ts     | 229 ++++++++++++++++++++++++++++++++++++++++----
 src/division.ts             |   4 +-
 src/index.ts                |  23 ++++-
 src/logs.ts                 |   2 +-
 src/parameter.ts            |  36 -------
 src/physical.location.ts    |   2 +-
 src/profile.ts              | 199 +++++++++++++++++++++++++++++++++++++-
 src/server.ts               | 135 +++++++++++++++++++++++++-
 src/stats.ts                | 115 ++++++++++++++++++++++
 src/status.ts               |  13 ++-
 src/type.ts                 |   7 +-
 src/user.ts                 |  96 ++++++++++++++++++-
 34 files changed, 1293 insertions(+), 115 deletions(-)

diff --git a/dist/acme.d.ts b/dist/acme.d.ts
index e768ddb..333c179 100644
--- a/dist/acme.d.ts
+++ b/dist/acme.d.ts
@@ -4,3 +4,7 @@ export interface ACMEAccount {
     provider: string;
     uri: string;
 }
+export interface ACMEDNSRecord {
+    fqdn: string;
+    record: string;
+}
diff --git a/dist/cache.group.d.ts b/dist/cache.group.d.ts
index aa3e779..579f332 100644
--- a/dist/cache.group.d.ts
+++ b/dist/cache.group.d.ts
@@ -3,7 +3,7 @@ export interface ResponseASN {
     cachegroup: string;
     cachegroupId: number;
     readonly id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
 }
 export interface RequestASN {
     asn: number;
@@ -32,7 +32,7 @@ interface ResponseCacheGroupBase {
     fallbacks: Array<string>;
     fallbackToClosest: boolean;
     readonly id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     latitude: number | null;
     localizationMethods: Array<LocalizationMethod>;
     longitude: number | null;
@@ -63,4 +63,23 @@ declare type ResponseCacheGroupWithSecondaryButNotParent = 
ResponseCacheGroupWit
 declare type ResponseCacheGroupWithoutParentOrSecondary = 
ResponseCacheGroupWithoutParent & ResponseCacheGroupWithoutSecondaryParent;
 export declare type ResponseCacheGroup = 
ResponseCacheGroupWithParentButNotSecondary | 
ResponseCacheGroupWithParentAndSecondary | 
ResponseCacheGroupWithSecondaryButNotParent | 
ResponseCacheGroupWithoutParentOrSecondary;
 export declare type CacheGroup = RequestCacheGroup | ResponseCacheGroup;
+export interface ResponseCacheGroupParameters {
+    cachegroupParameters: Array<{
+        parameter: number;
+        readonly lastUpdated: Date;
+        cachegroup: string;
+    }>;
+}
+export interface RequestCacheGroupParameter {
+    cacheGroupId: number;
+    parameterId: number;
+}
+export interface CacheGroupDeliveryServiceAssignmentRequest {
+    deliveryServices: Array<number>;
+}
+export interface CacheGroupDeliveryServiceAssignmentResponse {
+    deliveryServices: Array<number>;
+    readonly id: number;
+    serverNames: Array<string>;
+}
 export {};
diff --git a/dist/cdn.d.ts b/dist/cdn.d.ts
index 0320cdc..a0c79f7 100644
--- a/dist/cdn.d.ts
+++ b/dist/cdn.d.ts
@@ -7,7 +7,14 @@ export interface ResponseCDN {
     dnssecEnabled: boolean;
     domainName: string;
     readonly id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     name: string;
 }
 export declare type CDN = RequestCDN | ResponseCDN;
+export interface CDNDomain {
+    domainName: string;
+    profileId: number;
+    parameterId: number;
+    profileName: string;
+    profileDescription: string;
+}
diff --git a/dist/delivery.service.d.ts b/dist/delivery.service.d.ts
index b2f8b22..5d5cdd6 100644
--- a/dist/delivery.service.d.ts
+++ b/dist/delivery.service.d.ts
@@ -155,7 +155,7 @@ interface ResponseDeliveryServiceBase {
     innerHeaderRewrite: string | null;
     ipv6RoutingEnabled: boolean;
     lastHeaderRewrite: string | null;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     logsEnabled: boolean;
     longDesc: string | null;
     longDesc1?: string;
@@ -204,19 +204,98 @@ interface ResponseDeliveryServiceWithoutProfile extends 
ResponseDeliveryServiceB
 export declare type ResponseDeliveryService = 
ResponseDeliveryServiceWithProfile | ResponseDeliveryServiceWithoutProfile;
 export declare type DeliveryService = RequestDeliveryService | 
ResponseDeliveryService;
 export declare function bypassable(ds: DeliveryService): boolean;
-export interface DSCapacity {
-    availablePercent: number;
-    maintenancePercent: number;
-    unavailablePercent: number;
-    utilizedPercent: number;
-}
-export interface DSHealth {
-    cachegroups: Array<{
-        name: string;
-        offline: number;
-        online: number;
+export interface RequestDeliveryServiceRegexp {
+    pattern: string;
+    setNumber: number;
+    type: number;
+}
+export interface ResponseDeliveryServiceRegexp {
+    readonly id: number;
+    pattern: string;
+    setNumber: number;
+    type: number;
+    typeName: string;
+}
+export declare type DeliveryServiceRegexp = RequestDeliveryServiceRegexp | 
ResponseDeliveryServiceRegexp;
+export interface DeliveryServicesRegexps {
+    dsName: string;
+    regexes: Array<{
+        pattern: string;
+        setNumber: number;
+        type: string;
     }>;
-    totalOnline: number;
-    totalOffline: number;
 }
+export interface DSSafeUpdateRequest {
+    displayName: string;
+    infoUrl?: string | null;
+    longDesc?: string | null;
+    longDesc1?: string | null;
+}
+export interface RequestDeliveryServicesServers {
+    serverNames: Array<string>;
+}
+export interface ResponseDeliveryServicesServers {
+    serverNames: Array<string>;
+    xmlId: string;
+}
+export interface RequestDeliveryServiceServer {
+    dsId: number;
+    replace?: boolean | null;
+    servers?: Array<number> | null;
+}
+export interface ResponseDeliveryServiceServer {
+    deliveryService: number;
+    readonly lastUpdated: Date;
+    server: number;
+}
+export interface RequestServiceCategory {
+    name: string;
+}
+export interface ResponseServiceCategory {
+    readonly lastUpdated: Date;
+    name: string;
+}
+export declare type ServiceCategory = RequestServiceCategory | 
ResponseServiceCategory;
+export interface RequestStaticDNSEntry {
+    address: string;
+    cachegroupId?: number | null;
+    deliveryserviceId: number;
+    host: string;
+    ttl: number;
+    typeId: number;
+}
+export interface RequestStaticDNSEntryResponse {
+    address: string;
+    cachegroupId: number | null;
+    cachegroup: string | null;
+    deliveryserviceId: number;
+    deliveryservice: string | null;
+    host: string;
+    readonly id: number;
+    readonly lastUpdated: Date;
+    ttl: number;
+    type: string;
+    typeId: number;
+}
+interface ResponseStaticDNSEntryBase {
+    address: string;
+    deliveryserviceId: number;
+    deliveryservice: string;
+    host: string;
+    readonly id: number;
+    readonly lastUpdated: Date;
+    ttl: number;
+    type: string;
+    typeId: number;
+}
+interface ResponseStaticDNSEntryWithCacheGroup extends 
ResponseStaticDNSEntryBase {
+    cachegroupId: number;
+    cachegroup: string;
+}
+interface ResponseStaticDNSEntryWithoutCacheGroup extends 
ResponseStaticDNSEntryBase {
+    cachegroupId: null;
+    cachegroup: null;
+}
+export declare type ResponseStaticDNSEntry = 
ResponseStaticDNSEntryWithCacheGroup | ResponseStaticDNSEntryWithoutCacheGroup;
+export declare type StaticDNSEntry = RequestStaticDNSEntry | 
RequestStaticDNSEntryResponse | ResponseStaticDNSEntry;
 export {};
diff --git a/dist/division.d.ts b/dist/division.d.ts
index 4a41ac2..234cca7 100644
--- a/dist/division.d.ts
+++ b/dist/division.d.ts
@@ -3,7 +3,7 @@ export interface RequestDivision {
 }
 export interface ResponseDivision {
     readonly id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     name: string;
 }
 export declare type Division = RequestDivision | ResponseDivision;
@@ -15,7 +15,7 @@ export interface ResponseRegion {
     division: number;
     divisionName: string;
     readonly id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     name: string;
 }
 export declare type Region = RequestRegion | ResponseRegion;
diff --git a/dist/index.d.ts b/dist/index.d.ts
index cd7b655..4846846 100644
--- a/dist/index.d.ts
+++ b/dist/index.d.ts
@@ -2,21 +2,33 @@ export * from "./about";
 export * from "./acme";
 export * from "./alert";
 export * from "./cache.group";
+export * from "./capability";
 export * from "./cdn";
+export * from "./coordinate";
+export * from "./delivery.service.request";
 export * from "./delivery.service";
 export * from "./division";
+export * from "./dnssec";
+export * from "./federation";
 export * from "./invalidation";
 export * from "./iso";
 export * from "./login";
 export * from "./logs";
-export * from "./parameter";
+export * from "./origin";
 export * from "./physical.location";
 export * from "./plugin";
 export * from "./profile";
+export * from "./router";
+export * from "./server.capability";
 export * from "./server";
+export * from "./snap.and.queue";
+export * from "./ssl";
 export * from "./stats";
 export * from "./status";
+export * from "./steering";
+export * from "./topology";
 export * from "./type";
+export * from "./uri.signing";
 export * from "./user";
 export * from "./vault";
 import type { Alert } from "./alert";
@@ -27,7 +39,7 @@ interface VersionType {
     readonly unstable: boolean;
 }
 export declare const VERSION: VersionType;
-export interface APIResponse<T> {
+export interface APISuccessResponse<T> {
     alerts?: Array<Alert>;
     response: T;
     summary?: {
diff --git a/dist/index.js b/dist/index.js
index a5f9262..aa2a912 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -2,21 +2,33 @@ export * from "./about";
 export * from "./acme";
 export * from "./alert";
 export * from "./cache.group";
+export * from "./capability";
 export * from "./cdn";
+export * from "./coordinate";
+export * from "./delivery.service.request";
 export * from "./delivery.service";
 export * from "./division";
+export * from "./dnssec";
+export * from "./federation";
 export * from "./invalidation";
 export * from "./iso";
 export * from "./login";
 export * from "./logs";
-export * from "./parameter";
+export * from "./origin";
 export * from "./physical.location";
 export * from "./plugin";
 export * from "./profile";
+export * from "./router";
+export * from "./server.capability";
 export * from "./server";
+export * from "./snap.and.queue";
+export * from "./ssl";
 export * from "./stats";
 export * from "./status";
+export * from "./steering";
+export * from "./topology";
 export * from "./type";
+export * from "./uri.signing";
 export * from "./user";
 export * from "./vault";
 export const VERSION = {
diff --git a/dist/logs.d.ts b/dist/logs.d.ts
index dbe04bf..bcdcd2e 100644
--- a/dist/logs.d.ts
+++ b/dist/logs.d.ts
@@ -1,6 +1,6 @@
 export interface Log {
     readonly id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     level: "APICHANGE";
     message: string;
     readonly ticketNum: number | null;
diff --git a/dist/physical.location.d.ts b/dist/physical.location.d.ts
index 99b324f..1ae0a40 100644
--- a/dist/physical.location.d.ts
+++ b/dist/physical.location.d.ts
@@ -4,7 +4,7 @@ export interface ResponsePhysicalLocation {
     comments: string | null;
     email: string | null;
     id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     name: string;
     phone: string | null;
     poc: string | null;
diff --git a/dist/profile.d.ts b/dist/profile.d.ts
index dc870cb..2814f3f 100644
--- a/dist/profile.d.ts
+++ b/dist/profile.d.ts
@@ -17,8 +17,8 @@ export declare const enum ProfileType {
 }
 interface ResponseProfileParameter {
     configFile: string;
-    id: number;
-    lastUpdated: null;
+    readonly id: number;
+    readonly lastUpdated: null;
     name: string;
     profiles: null;
     secure: boolean;
@@ -29,7 +29,7 @@ export interface ResponseProfile {
     cdnName: string | null;
     description: string;
     id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     name: string;
     params?: [ResponseProfileParameter, ...ResponseProfileParameter[]];
     routingDisabled: boolean;
@@ -43,4 +43,82 @@ export interface RequestProfile {
     type: ProfileType;
 }
 export declare type Profile = RequestProfile | ResponseProfile;
+export interface RequestParameter {
+    configFile: string;
+    name: string;
+    secure: boolean;
+    value?: string | null;
+}
+export interface ResponseParameter {
+    configFile: string;
+    readonly id: number;
+    readonly lastUpdated: Date;
+    name: string;
+    profiles: Array<string> | null;
+    secure: boolean;
+    value: string;
+}
+export declare type Parameter = RequestParameter | ResponseParameter;
+export interface RequestParameterProfile {
+    paramId: number;
+    profileIds: Array<number>;
+    replace?: boolean | null;
+}
+export interface RequestParameterProfileResponse {
+    paramId: number;
+    profileIds: Array<number>;
+    replace: boolean;
+}
+export declare type ParameterProfile = RequestParameterProfile | 
RequestParameterProfileResponse;
+export interface RequestProfileParameter {
+    profileId: number;
+    paramIds: Array<number>;
+    replace?: boolean | null;
+}
+export interface RequestProfileParameterResponse {
+    profileId: number;
+    paramIds: Array<number>;
+    replace: boolean;
+}
+export declare type ProfileParameter = RequestProfileParameter | 
RequestProfileParameterResponse;
+export interface RequestProfileParameters {
+    parameterId: number;
+    profileId: number;
+}
+export interface RequestProfileParametersResponse {
+    readonly lastUpdated: null;
+    parameter: string | null;
+    parameterId: number;
+    profileId: number;
+    profile: string | null;
+}
+export interface ResponseProfileParameters {
+    readonly lastUpdated: Date;
+    profile: string;
+    parameter: number;
+}
+export declare type ProfileParameters = RequestProfileParameters | 
RequestProfileParametersResponse | ResponseProfileParameters;
+export interface ProfileImport {
+    profile: {
+        cdn: string;
+        description: string;
+        name: string;
+        type: ProfileType;
+    };
+    parameters: Array<{
+        config_file: string;
+        name: string;
+        value: string;
+    }>;
+}
+export interface ProfileExport extends ProfileImport {
+    alerts: null;
+}
+export interface ProfileCopyResponse {
+    description: string;
+    idCopyFrom: number;
+    id: number;
+    name: string;
+    profileCopyFrom: string;
+}
 export {};
diff --git a/dist/server.d.ts b/dist/server.d.ts
index da31c46..5a5f71c 100644
--- a/dist/server.d.ts
+++ b/dist/server.d.ts
@@ -1,3 +1,4 @@
+import type { Alert } from "./alert";
 export interface IPAddress {
     address: string;
     gateway: string | null;
@@ -10,7 +11,7 @@ export interface Interface {
     mtu: number | null;
     name: string;
 }
-export declare function serviceAddresses(inf: Interface | Array<IPAddress>, 
exhaustive?: boolean): [ipv4Address: IPAddress | null, ipv6Address: IPAddress | 
null];
+export declare function serviceAddresses(infs: Array<Interface>, exhaustive?: 
boolean): [ipv4Address: IPAddress | null, ipv6Address: IPAddress | null];
 export interface ResponseServer {
     cachegroup: string;
     cachegroupId: number;
@@ -27,7 +28,7 @@ export interface ResponseServer {
     iloPassword: string | null;
     iloUsername: string | null;
     interfaces: Array<Interface>;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     mgmtIpAddress: string | null;
     mgmtIpGateway: string | null;
     mgmtIpNetmask: string | null;
@@ -63,3 +64,79 @@ export interface Servercheck {
     updPending: boolean;
 }
 export declare function checkMap(srv: Servercheck): Map<string, number | 
boolean>;
+export interface RequestServercheckExtension {
+    additional_config_json?: string | null;
+    description?: string | null;
+    info_url: string;
+    isactive: 0 | 1;
+    name: string;
+    servercheck_short_name: string;
+    script_file: string;
+    type: string;
+    version: string;
+}
+export interface RequestServercheckExtensionResponse {
+    alerts: Array<Alert>;
+    supplemental: {
+        readonly id: number;
+    };
+}
+export interface ResponseServercheckExtension {
+    additional_config_json: string | null;
+    description: string | null;
+    info_url: string;
+    isactive: 0 | 1;
+    name: string;
+    servercheck_short_name: string;
+    script_file: string;
+    type: string;
+    version: string;
+}
+export declare type ServercheckExtension = RequestServercheckExtension | 
ResponseServercheckExtension;
+export interface ServerDetails {
+    cachegroup: string;
+    cdnName: string;
+    deliveryservices?: [number, ...number[]];
+    domainName: string;
+    guid: string | null;
+    hardwareInfo: unknown;
+    hostName: string;
+    httpsPort: number | null;
+    readonly id: number;
+    iloIpAddress: string;
+    iloIpGateway: string;
+    iloIpNetmask: string;
+    iloPassword: string;
+    iloUsername: string;
+    interfaces: Array<Interface>;
+    mgmtIpAddress: string;
+    mgmtIpGateway: string;
+    mgmtIpNetmask: string;
+    offlineReason: string;
+    physLocation: string;
+    profile: string;
+    profileDesc: string;
+    rack: string;
+    routerHostName: string;
+    routerPortName: string;
+    status: string;
+    tcpPort: number;
+    type: string;
+    xmppId: string;
+    xmppPasswd: string;
+}
+export interface ServerUpdateStatus {
+    host_id: number;
+    host_name: string;
+    parent_pending: boolean;
+    parent_reval_pending: boolean;
+    reval_pending: boolean;
+    status: string;
+    upd_pending: boolean;
+    use_reval_pending: boolean;
+}
+export interface ServerDeliveryServices {
+    dsIds: Array<number>;
+    serverId: number;
+    replace: boolean;
+}
diff --git a/dist/server.js b/dist/server.js
index 8811d63..8634891 100644
--- a/dist/server.js
+++ b/dist/server.js
@@ -43,8 +43,8 @@ function inexhaustiveServiceAddresses(ips) {
     }
     return [ipv4, ipv6];
 }
-export function serviceAddresses(inf, exhaustive = false) {
-    const arr = inf instanceof Array ? inf : inf.ipAddresses;
+export function serviceAddresses(infs, exhaustive = false) {
+    const arr = infs.map(inf => inf.ipAddresses).flat();
     if (exhaustive) {
         return exhaustiveServiceAddresses(arr);
     }
diff --git a/dist/stats.d.ts b/dist/stats.d.ts
index 42b2223..10d02f6 100644
--- a/dist/stats.d.ts
+++ b/dist/stats.d.ts
@@ -32,3 +32,61 @@ export interface CurrentStats {
         }
     ];
 }
+export interface CachesStats {
+    cachegroup: string;
+    connections: number;
+    healthy: boolean;
+    hostname: string;
+    ip: string | null;
+    kbps: number;
+    profile: string;
+    status: string;
+}
+export interface Health {
+    cacheGroups: Array<{
+        name: string;
+        offline: number;
+        online: number;
+    }>;
+    totalOffline: number;
+    totalOnline: number;
+}
+export interface Capacity {
+    readonly availablePercent: number;
+    readonly maintenancePercent: number;
+    readonly unavailablePercent: number;
+    readonly utilizedPercent: number;
+}
+export interface CDNDNSSECKSKKeyGenerationRequest {
+    effectiveDate?: Date | null;
+    expirationDays: number;
+}
+export interface Routing {
+    cz: number;
+    deepCz: number;
+    dsr: number;
+    err: number;
+    fed: number;
+    geo: number;
+    miss: number;
+    regionalAlternate: number;
+    regionalDenied: number;
+    staticRoute: number;
+}
+export interface RequestStatsSummary {
+    cdnName?: string | null;
+    deliveryServiceName?: string | null;
+    statName: string;
+    statValue: number;
+    summaryTime: Date;
+    statDate?: `${number}-${number}-${number}` | Date | null;
+}
+export interface ResponseStatsSummary {
+    cdnName: string;
+    deliveryServiceName: string;
+    summaryTime: Date;
+    statDate: `${number}-${number}-${number}` | null;
+    statValue: number;
+}
+export declare type StatsSummary = RequestStatsSummary | ResponseStatsSummary;
+export declare function isValidStatDate(statDate: string): statDate is 
`${number}-${number}-${number}`;
diff --git a/dist/stats.js b/dist/stats.js
index cb0ff5c..9c6bab7 100644
--- a/dist/stats.js
+++ b/dist/stats.js
@@ -1 +1,3 @@
-export {};
+export function isValidStatDate(statDate) {
+    return /^\d{4}-(0[1-9]|1[12])-([12][0-9]|3[01])$/.test(statDate);
+}
diff --git a/dist/status.d.ts b/dist/status.d.ts
index 2670e75..d4d52f9 100644
--- a/dist/status.d.ts
+++ b/dist/status.d.ts
@@ -1,7 +1,7 @@
 export interface ResponseStatus {
     description: string | null;
     id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     name: string;
 }
 export interface RequestStatus {
@@ -9,3 +9,7 @@ export interface RequestStatus {
     name: string;
 }
 export declare type Status = ResponseStatus | RequestStatus;
+export interface StatusChangeRequest {
+    offlineReason?: string | null;
+    status: string;
+}
diff --git a/dist/type.d.ts b/dist/type.d.ts
index 55d3866..3c749e2 100644
--- a/dist/type.d.ts
+++ b/dist/type.d.ts
@@ -1,7 +1,7 @@
 export interface TypeFromResponse {
     description: string;
-    id: number;
-    lastUpdated: Date;
+    readonly id: number;
+    readonly lastUpdated: Date;
     name: string;
     useInTable: string;
 }
diff --git a/dist/user.d.ts b/dist/user.d.ts
index 3bddeba..7ce5400 100644
--- a/dist/user.d.ts
+++ b/dist/user.d.ts
@@ -51,7 +51,7 @@ interface ResponseUser {
     fullName: string;
     gid: number | null;
     id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     newUser: boolean | null;
     phoneNumber: string | null;
     postalCode: string | null;
@@ -86,7 +86,7 @@ export interface ResponseCurrentUser {
     fullName: string;
     gid: number | null;
     id: number;
-    lastUpdated: Date;
+    readonly lastUpdated: Date;
     localUser: boolean;
     newUser: boolean;
     phoneNumber: string | null;
@@ -101,6 +101,7 @@ export interface ResponseCurrentUser {
     uid: number | null;
     username: string;
 }
+export declare function userEmailIsValid(email: string): email is 
`${string}@${string}.${string}`;
 export interface RequestCurrentUser {
     addressLine1?: string | null;
     addressLine2?: string | null;
@@ -123,4 +124,40 @@ export interface RequestCurrentUser {
     username?: never;
 }
 export declare type CurrentUser = ResponseCurrentUser | RequestCurrentUser;
+export interface RequestRole {
+    capabilities: Array<string>;
+    description: string;
+    name: string;
+    privLevel: number;
+}
+export interface ResponseRole extends RequestRole {
+    readonly id: number;
+}
+export declare type Role = RequestRole | ResponseRole;
+export interface RequestTenant {
+    active: boolean;
+    name: string;
+    parentId: number;
+}
+export interface RequestTenantResponse extends RequestTenant {
+    readonly id: number;
+    readonly lastUpdated: Date;
+}
+interface ResponseTenantBase {
+    active: boolean;
+    readonly id: number;
+    readonly lastUpdated: Date;
+    name: string;
+}
+interface ResponseRootTenant extends ResponseTenantBase {
+    active: true;
+    name: "root";
+    parentId: null;
+}
+interface ResponseRegularTenant extends ResponseTenantBase {
+    name: Exclude<string, "root">;
+    parentId: number;
+}
+export declare type ResponseTenant = ResponseRootTenant | 
ResponseRegularTenant;
+export declare type Tenant = ResponseTenant | RequestTenant | 
RequestTenantResponse;
 export {};
diff --git a/dist/user.js b/dist/user.js
index cb0ff5c..26251dc 100644
--- a/dist/user.js
+++ b/dist/user.js
@@ -1 +1,3 @@
-export {};
+export function userEmailIsValid(email) {
+    return /^.+@.+\..+$/.test(email);
+}
diff --git a/package.json b/package.json
index cec48de..3923e5d 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
        "name": "trafficops-types",
-       "version": "3.1.0-beta",
+       "version": "3.1.0-beta-2",
        "description": "A library for dealing with Apache Traffic Control 
objects",
        "main": "dist/index.js",
        "scripts": {
diff --git a/src/acme.ts b/src/acme.ts
index c86ffa9..0be2dcb 100644
--- a/src/acme.ts
+++ b/src/acme.ts
@@ -8,3 +8,11 @@ export interface ACMEAccount {
        provider: string;
        uri: string;
 }
+
+/**
+ * Represents a single DNS record used for completing ACME challenges.
+ */
+export interface ACMEDNSRecord {
+       fqdn: string;
+       record: string;
+}
diff --git a/src/cache.group.ts b/src/cache.group.ts
index a121c60..b221ac1 100644
--- a/src/cache.group.ts
+++ b/src/cache.group.ts
@@ -10,7 +10,7 @@ export interface ResponseASN {
         * [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;
+       readonly lastUpdated: Date;
 }
 
 /** Represents an ASN in an API request. */
@@ -87,7 +87,7 @@ interface ResponseCacheGroupBase {
        fallbacks: Array<string>;
        fallbackToClosest: boolean;
        readonly id: number;
-       lastUpdated: Date;
+       readonly lastUpdated: Date;
        latitude: number | null;
        localizationMethods: Array<LocalizationMethod>;
        longitude: number | null;
@@ -155,3 +155,55 @@ ResponseCacheGroupWithoutParentOrSecondary;
  * Refer to 
https://traffic-control-cdn.readthedocs.io/en/latest/overview/cache_groups.html
  */
 export type CacheGroup = RequestCacheGroup | ResponseCacheGroup;
+
+/**
+ * ResponseCacheGroupParameters represents a response from Traffic Ops to a
+ * request made to its /cachegroupparameters` API endpoint.
+ *
+ * @deprecated In the latest API version, there is no notion of associating a
+ * Parameter with a Cache Group.
+ */
+export interface ResponseCacheGroupParameters {
+       cachegroupParameters: Array<{
+               parameter: number;
+               readonly lastUpdated: Date;
+               /** The Name of the Cache Group associated with this Parameter. 
*/
+               cachegroup: string;
+       }>;
+}
+
+/**
+ * RequestCacheGroupParameter represents an association between a Cache Group
+ * and a Parameter as Traffic Ops requires it in requests to its API. Note that
+ * the `/cachegroupparameters` endpoint allows the request body to either be
+ * one of these structures, or an array thereof.
+ *
+ * This is also the type of a response from Traffic Ops to the request that
+ * passed this structure for the purposes of creating an association between a
+ * Parameter and a Cache Group.
+ *
+ * @deprecated In the latest API version, there is no notion of associating a
+ * Parameter with a Cache Group.
+ */
+export interface RequestCacheGroupParameter {
+       cacheGroupId: number;
+       parameterId: number;
+}
+
+/**
+ * Represents a request to assign servers within a Cache Group to a specified
+ * set of Delivery Services.
+ */
+export interface CacheGroupDeliveryServiceAssignmentRequest {
+       deliveryServices: Array<number>;
+}
+
+/**
+ * Represents a response from the Traffic Ops API to a request to associate the
+ * servers of a Cache Group with a set of Delivery Services.
+ */
+export interface CacheGroupDeliveryServiceAssignmentResponse {
+       deliveryServices: Array<number>;
+       readonly id: number;
+       serverNames: Array<string>;
+}
diff --git a/src/cdn.ts b/src/cdn.ts
index c7d5220..938eed8 100644
--- a/src/cdn.ts
+++ b/src/cdn.ts
@@ -17,9 +17,21 @@ export interface ResponseCDN {
        dnssecEnabled: boolean;
        domainName: string;
        readonly id: number;
-       lastUpdated: Date;
+       readonly lastUpdated: Date;
        name: string;
 }
 
 /** Represents a CDN. */
 export type CDN = RequestCDN | ResponseCDN;
+
+/**
+ * Represents an association between a CDN's DNS domain and the Profile of the
+ * Traffic Router(s) that service it.
+ */
+export interface CDNDomain {
+       domainName: string;
+       profileId: number;
+       parameterId: number;
+       profileName: string;
+       profileDescription: string;
+}
diff --git a/src/delivery.service.ts b/src/delivery.service.ts
index 7ebd6d0..0e910eb 100644
--- a/src/delivery.service.ts
+++ b/src/delivery.service.ts
@@ -554,7 +554,7 @@ interface ResponseDeliveryServiceBase {
        ipv6RoutingEnabled: boolean;
        lastHeaderRewrite: string | null;
        /** When the Delivery Service was last updated via the API. */
-       lastUpdated: Date;
+       readonly lastUpdated: Date;
        /** Whether or not logging should be enabled for the Delivery Service. 
*/
        logsEnabled: boolean;
        /** A textual description of arbitrary length. */
@@ -731,26 +731,221 @@ export function bypassable(ds: DeliveryService): boolean 
{
 }
 
 /**
- * DSCapacity represents a response from the API to a request for the capacity
- * of a Delivery Service.
+ * Represents a Delivery Service "Regular Expression" as Traffic Ops requires 
it
+ * in requests.
  */
-export interface DSCapacity {
-       availablePercent: number;
-       maintenancePercent: number;
-       unavailablePercent: number;
-       utilizedPercent: number;
+export interface RequestDeliveryServiceRegexp {
+       pattern: string;
+       setNumber: number;
+       type: number;
 }
 
 /**
- * DSHealth represents a response from the API to a request for the health of a
- * Delivery Service.
+ * Represents a Delivery Service "Regular Expression" as Traffic Ops presents 
it
+ * in responses.
  */
-export interface DSHealth {
-       cachegroups: Array<{
-               name: string;
-               offline: number;
-               online: number;
+export interface ResponseDeliveryServiceRegexp {
+       readonly id: number;
+       pattern: string;
+       setNumber: number;
+       type: number;
+       typeName: string;
+}
+
+/** Represents a Delivery Service "Regular Expression" in an arbitrary 
context. */
+export type DeliveryServiceRegexp = RequestDeliveryServiceRegexp | 
ResponseDeliveryServiceRegexp;
+
+/**
+ * Represents the Delivery Service "Regular Expressions" of a Delivery Service
+ * as they appear in responses from the Traffic Ops API's
+ * `/deliveryservices_regexes` endpoint.
+ */
+export interface DeliveryServicesRegexps {
+       /** The Delivery Service's XMLID. */
+       dsName: string;
+       regexes: Array<{
+               pattern: string;
+               setNumber: number;
+               type: string;
        }>;
-       totalOnline: number;
-       totalOffline: number;
 }
+
+/**
+ * Represents a request to update the "safe" fields of a Delivery Service - 
i.e.
+ * the ones that are modifiable through the `/deliveryservices/{{ID}}/safe`
+ * endpoint of the Traffic Ops API.
+ */
+export interface DSSafeUpdateRequest {
+       displayName: string;
+       infoUrl?: string | null;
+       longDesc?: string | null;
+       /** @deprecated This has been removed in the latest API version. */
+       longDesc1?: string | null;
+}
+
+/**
+ * Represents a request to associate zero or more servers with a Delivery
+ * Service.
+ *
+ * This is redundant with {@link RequestDeliveryServiceServer}, so
+ * applications are recommended to pick one API endpoint to use for such
+ * assignments, which will determine the representation used. Generally it 
boils
+ * down to whether you'd rather use hostnames (which can't be guaranteed to be
+ * unique to a server so they may be a bad choice!) and XMLIDs or numeric IDs 
to
+ * identify servers and Delivery Services.
+ */
+export interface RequestDeliveryServicesServers {
+       serverNames: Array<string>;
+}
+
+/**
+ * Represents a response from Traffic Ops to a request to associate zero or 
more
+ * servers with a Delivery Service.
+ *
+ * This is redundant with {@link ResponseDeliveryServiceServer}, so
+ * applications are recommended to pick one API endpoint to use for such
+ * assignments, which will determine the representation used. Generally it 
boils
+ * down to whether you'd rather use hostnames (which can't be guaranteed to be
+ * unique to a server so they may be a bad choice!) and XMLIDs or numeric IDs 
to
+ * identify servers and Delivery Services.
+ */
+export interface ResponseDeliveryServicesServers {
+       serverNames: Array<string>;
+       xmlId: string;
+}
+
+/**
+ * Represents a request to associate a Delivery Service with zero or more
+ * servers as Traffic Ops requires it in requests to its
+ * `/deliveryserviceserver` API endpoint.
+ *
+ * This is redundant with {@link RequestDeliveryServicesServers}, so
+ * applications are recommended to pick one API endpoint to use for such
+ * assignments, which will determine the representation used. Generally it 
boils
+ * down to whether you'd rather use hostnames (which can't be guaranteed to be
+ * unique to a server so they may be a bad choice!) and XMLIDs or numeric IDs 
to
+ * identify servers and Delivery Services.
+ */
+export interface RequestDeliveryServiceServer {
+       dsId: number;
+       /** @default false */
+       replace?: boolean | null;
+       /** @default [] */
+       servers?: Array<number> | null;
+}
+
+/**
+ * Represents a single association shown in responses to GET requests made to
+ * `/deliveryserviceserver` endpoint of the Traffic Ops API.
+ *
+ * This is redundant with {@link ResponseDeliveryServicesServers}, so
+ * applications are recommended to pick one API endpoint to use for such
+ * assignments, which will determine the representation used. Generally it 
boils
+ * down to whether you'd rather use hostnames (which can't be guaranteed to be
+ * unique to a server so they may be a bad choice!) and XMLIDs or numeric IDs 
to
+ * identify servers and Delivery Services.
+ */
+export interface ResponseDeliveryServiceServer {
+       deliveryService: number;
+       readonly lastUpdated: Date;
+       server: number;
+}
+
+/**
+ * Represents a Service Category as Traffic Ops requires it in requests.
+ */
+export interface RequestServiceCategory {
+       name: string;
+}
+
+/**
+ * Represents a Service Category as Traffic Ops presents it in responses.
+ */
+export interface ResponseServiceCategory {
+       readonly lastUpdated: Date;
+       name: string;
+}
+
+/**
+ * Service Categories are used to group Delivery Services for the purposes of
+ * metrics and analytics. Cache servers will add the value of a Delivery
+ * Service's Service Category as the `X-CDN-SVC` HTTP Header in their 
downstream
+ * responses.
+ */
+export type ServiceCategory = RequestServiceCategory | ResponseServiceCategory;
+
+/**
+ * Represents a Static DNS Entry as Traffic Ops requires it in requests.
+ */
+export interface RequestStaticDNSEntry {
+       address: string;
+       /** @default null */
+       cachegroupId?: number | null;
+       deliveryserviceId: number;
+       host: string;
+       /** In seconds */
+       ttl: number;
+       typeId: number;
+}
+
+/**
+ * A response to a {@link RequestStaticDNSEntry}.
+ */
+export interface RequestStaticDNSEntryResponse {
+       address: string;
+       cachegroupId: number | null;
+       cachegroup: string | null;
+       deliveryserviceId: number;
+       deliveryservice: string | null;
+       host: string;
+       readonly id: number;
+       readonly lastUpdated: Date;
+       /** In seconds */
+       ttl: number;
+       type: string;
+       typeId: number;
+}
+
+/**
+ * All of the properties common to Static DNS Entries as presented in 
responses.
+ */
+interface ResponseStaticDNSEntryBase {
+       address: string;
+       deliveryserviceId: number;
+       deliveryservice: string;
+       host: string;
+       readonly id: number;
+       readonly lastUpdated: Date;
+       /** In seconds */
+       ttl: number;
+       type: string;
+       typeId: number;
+}
+
+/**
+ * Represents a Static DNS Entry with an associated Cache Group as Traffic Ops
+ * presents it in responses.
+ */
+interface ResponseStaticDNSEntryWithCacheGroup extends 
ResponseStaticDNSEntryBase {
+       cachegroupId: number;
+       cachegroup: string;
+}
+
+/**
+ * Represents a Static DNS Entry without an associated Cache Group as Traffic
+ * Ops presents it in responses.
+ */
+interface ResponseStaticDNSEntryWithoutCacheGroup extends 
ResponseStaticDNSEntryBase {
+       cachegroupId: null;
+       cachegroup: null;
+}
+
+/**
+ * Represents a Static DNS Entry as Traffic Ops presents it in responses.
+ */
+export type ResponseStaticDNSEntry = ResponseStaticDNSEntryWithCacheGroup | 
ResponseStaticDNSEntryWithoutCacheGroup;
+
+/**
+ * A Static DNS Entry represents a custom DNS record for a Delivery Service.
+ */
+export type StaticDNSEntry = RequestStaticDNSEntry | 
RequestStaticDNSEntryResponse | ResponseStaticDNSEntry;
diff --git a/src/division.ts b/src/division.ts
index cdc25e0..4a9e2c6 100644
--- a/src/division.ts
+++ b/src/division.ts
@@ -10,7 +10,7 @@ export interface RequestDivision {
  */
 export interface ResponseDivision {
        readonly id: number;
-       lastUpdated: Date;
+       readonly lastUpdated: Date;
        name: string;
 }
 
@@ -32,7 +32,7 @@ export interface ResponseRegion {
        division: number;
        divisionName: string;
        readonly id: number;
-       lastUpdated: Date;
+       readonly lastUpdated: Date;
        name: string;
 }
 
diff --git a/src/index.ts b/src/index.ts
index c1edef1..8b4549c 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -2,21 +2,33 @@ export * from "./about";
 export * from "./acme";
 export * from "./alert";
 export * from "./cache.group";
+export * from "./capability";
 export * from "./cdn";
+export * from "./coordinate";
+export * from "./delivery.service.request";
 export * from "./delivery.service";
 export * from "./division";
+export * from "./dnssec";
+export * from "./federation";
 export * from "./invalidation";
 export * from "./iso";
 export * from "./login";
 export * from "./logs";
-export * from "./parameter";
+export * from "./origin";
 export * from "./physical.location";
 export * from "./plugin";
 export * from "./profile";
+export * from "./router";
+export * from "./server.capability";
 export * from "./server";
+export * from "./snap.and.queue";
+export * from "./ssl";
 export * from "./stats";
 export * from "./status";
+export * from "./steering";
+export * from "./topology";
 export * from "./type";
+export * from "./uri.signing";
 export * from "./user";
 export * from "./vault";
 
@@ -58,10 +70,17 @@ export const VERSION: VersionType = {
 /**
  * (Nearly) All responses from the Traffic Ops API conform to this interface.
  */
-export interface APIResponse<T> {
+export interface APISuccessResponse<T> {
+       /** Any and all Alerts that may accompany the response. */
        alerts?: Array<Alert>;
+       /** The actual response object. */
        response: T;
+       /** An object containing summary statistics. */
        summary?: {
+               /**
+                * The total number of results that *would have* been returned 
if not
+                * for pagination controls used in the request's query string.
+                */
                count: number;
        };
 }
diff --git a/src/logs.ts b/src/logs.ts
index f467162..5aecd12 100644
--- a/src/logs.ts
+++ b/src/logs.ts
@@ -10,7 +10,7 @@ export interface Log {
         * [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;
+       readonly lastUpdated: Date;
        /**
         * @deprecated This field has no further use, and is subject to removal 
in
         * the future.
diff --git a/src/parameter.ts b/src/parameter.ts
deleted file mode 100644
index 0e749cd..0000000
--- a/src/parameter.ts
+++ /dev/null
@@ -1,36 +0,0 @@
-/**
- * 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
index 6eb4b45..729f59f 100644
--- a/src/physical.location.ts
+++ b/src/physical.location.ts
@@ -19,7 +19,7 @@ export interface ResponsePhysicalLocation {
         * [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;
+       readonly lastUpdated: Date;
        /** The name of the Physical Location. */
        name: string;
        /** A phone number where the the Physical Location’s poc might be 
reached. */
diff --git a/src/profile.ts b/src/profile.ts
index 803dd58..facb8e5 100644
--- a/src/profile.ts
+++ b/src/profile.ts
@@ -42,11 +42,13 @@ export const enum ProfileType {
 /**
  * In responses from certain endpoints, Profiles include these custom
  * representations of their assigned Parameters.
+ *
+ * This is **not** the response to a {@link RequestProfileParameter}.
  */
 interface ResponseProfileParameter {
        configFile: string;
-       id: number;
-       lastUpdated: null;
+       readonly id: number;
+       readonly lastUpdated: null;
        name: string;
        profiles: null;
        secure: boolean;
@@ -69,7 +71,7 @@ export interface ResponseProfile {
         * [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;
+       readonly lastUpdated: Date;
        name: string;
        /**
         * This only appears when a response array contains exactly one Profile,
@@ -94,3 +96,194 @@ export interface RequestProfile {
  * request to or a response from the Traffic Ops API.
  */
 export type Profile = RequestProfile | ResponseProfile;
+
+/**
+ * A RequestParameter is a Parameter as given in PUT and POST requests to
+ * /parameters.
+ */
+export interface RequestParameter {
+       configFile: string;
+       name: string;
+       secure: boolean;
+       /** @default "" */
+       value?: string | null;
+}
+
+/**
+ * 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.
+        */
+       readonly lastUpdated: Date;
+       name: string;
+       profiles: Array<string> | null;
+       secure: boolean;
+       value: string;
+}
+
+/**
+ * A Parameter generically represents a Parameter, either in request format or
+ * response format.
+ */
+export type Parameter = RequestParameter | ResponseParameter;
+
+/**
+ * Represents a request to associate a Parameter with zero or more Profiles.
+ */
+export interface RequestParameterProfile {
+       paramId: number;
+       profileIds: Array<number>;
+       /** @default false */
+       replace?: boolean | null;
+}
+
+/**
+ * The response to a {@link RequestParameterProfile}.
+ */
+export interface RequestParameterProfileResponse {
+       paramId: number;
+       profileIds: Array<number>;
+       replace: boolean;
+}
+
+/**
+ * A ProfileParameter represents the association of a Parameter to zero or more
+ * Profiles.
+ *
+ * This is redundant with {@link ProfileParameter} and with
+ * {@link ProfileParameters}. It is suggested that clients choose which API
+ * endpoint they'd like to use, which will dictate which of these
+ * representations is appropriate.
+ */
+export type ParameterProfile = RequestParameterProfile | 
RequestParameterProfileResponse;
+
+/**
+ * Represents a request to associate a Profile with zero or more Parameters.
+ */
+export interface RequestProfileParameter {
+       profileId: number;
+       paramIds: Array<number>;
+       /** @default false */
+       replace?: boolean | null;
+}
+
+/**
+ * The response to a {@link RequestProfileParameter}.
+ */
+export interface RequestProfileParameterResponse {
+       profileId: number;
+       paramIds: Array<number>;
+       replace: boolean;
+}
+
+/**
+ * A ProfileParameter represents the association of a Profile to zero or more
+ * Parameters.
+ *
+ * This is redundant with {@link ProfileParameters} and with
+ * {@link ParameterProfile}. It is suggested that clients choose which API
+ * endpoint they'd like to use, which will dictate which of these
+ * representations is appropriate.
+ */
+export type ProfileParameter = RequestProfileParameter | 
RequestProfileParameterResponse;
+
+/**
+ * Represents an association between a single Profile and a single Parameter, 
as
+ * required by Traffic Ops in requests to its `/profileparameters` API 
endpoint.
+ */
+export interface RequestProfileParameters {
+       parameterId: number;
+       profileId: number;
+}
+
+/**
+ * The response to a {@link RequestProfileParameters}.
+ */
+export interface RequestProfileParametersResponse {
+       /**
+        * @deprecated This is always `null` and has no practical use, so it'll
+        * probably wind up getting removed at some point in the future.
+        */
+       readonly lastUpdated: null;
+       /** @deprecated This value has unknown meaning and no real use. */
+       parameter: string | null;
+       parameterId: number;
+       profileId: number;
+       profile: string | null;
+}
+
+/**
+ * Represents an association between a single Profile and a single Parameter, 
as
+ * presented by Traffic Ops in responses to GET requests made to the
+ * `/profileparameters` endpoint of its API.
+ */
+export interface ResponseProfileParameters {
+       readonly lastUpdated: Date;
+       profile: string;
+       parameter: number;
+}
+
+/**
+ * A ProfileParameters represents the association between a Profile and a
+ * Parameter.
+ *
+ * This is redundant with {@link ProfileParameter} and with
+ * {@link ParameterProfile}. It is suggested that clients choose which API
+ * endpoint they'd like to use, which will dictate which of these
+ * representations is appropriate.
+ */
+export type ProfileParameters = RequestProfileParameters | 
RequestProfileParametersResponse | ResponseProfileParameters;
+
+/**
+ * A ProfileImport is the format required by Traffic Ops to import Profiles
+ * through its `/profiles/import` endpoint.
+ */
+export interface ProfileImport {
+       profile: {
+               cdn: string;
+               description: string;
+               name: string;
+               type: ProfileType;
+       };
+       parameters: Array<{
+               // eslint-disable-next-line @typescript-eslint/naming-convention
+               config_file: string;
+               name: string;
+               value: string;
+       }>;
+}
+
+/**
+ * An exported Profile is enough information to reconstruct the Profile at a
+ * later time and/or in a different ATC system using the `/profiles/import` API
+ * endpoint.
+ */
+export interface ProfileExport extends ProfileImport{
+       /**
+        * @deprecated This field exists by mistake and will be removed in the
+        * future. Refer to
+        * {@link https://github.com/apache/trafficcontrol/issues/6797 #6797} 
for
+        * details/progress updates.
+        */
+        alerts: null;
+}
+
+/**
+ * This is a response from Traffic Ops to a request to copy a Profile.
+ */
+export interface ProfileCopyResponse {
+       description: string;
+       idCopyFrom: number;
+       /** The ID of the newly created copy Profile. */
+       id: number;
+       name: string;
+       profileCopyFrom: string;
+}
diff --git a/src/server.ts b/src/server.ts
index f06d9ea..6c91136 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -2,6 +2,8 @@
  * This file is for modeling and functionality related to Server objects
  */
 
+import type { Alert } from "./alert";
+
 /** IPAddress is a single IP address of a single network interface of a 
server. */
 export interface IPAddress {
        /** The actual IP address. */
@@ -90,8 +92,7 @@ function inexhaustiveServiceAddresses(ips: Array<IPAddress>): 
[IPAddress | null,
  * 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 infs The interfaces 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
@@ -106,8 +107,8 @@ function inexhaustiveServiceAddresses(ips: 
Array<IPAddress>): [IPAddress | null,
  * @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;
+export function serviceAddresses(infs: Array<Interface>, exhaustive = false): 
[ipv4Address: IPAddress | null, ipv6Address: IPAddress | null] {
+       const arr = infs.map(inf=>inf.ipAddresses).flat();
        if (exhaustive) {
                return exhaustiveServiceAddresses(arr);
        }
@@ -169,7 +170,7 @@ export interface ResponseServer {
        /** The Server's network interfaces. */
        interfaces: Array<Interface>;
        /** The date/time at which the Server was last updated. */
-       lastUpdated: Date;
+       readonly 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. 
*/
@@ -299,3 +300,127 @@ export function checkMap(srv: Servercheck): Map<string, 
number | boolean> {
        }
        return ret;
 }
+
+/**
+ * A Servercheck Extension as Traffic Ops requires it in requests.
+ */
+export interface RequestServercheckExtension {
+       /* eslint-disable @typescript-eslint/naming-convention */
+       /** @default null */
+       additional_config_json?: string | null;
+       /** @default null */
+       description?: string | null;
+       info_url: string;
+       isactive: 0 | 1;
+       name: string;
+       servercheck_short_name: string;
+       script_file: string;
+       type: string;
+       version: string;
+       /* eslint-enable @typescript-eslint/naming-convention */
+}
+
+/**
+ * Traffic Ops's non-standard response to a {@link 
RequestServercheckExtension}.
+ */
+export interface RequestServercheckExtensionResponse {
+       alerts: Array<Alert>;
+       supplemental: {
+               readonly id: number;
+       };
+}
+
+/**
+ * Represents a Servercheck Extension as presented by Traffic Ops in responses.
+ */
+export interface ResponseServercheckExtension {
+       /* eslint-disable @typescript-eslint/naming-convention */
+       additional_config_json: string | null;
+       description: string | null;
+       info_url: string;
+       isactive: 0 | 1;
+       name: string;
+       servercheck_short_name: string;
+       script_file: string;
+       type: string;
+       version: string;
+       /* eslint-enable @typescript-eslint/naming-convention */
+}
+
+/**
+ * A Servercheck extension is a "check"-type extension to Traffic Ops that
+ * provides servercheck data for later retrieval through the `/servercheck`
+ * endpoint.
+ */
+export type ServercheckExtension = RequestServercheckExtension | 
ResponseServercheckExtension;
+
+/**
+ * @deprecated This gives no useful information that an {@link Server} doesn't,
+ * so there's no reason to use it.
+ */
+export interface ServerDetails  {
+       cachegroup: string;
+       cdnName: string;
+       deliveryservices?: [number, ...number[]];
+       domainName: string;
+       /** @deprecated this has no known purpose, and you shouldn't invent 
one. */
+       guid: string | null;
+       /**
+        * @deprecated This field is legacy and cannot be populated, and should 
be
+        * removed soon (if this whole type isn't).
+        */
+       hardwareInfo: unknown;
+       hostName: string;
+       httpsPort: number | null;
+       readonly id: number;
+       iloIpAddress: string;
+       iloIpGateway: string;
+       iloIpNetmask: string;
+       iloPassword: string;
+       iloUsername: string;
+       interfaces: Array<Interface>;
+       mgmtIpAddress: string;
+       mgmtIpGateway: string;
+       mgmtIpNetmask: string;
+       offlineReason: string;
+       physLocation: string;
+       profile: string;
+       /** @deprecated This has been removed from the latest API version. */
+       profileDesc: string;
+       /** @deprecated this has no known purpose, and you shouldn't invent 
one. */
+       rack: string;
+       routerHostName: string;
+       routerPortName: string;
+       status: string;
+       tcpPort: number;
+       type: string;
+       xmppId: string;
+       xmppPasswd: string;
+}
+
+/**
+ * Represents the various statuses of a Server to give a complete view of its
+ * current state.
+ */
+export interface ServerUpdateStatus {
+       /* eslint-disable @typescript-eslint/naming-convention */
+       host_id: number;
+       host_name: string;
+       parent_pending: boolean;
+       parent_reval_pending: boolean;
+       reval_pending: boolean;
+       status: string;
+       upd_pending: boolean;
+       use_reval_pending: boolean;
+       /* eslint-enable @typescript-eslint/naming-convention */
+}
+
+/**
+ * Represents a response from Traffic Ops to a request to associate zero or 
more
+ * Delivery Services with a server.
+ */
+export interface ServerDeliveryServices {
+       dsIds: Array<number>;
+       serverId: number;
+       replace: boolean;
+}
diff --git a/src/stats.ts b/src/stats.ts
index 3d0752e..507ce73 100644
--- a/src/stats.ts
+++ b/src/stats.ts
@@ -65,3 +65,118 @@ export interface CurrentStats {
                }
        ];
 }
+
+/**
+ * Not to be confused with {@link CacheStats}, CachesStats represents a set of
+ * some summary statistics about all cache servers throughout Traffic Ops.
+ */
+export interface CachesStats {
+       cachegroup: string;
+       connections: number;
+       healthy: boolean;
+       hostname: string;
+       /**
+        * For a single CachesStats, this is the service IPv4 address of the 
server
+        * (or `null` if it only has an IPv6 service address), and for aggregate
+        * CachesStats items (i.e. where one or more of `cachegroup`, 
`hostname`,
+        * `profile`, and `status`  is/are the special, reserved name "ALL") it 
is
+        * `null`.
+        */
+       ip: string | null;
+       kbps: number;
+       profile: string;
+       status: string;
+}
+
+/**
+ * This structure gets its name from the endpoint whose response it models:
+ * `/cdns/health` and/or `/deliveryservices/{{ID}}/health`, but its actual
+ * purpose is to represent cache health as an aggregate across *Cache Groups*
+ * within the specified CDN or Delivery Service.
+ */
+export interface Health {
+       cacheGroups: Array<{
+               name: string;
+               offline: number;
+               online: number;
+       }>;
+       totalOffline: number;
+       totalOnline: number;
+}
+
+/**
+ * Represents the total "capacity" of a Delivery Service or CDN in terms of
+ * cache servers and their ability to perform useful functions for the CDN.
+ */
+export interface Capacity {
+       readonly availablePercent: number;
+       readonly maintenancePercent: number;
+       readonly unavailablePercent: number;
+       readonly utilizedPercent: number;
+}
+
+/** Represents a request to generate a DNSSEC KSK Key for a CDN. */
+export interface CDNDNSSECKSKKeyGenerationRequest {
+       /** @default Date.now() */
+       effectiveDate?: Date | null;
+       expirationDays: number;
+}
+
+/**
+ * Represents the aggregated routing percentages across all CDNs, or a
+ * particular Delivery Service.
+ */
+export interface Routing {
+       cz: number;
+       deepCz: number;
+       dsr: number;
+       err: number;
+       fed: number;
+       geo: number;
+       miss: number;
+       regionalAlternate: number;
+       regionalDenied: number;
+       staticRoute: number;
+}
+
+/**
+ * Represents a stats summary as Traffic Ops requires it in requests.
+ */
+export interface RequestStatsSummary {
+       /** @default "all" */
+       cdnName?: string | null;
+       /** @default "all" */
+       deliveryServiceName?: string | null;
+       statName: string;
+       statValue: number;
+       summaryTime: Date;
+       statDate?: `${number}-${number}-${number}` | Date | null;
+}
+
+/**
+ * Represents a stats summary as Traffic Ops presents it in responses.
+ */
+export interface ResponseStatsSummary {
+       cdnName: string;
+       deliveryServiceName: string;
+       summaryTime: Date;
+       statDate: `${number}-${number}-${number}` | null;
+       statValue: number;
+}
+
+/**
+ * A StatsSummary is a manually created report of some custom statistic that 
can
+ * be retrieved later.
+ */
+export type StatsSummary = RequestStatsSummary | ResponseStatsSummary;
+
+/**
+ * Checks if a given string is valid as a "stat date".
+ *
+ * @param statDate The string to test.
+ * @returns Whether `statDate` is a valid `statDate` property for an
+ * {@link StatsSummary} string.
+ */
+export function isValidStatDate(statDate: string): statDate is 
`${number}-${number}-${number}` {
+       return /^\d{4}-(0[1-9]|1[12])-([12][0-9]|3[01])$/.test(statDate);
+}
diff --git a/src/status.ts b/src/status.ts
index dbc025a..339596b 100644
--- a/src/status.ts
+++ b/src/status.ts
@@ -8,7 +8,7 @@ export interface ResponseStatus {
         * [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;
+       readonly lastUpdated: Date;
        name: string;
 }
 
@@ -23,3 +23,14 @@ export interface RequestStatus {
  * response.
  */
 export type Status = ResponseStatus | RequestStatus;
+
+/** Represents a request to change a server's Status. */
+export interface StatusChangeRequest {
+       /**
+        * This is required to be a non-empty string if and only if `status` is
+        * `ADMIN_DOWN` or `OFFLINE`.
+        * @default ""
+        */
+       offlineReason?: string | null;
+       status: string;
+}
diff --git a/src/type.ts b/src/type.ts
index 7b11fa4..4eb59bb 100644
--- a/src/type.ts
+++ b/src/type.ts
@@ -6,14 +6,14 @@
  */
 export interface TypeFromResponse {
        description: string;
-       id: 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;
+       readonly lastUpdated: Date;
        name: string;
        useInTable: string;
 }
@@ -22,6 +22,9 @@ export interface TypeFromResponse {
 export interface RequestType {
        description: string;
        name: string;
+       /**
+        * In practice this is limited to "server" and "cachegroup".
+        */
        useInTable: string;
 }
 
diff --git a/src/user.ts b/src/user.ts
index 7950f25..dd810ff 100644
--- a/src/user.ts
+++ b/src/user.ts
@@ -80,7 +80,7 @@ interface ResponseUser {
         * [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;
+       readonly lastUpdated: Date;
        newUser: boolean | null;
        phoneNumber: string | null;
        postalCode: string | null;
@@ -145,7 +145,7 @@ export interface ResponseCurrentUser {
         * [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;
+       readonly lastUpdated: Date;
        localUser: boolean;
        newUser: boolean;
        phoneNumber: string | null;
@@ -161,6 +161,16 @@ export interface ResponseCurrentUser {
        username: string;
 }
 
+/**
+ * Checks if a provided user email is valid.
+ *
+ * @param email The email to check.
+ * @returns `true` if `email` is valid, `false` otherwise.
+ */
+export function userEmailIsValid(email: string): email is 
`${string}@${string}.${string}` {
+       return /^.+@.+\..+$/.test(email);
+}
+
 /**
  * Currently, a request to /user/current has no properties. This bug is tracked
  * by apache/trafficcontrol#6367.
@@ -227,6 +237,86 @@ export interface RequestCurrentUser {
 /**
  * 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.
+ * key ways as tracked by
+ * {@link https://github.com/apache/trafficcontrol/issues/6299 #6299}.
  */
 export type CurrentUser = ResponseCurrentUser | RequestCurrentUser;
+
+/**
+ * Represents a Role as Traffic Ops requires it in requests.
+ */
+export interface RequestRole {
+       capabilities: Array<string>;
+       description: string;
+       name: string;
+       privLevel: number;
+}
+
+/**
+ * Represents a Role as Traffic Ops presents it in responses.
+ */
+export interface ResponseRole extends RequestRole {
+       readonly id: number;
+}
+
+/**
+ * A Role encapsulates the permissions to perform operations through the 
Traffic
+ * Ops API.
+ */
+export type Role = RequestRole | ResponseRole;
+
+/**
+ * Represents a Tenant as Traffic Ops requires it in requests.
+ */
+export interface RequestTenant {
+       active: boolean;
+       name: string;
+       parentId: number;
+}
+
+/**
+ * A response to a {@link RequestTenant}.
+ */
+export interface RequestTenantResponse extends RequestTenant {
+       readonly id: number;
+       readonly lastUpdated: Date;
+}
+
+/**
+ * Properties common to Tenants in (almost) all responses.
+ */
+interface ResponseTenantBase {
+       active: boolean;
+       readonly id: number;
+       readonly lastUpdated: Date;
+       name: string;
+}
+
+/**
+ * The root Tenant - it's the only one allowed to have a `null` `parentId`.
+ */
+interface ResponseRootTenant extends ResponseTenantBase {
+       active: true;
+       name: "root";
+       parentId: null;
+}
+
+/**
+ * A regular Tenant - its `parentId` must not be `null`.
+ */
+interface ResponseRegularTenant extends ResponseTenantBase {
+       // I know this doesn't work, but I'm doing it anyway.
+       name: Exclude<string, "root">;
+       parentId: number;
+}
+
+/**
+ * Represents a Tenant as Traffic Ops presents it in responses.
+ */
+export type ResponseTenant = ResponseRootTenant | ResponseRegularTenant;
+
+/**
+ * A Tenant is a grouping of users to manage a shared set of CDN configuration,
+ * most frequently one or more Delivery Services.
+ */
+export type Tenant = ResponseTenant | RequestTenant | RequestTenantResponse;

Reply via email to