Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zendesk ZAF typings #7

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5,338 changes: 5,338 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions packages/zendesk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,17 @@
"description": "",
"main": "index.js",
"scripts": {
"build": "node scripts/build.mjs"
"build": "node scripts/build.mjs",
"test": "npx tsd tsd_project"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"fs-extra": "^10.1.0"
"fs-extra": "^10.1.0",
"tsd": "^0.25.0"
},
"dependencies": {
"typescript": "^4.9.4"
}
}
30 changes: 7 additions & 23 deletions packages/zendesk/sdk/index.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,17 @@
// The ZAFClient is injected in the index.html file when built / served.
// See docs for help regarding the ZAFClient: https://developer.zendesk.com/apps/docs/developer-guide/getting_started

interface IMetadata<T> {
appId: number;
installationId: number;
name: string;
plan: {
name: string;
};
settings?: T
}

interface IClient {
invoke: (cmd: string, arg: any) => void;
get: (getter: string) => any;
metadata: <U>() => IMetadata<U>;
request: <U>(data: Object) => Promise<U>;
on: (eventName: string, listener: (...args: any) => any) => void;
}
import type { ZafClient } from "./types/client/client";

declare global {
interface Window {
ZAFClient: {
init: () => IClient
}
}
interface Window {
ZAFClient: {
init: () => ZafClient;
};
}
}

let zafClient: IClient;
let zafClient: ZafClient;
if (typeof window.ZAFClient === "undefined") {
// eslint-disable-line no-undef
throw new Error("ZAFClient cannot run outside Zendesk");
Expand Down
5 changes: 5 additions & 0 deletions packages/zendesk/sdk/types/apps/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Support } from "./support";

export type Apps = {
Support: Support;
};
5 changes: 5 additions & 0 deletions packages/zendesk/sdk/types/apps/support/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Locations } from "./locations";

export type Support = {
Locations: Locations;
};
7 changes: 7 additions & 0 deletions packages/zendesk/sdk/types/apps/support/locations/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { NewTicketSidebar } from "./new_ticket_sidebar";
import { TicketSidebar } from "./ticket_sidebar";

export type Locations = {
["ticket_sidebar"]: TicketSidebar;
["new_ticket_sidebar"]: NewTicketSidebar;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Ticket } from "../objects/ticket";

