Skip to content
5 changes: 2 additions & 3 deletions index.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { CreateClient, CreateOptions } from './lib/types';
import { apiUrls } from './lib/utils/apis';
import { CreateClient, CreateOptions, apiUrlByResource } from './lib/types';
import { createEvents } from './lib/events';

const _ = require('underscore');

Check warning on line 4 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
const winston = require('winston');

Check warning on line 5 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden

// Possible TODO: Namespace parameters for different subcomponents
// E.g. clientOptions.requestor.instance OR
Expand All @@ -20,7 +19,7 @@

requestorConfig.logger = buildLogger(clientOptions);

return require('./lib/utils/httpRequestor.js').create(requestorConfig);

Check warning on line 22 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
}

function buildLogger(clientOptions) {
Expand Down Expand Up @@ -78,7 +77,7 @@
const requestor = buildRequestor(clientOptions);

const options: CreateOptions = {
apiUrls: apiUrls,
apiUrls: apiUrlByResource,
requestor: requestor,
clientOptions: {
accessToken: clientOptions.accessToken || process.env.SMARTSHEET_ACCESS_TOKEN,
Expand All @@ -88,14 +87,14 @@
};

return {
constants: require('./lib/utils/constants.js'),

Check warning on line 90 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
contacts: require('./lib/contacts/').create(options),

Check warning on line 91 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
events: createEvents(options),
favorites: require('./lib/favorites/').create(options),

Check warning on line 93 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
folders: require('./lib/folders/').create(options),

Check warning on line 94 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
groups: require('./lib/groups/').create(options),

Check warning on line 95 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
home: require('./lib/home/').create(options),

Check warning on line 96 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
images: require('./lib/images/').create(options),

Check warning on line 97 in index.ts

View workflow job for this annotation

GitHub Actions / lint

A `require()` style import is forbidden
reports: require('./lib/reports/').create(options),
request: require('./lib/request/').create(options),
search: require('./lib/search/').create(options),
Expand Down
24 changes: 4 additions & 20 deletions lib/events/index.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,14 @@
import { createApiProvider } from '../utils/createApiProvider';
import { EventsApi, GetEventsOptions, GetEventsResponse } from './types';
import { ClientOptions, CreateOptions, RequestCallback, RequestOptions } from '../types';

type OptionsToSend = Partial<ClientOptions> & {
url: string;
};
import { ApiResource, CreateOptions, RequestCallback, RequestOptions } from '../types';

export const createEvents = (options: CreateOptions): EventsApi => {
const requester = options.requestor;

let optionsToSend: OptionsToSend = {
url: options.apiUrls.events,
};

if (options.clientOptions) {
optionsToSend = {
...optionsToSend,
...options.clientOptions,
};
}

return {
return createApiProvider<EventsApi>(options, ApiResource.Events, (requester, optionsToSend) => ({
getEvents: (
options: RequestOptions<GetEventsOptions, undefined>,
callback?: RequestCallback<GetEventsResponse>
): Promise<GetEventsResponse> => {
return requester.get({ ...optionsToSend, ...options }, callback);
},
};
}));
};
60 changes: 60 additions & 0 deletions lib/favorites/endpoints/AddItemsToFavorites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { RequestCallback } from '../../types';
import { ApiGenerator, FavoritableResource, FavoriteItem, PostResult } from '../sharedTypes';
const _ = require('underscore');

type AddItemsToFavoritesParams = {

Check failure on line 5 in lib/favorites/endpoints/AddItemsToFavorites.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`
body: FavoriteItem | FavoriteItem[];
};

type AddItemsToFavoritesResponse = {
/**
* @description Favorite (object) or Array of Favorite (objects)
*/
result: FavoriteItem | FavoriteItem[];
} & PostResult;

type AddItemsToFavoritesRequest = (
params: AddItemsToFavoritesParams,
callback: RequestCallback<AddItemsToFavoritesResponse>
) => Promise<AddItemsToFavoritesResponse>;

export const addItemsToFavorites: ApiGenerator<AddItemsToFavoritesRequest> =
(requestor, optionsToSend) => (params, callback) => {
// TODO Bfeigin do i need to explicitly set this to be a body param?
return requestor.post(_.extend({}, optionsToSend, params), callback);
};

type AddResourceToFavoritesParams = {

Check failure on line 27 in lib/favorites/endpoints/AddItemsToFavorites.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`
objectId: string;
};

type AddItemOfTypeToFavoritesRequest = (
params: AddResourceToFavoritesParams,
callback: RequestCallback<AddItemsToFavoritesResponse>
) => Promise<AddItemsToFavoritesResponse>;

type AddFavoritesBuilder = (resourceType: FavoritableResource) => ApiGenerator<AddItemOfTypeToFavoritesRequest>;

export const buildAddFavoriteResourceFn: AddFavoritesBuilder = (resourceType: FavoritableResource) => {
return (requestor, optionsToSend) => (params, callback) => {
const generatedBody = {
objectId: params.objectId,
type: resourceType,
};

// Ensure we've extracted out any type and objectId params, placing them into body instead
const constructedPostParams = {
..._.omit(params, 'type', 'objectId'),
body: generatedBody,
};

return requestor.post(_.extend({}, optionsToSend, constructedPostParams), callback);
};
};

export const addSheetToFavorites = buildAddFavoriteResourceFn(FavoritableResource.Sheet);
export const addFolderToFavorites = buildAddFavoriteResourceFn(FavoritableResource.Folder);
export const addReportToFavorites = buildAddFavoriteResourceFn(FavoritableResource.Report);
export const addTemplateToFavorites = buildAddFavoriteResourceFn(FavoritableResource.Template);
export const addWorkspaceToFavorites = buildAddFavoriteResourceFn(FavoritableResource.Workspace);
export const addSightToFavorites = buildAddFavoriteResourceFn(FavoritableResource.Sight);
32 changes: 32 additions & 0 deletions lib/favorites/endpoints/ListFavorites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import { RequestCallback } from '../../types';
import { ApiGenerator, FavoriteItem, Pagination, PaginationResponse } from '../sharedTypes';

type IncludeOptions = string;

type ListFavortesParams = {
/**
* @description If true, include all results, that is, do not paginate. Mutually exclusive with page and pageSize (they are ignored if includeAll=true is specified).
*/
includeAll?: boolean;
/**
* @description A comma-separated list of optional elements to include in the response.
* Enum ["directId", "name"]
*/
include?: IncludeOptions;
} & Pagination;

export type ListFavoritesResponse = PaginationResponse & {
data: FavoriteItem[];
};
/**
* @description Gets a list of all of the user's favorite items.
*/
export type ListFavoritesRequest = (
params: ListFavortesParams,
callback: RequestCallback<ListFavoritesResponse>
) => Promise<ListFavoritesResponse>;

export const createListFavorites: ApiGenerator<ListFavoritesRequest> =
(requestor, optionsToSend) => (params, callback) => {
return requestor.get({ ...optionsToSend, ...params }, callback);
};
11 changes: 11 additions & 0 deletions lib/favorites/endpoints/RemoveFavorites.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { FavoritableResource, FavoriteItem } from '../sharedTypes';

type RemoveSingleFavoriteItem = {};

Check failure on line 3 in lib/favorites/endpoints/RemoveFavorites.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`

Check failure on line 3 in lib/favorites/endpoints/RemoveFavorites.ts

View workflow job for this annotation

GitHub Actions / lint

'RemoveSingleFavoriteItem' is defined but never used. Allowed unused vars must match /^_/u

type RemoveFavoritesBaseParams = {
/**
* @description A string or array of strings representing the objectIds to remove from favorites
*/
objectIds: FavoriteItem['objectId'] | FavoriteItem['objectId'][];
favoriteType: FavoritableResource;
};
60 changes: 60 additions & 0 deletions lib/favorites/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { ApiResource, CreateOptions } from '../types';
import { createApiProvider } from '../utils/createApiProvider';
import { createListFavorites } from './endpoints/ListFavorites';
import {
addFolderToFavorites,
addItemsToFavorites,
addReportToFavorites,
addSheetToFavorites,
addSightToFavorites,
addTemplateToFavorites,
addWorkspaceToFavorites,
} from './endpoints/AddItemsToFavorites';
import { ApiGenerator } from './sharedTypes';
import { FavoritesApi } from './types';

const buildFavoritesApi: ApiGenerator<FavoritesApi> = (requestor, optionsToSend) => {
return {
listFavorites: createListFavorites(requestor, optionsToSend),
addItemsToFavorites: addItemsToFavorites(requestor, optionsToSend),
addFolderToFavorites: addFolderToFavorites(requestor, optionsToSend),
addReportToFavorites: addReportToFavorites(requestor, optionsToSend),
addSheetToFavorites: addSheetToFavorites(requestor, optionsToSend),
addSightToFavorites: addSightToFavorites(requestor, optionsToSend),
addTemplateToFavorites: addTemplateToFavorites(requestor, optionsToSend),
addWorkspaceToFavorites: addWorkspaceToFavorites(requestor, optionsToSend),
// Duplicate of addItemsToFavorites
addMultipleToFavorites: addItemsToFavorites(requestor, optionsToSend),
};
};

//type FavoritesApi = {
// listFavorites : listFavorites,
// addItemsToFavorites : addItemsToFavorites,
// addSheetToFavorites : addSheetToFavorites,
// addFolderToFavorites : addFolderToFavorites,
// addReportToFavorites : addReportToFavorites,
// addTemplateToFavorites : addTemplateToFavorites,
// addSightToFavorites : addSightToFavorites,
// addWorkspaceToFavorites : addWorkspaceToFavorites,
// addMultipleToFavorites : addMultipleToFavorites,
// removeSheetFromFavorites : removeSheetFromFavorites,
// removeFolderFromFavorites : removeFolderFromFavorites,
// removeReportFromFavorites : removeReportFromFavorites,
// removeTemplateFromFavorites : removeTemplateFromFavorites,
// removeSightFromFavorites : removeSightFromFavorites,
// removeWorkspaceFromFavorites : removeWorkspaceFromFavorites,
// //convenience methods to remove multiples.
// //Uses the same as the singular remove methods.
// removeSheetsFromFavorites : removeSheetFromFavorites,
// removeFoldersFromFavorites : removeFolderFromFavorites,
// removeReportsFromFavorites : removeReportFromFavorites,
// removeTemplatesFromFavorites : removeTemplateFromFavorites,
// removeSightsFromFavorites : removeSightFromFavorites,
// removeWorkspacesFromFavorites : removeWorkspaceFromFavorites
//
//}

export const createFavorites = (options: CreateOptions) => {
return createApiProvider(options, ApiResource.Favorites, buildFavoritesApi);
};
58 changes: 58 additions & 0 deletions lib/favorites/sharedTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { OptionsToSend, Requestor } from '../types';

export type Pagination = {

Check failure on line 3 in lib/favorites/sharedTypes.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`
/**
* @description Which page to return. Defaults to 1 if not specified. If you specify a value greater than the total number of pages, the last page of results is returned.
*
*/
page?: number;
/**
* @description The maximum number of items to return per page. Unless otherwise stated for a specific endpoint, defaults to 100. If only page is specified, defaults to a page size of 100. For reports, the default is 100 rows. If you need larger sets of data from your report, returns a maximum of 10,000 rows per request.
*/
pageSize?: number;
};

export type PaginationResponse = {

Check failure on line 15 in lib/favorites/sharedTypes.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How frequently are these types used (everywhere?)

pageNumber: number;
pageSize?: number;
totalPages: number;
totalCount: number;
};

export enum FavoritableResource {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a standard set of resources?

Folder = 'folder',
Report = 'report',
Sheet = 'sheet',
Sight = 'sight',
Template = 'template',
Workspace = 'workspace',
}

export enum ResponseStatusMessage {
PartialSuccess = 'PARTIAL_SUCCESS',
SUCCESS = 'SUCCESS',
}

export enum ResultCode {
Success = 0,
PartialSuccess = 3,
}

export type PostResult = {

Check failure on line 41 in lib/favorites/sharedTypes.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`
/**
* @description Message that indicates the outcome of the request. (One of SUCCESS or PARTIAL_SUCCESS)
*/
message: ResponseStatusMessage;
/**
* @description number indicating result status: 0 Success, 3 Partial Success of Bulk Operation
*
*/
resultCode: ResultCode;
};

export type FavoriteItem = {

Check failure on line 53 in lib/favorites/sharedTypes.ts

View workflow job for this annotation

GitHub Actions / lint

Use an `interface` instead of a `type`
objectId: string;
type: FavoritableResource;
};

export type ApiGenerator<T> = (requestor: Requestor, optionsToSend: OptionsToSend) => T;
5 changes: 5 additions & 0 deletions lib/favorites/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ListFavoritesRequest } from "./endpoints/ListFavorites";

export type FavoritesApi = {
listFavorites: ListFavoritesRequest;
};
65 changes: 46 additions & 19 deletions lib/types/ApiUrls.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,47 @@
export interface ApiUrls {
contacts: string;
events: string;
favorites: string;
folders: string;
groups: string;
home: string;
imageUrls: string;
reports: string;
search: string;
server: string;
sheets: string;
sights: string;
templates: string;
templatesPublic: string;
token: string;
users: string;
webhooks: string;
workspaces: string;
export enum ApiResource {
Contacts = 'contacts',
Events = 'events',
Favorites = 'favorites',
Folders = 'folders',
Groups = 'groups',
Home = 'home',
ImageUrls = 'imageurls',
Reports = 'reports',
Search = 'search',
Server = 'serverinfo',
Sheets = 'sheets',
Sights = 'sights',
Templates = 'templates',
TemplatesPublic = 'templatespublic',
Token = 'token',
Users = 'users',
Webhooks = 'webhooks',
Workspaces = 'workspaces',
}

export const apiUrlByResource = {
[ApiResource.Contacts]: 'contacts/',
[ApiResource.Events]: 'events/',
[ApiResource.Favorites]: 'favorites/',
[ApiResource.Folders]: 'folders/',
[ApiResource.Groups]: 'groups/',
[ApiResource.Home]: 'home/',
[ApiResource.ImageUrls]: 'imageurls/',
[ApiResource.Reports]: 'reports/',
[ApiResource.Search]: 'search/',
[ApiResource.Server]: 'serverinfo/',
[ApiResource.Sheets]: 'sheets/',
[ApiResource.Sights]: 'sights/',
[ApiResource.Templates]: 'templates/',
[ApiResource.TemplatesPublic]: 'templates/public',
[ApiResource.Token]: 'token',
[ApiResource.Users]: 'users/',
[ApiResource.Webhooks]: 'webhooks/',
[ApiResource.Workspaces]: 'workspaces/',
} as const;

// Map of ApiResource to path
export type ApiUrlPathByResource = typeof apiUrlByResource;

// Valid paths for Api Resources
export type ApiUrlPath = ApiUrlPathByResource[ApiResource];
26 changes: 23 additions & 3 deletions lib/types/CreateOptions.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,30 @@
import { ApiUrls } from './ApiUrls';
import { ApiUrlPathByResource } from './ApiUrls';
import { CreateClientOptions } from './CreateClientOptions';

export type ClientOptions = Pick<CreateClientOptions, 'accessToken' | 'userAgent' | 'baseUrl'>;

export interface Requestor {
get: (options: any, callback: any) => any;
put: (options: any, callback: any) => any;
post: (options: any, callback: any) => any;
postFile: (options: any, callback: any) => any;
delete: (options: any, callback: any) => any;
internal: {
buildHeaders: (options: any) => {
Accept: any;
'Content-Type': any;
'User-Agent': string;
};
buildUrl: (options: any) => any;
};
}

export interface CreateOptions {
apiUrls: ApiUrls;
requestor: any;
apiUrls: ApiUrlPathByResource;
requestor: Requestor;
clientOptions?: ClientOptions;
}

export type OptionsToSend = Partial<ClientOptions> & {
url: string;
};
Loading
Loading