export type NewTicketSidebar = {
["ticket"]: Ticket;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export type Group = {
id: number;
name: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import { Group } from "../group";
import { User } from "../user";

export type Ticket = {
createdAt: string;
description: string;
externalId: null | unknown;
emailCcs: unknown;
id: number;
isNew: boolean;
postSaveAction: string; // string enum to find
priority: string; // string enum to find
recipient: unknown;
sharedWith: unknown;
status: string; // string enum to find
subject: string;
tags: string[];
type: string; // string enum to find
updatedAt: string;
viewers: unknown;
brand: unknown;
comment: unknown;
form: unknown;
editor: unknown;
organization: unknown;
via: unknown;
conversation: unknown;
collaborators: unknown;
followers: unknown;
assignee: {
group: Group;
user: User;
};
requester: User;
comments: unknown;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
type IdentityType =
| "email"
| "twitter"
| "facebook"
| "google"
| "agent_forwarding"
| "phone_number";

export type Identity<I = "email"> = {
id: number;
type: IdentityType;
value: string;
verified: boolean;
primary: boolean;
userId: number;
undeliverableCount: number;
deliverableState: I extends "email" ? "deliverable" | "undeliverable" : null;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Group } from "../group";
import { Identity } from "./identities";
import { Organization } from "./organizations";
import { Timezone } from "./timezone";

type UserRole = "end-user" | "agent" | "admin";

export type User = {
alias: string | null;
avatarUrl: string;
details: string | null;
email: string;
externalId: string | null;
id: number;
identities: Identity[];
isSystemUser: boolean;
locale: string;
name: string;
notes: null;
role: UserRole;
signature: string | null;
tags: [];
timeZone: Timezone;
groups: Group[];
organizations: Organization[];
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// TODO add support for custom fields

import { Group } from "../../group";

// TODO incomplete!
type OrganizationField = {
name: string;
isVisible: boolean;
}

export type Organization = {
details: string | null;
domains: string;
externalId: string | null;
groups: Group;
id: number;
name: string;
notes: string | null;
sharedComments: boolean;
sharedTickets: boolean;
tags: string[];
organizationFields: OrganizationField[];
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export type Timezone = {
name: string;
ianaName: string;
offset: number;
formattedOffset: string;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { Ticket } from "../objects/ticket";

export type TicketSidebar = {
["ticket"]: Ticket;
};
12 changes: 12 additions & 0 deletions packages/zendesk/sdk/types/client/client.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { expectType } from "tsd";

import zafClient from "../..";

// wrpapper around tests to be abe to use async/await
const ClientGet = async () => {
const idData = await zafClient.get("ticket.id");
expectType<number>(idData["ticket.id"]);

const arrayOfTags = await zafClient.get("ticket.tags");
expectType<string[]>(arrayOfTags["ticket.tags"]);
};
18 changes: 18 additions & 0 deletions packages/zendesk/sdk/types/client/client.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { NestedPaths } from "../utilities";
import { GetData, GettableLocations } from "./get";

type ZendeskApiResponse<U> = U & {
errors: {}; // need to reproduce errors somehow to property type it
};

export type ZafClient = {
invoke: (cmd: string, arg: any) => void;

get: <Path extends NestedPaths<GettableLocations>>(
key: Path
) => Promise<ZendeskApiResponse<GetData<Path>>>;

metadata: <U>() => Metadata<U>;
request: <U>(data: Object) => Promise<U>;
on: (eventName: string, listener: (...args: any) => any) => void;
};
9 changes: 9 additions & 0 deletions packages/zendesk/sdk/types/client/get.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Locations as AllLocations } from "../apps/support/locations";
import { NestedPaths, TypeFromPath } from "../utilities";

type LocationsKeys = keyof AllLocations;
export type GettableLocations = AllLocations[LocationsKeys];

export type GetData<Key extends NestedPaths<GettableLocations>> = {
[key in Key]: TypeFromPath<GettableLocations, key>;
}
9 changes: 9 additions & 0 deletions packages/zendesk/sdk/types/metadata/metadata.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
type Metadata<T> = {
appId: number;
installationId: number;
name: string;
plan: {
name: string;
};
settings?: T;
};
62 changes: 62 additions & 0 deletions packages/zendesk/sdk/types/utilities/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
export type Primitive = string | number | symbol;

type GenericObject = Record<Primitive, unknown>;

type Join<
L extends Primitive | undefined,
R extends Primitive | undefined
> = L extends string | number
? R extends string | number
? `${L}.${R}`
: L
: R extends string | number
? R
: undefined;

type Union<
L extends unknown | undefined,
R extends unknown | undefined
> = L extends undefined
? R extends undefined
? undefined
: R
: R extends undefined
? L
: L | R;

/**
* NestedPaths
* Get all the possible paths of an object
* @example
* type Keys = NestedPaths<{ a: { b: { c: string } }>
* // 'a' | 'a.b' | 'a.b.c'
*/
export type NestedPaths<
T extends GenericObject,
Prev extends Primitive | undefined = undefined,
Path extends Primitive | undefined = undefined
> = {
[K in keyof T]: T[K] extends GenericObject
? NestedPaths<T[K], Union<Prev, Path>, Join<Path, K>>
: Union<Union<Prev, Path>, Join<Path, K>>;
}[keyof T];

/**
* TypeFromPath
* Get the type of the element specified by the path
* @example
* type TypeOfAB = TypeFromPath<{ a: { b: { c: string } }, 'a.b'>
* // { c: string }
*/
export type TypeFromPath<
T extends GenericObject,
Path extends string // Or, if you prefer, NestedPaths<T>
> = {
[K in Path]: K extends keyof T
? T[K]
: K extends `${infer P}.${infer S}`
? T[P] extends GenericObject
? TypeFromPath<T[P], S>
: never
: never;
}[Path];
7 changes: 6 additions & 1 deletion packages/zendesk/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
{
"compilerOptions": {
"typeRoots": ["./@types"],
"target": "es2016",
"module": "commonjs",
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
4 changes: 4 additions & 0 deletions packages/zendesk/tsd_project/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
## What is this?

Dummy project to force `tsd` package to play nicely with testing types
https://github.com/SamVerschueren/tsd/issues/32#issuecomment-778650556
Empty file.
6 changes: 6 additions & 0 deletions packages/zendesk/tsd_project/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"types": "dummy.d.ts",
"tsd": {
"directory": "../sdk"
}
}
Loading