diff --git a/types/jsforce/connection.d.ts b/types/jsforce/connection.d.ts index 859b6dbdb2..189ce234e8 100644 --- a/types/jsforce/connection.d.ts +++ b/types/jsforce/connection.d.ts @@ -20,7 +20,7 @@ export interface ConnectionOptions extends Partial { loginUrl?: string; logLevel?: string; maxRequest?: number; - oauth2?: OAuth2Options; + oauth2?: Partial; proxyUrl?: string; redirectUri?: string; refreshToken?: string; @@ -38,12 +38,33 @@ export interface UserInfo { export type ConnectionEvent = "refresh"; -export class Connection { - constructor(params: ConnectionOptions) - - accessToken: string; +/** + * the methods exposed here are done so that a client can use 'declaration augmentation' to get intellisense on their own projects. + * for example, given a type + * + * interface Foo { + * thing: string; + * yes: boolean; + * } + * + * you can write + * + * declare module "jsforce" { + * interface Connection { + * sobject(type: 'Foo'): SObject + * } + * } + * + * to ensure that you have the correct data types for the various collection names. + */ +export interface Connection { query(soql: string, callback?: (err: Error, result: QueryResult) => void): QueryResult; - sobject(resource: string): SObject; + sobject(resource: string): SObject; +} + +export class Connection implements Connection { + constructor(params: ConnectionOptions) + accessToken: string; login(user: string, password: string, callback?: (err: Error, res: UserInfo) => void): Promise; loginByOAuth2(user: string, password: string, callback?: (err: Error, res: UserInfo) => void): Promise; loginBySoap(user: string, password: string, callback?: (err: Error, res: UserInfo) => void): Promise; diff --git a/types/jsforce/jsforce-tests.ts b/types/jsforce/jsforce-tests.ts index 3c1657711d..208dba8bc8 100644 --- a/types/jsforce/jsforce-tests.ts +++ b/types/jsforce/jsforce-tests.ts @@ -1,5 +1,11 @@ import * as sf from 'jsforce'; +export interface DummyRecord { + thing: boolean; + other: number; + person: string; +} + const salesforceConnection: sf.Connection = new sf.Connection({ instanceUrl: '', refreshToken: '', @@ -9,6 +15,11 @@ const salesforceConnection: sf.Connection = new sf.Connection({ }, }); +salesforceConnection.sobject("Dummy").select(["thing", "other"]); + +// note the following should never compile: +// salesforceConnection.sobject("Dummy").select(["lol"]); + salesforceConnection.sobject("Account").create({ Name: "Test Acc 2", BillingStreet: "Maplestory street", @@ -30,9 +41,9 @@ salesforceConnection.sobject("ContentVersion").create({ } }); -salesforceConnection.sobject("ContentVersion").retrieve("world", { +salesforceConnection.sobject("ContentVersion").retrieve("world", { test: "test" -}, (err: Error, ret: sf.Record) => { +}, (err: Error, ret) => { if (err) { return; } diff --git a/types/jsforce/record.d.ts b/types/jsforce/record.d.ts index 3bfec4c65b..3dd0bca1da 100644 --- a/types/jsforce/record.d.ts +++ b/types/jsforce/record.d.ts @@ -1,6 +1,16 @@ +import { RecordResult } from './record-result'; +import { Connection } from './connection'; import { SalesforceId } from './salesforce-id'; +import { Stream } from 'stream'; -export interface Record { - Id: SalesforceId; - attributes: Object[]; +export class RecordReference { + constructor(conn: Connection, type: string, id: SalesforceId); + blob(fieldName: string): Stream; + del(options?: Object, callback?: (err: Error, result: RecordResult) => void): Promise; + delete(options?: Object, callback?: (err: Error, result: RecordResult) => void): Promise; + destroy(options?: Object, callback?: (err: Error, result: RecordResult) => void): Promise; + retrieve(options?: Object, callback?: (err: Error, record: Record) => void): Promise>; + update(record: Partial, options?: Object, callback?: (err: Error, result: RecordResult) => void): Promise; } + +export type Record = {Id: SalesforceId } & T; diff --git a/types/jsforce/salesforce-object.d.ts b/types/jsforce/salesforce-object.d.ts index 2fd097b709..c1f8f61207 100644 --- a/types/jsforce/salesforce-object.d.ts +++ b/types/jsforce/salesforce-object.d.ts @@ -3,19 +3,20 @@ import * as stream from 'stream'; import { SObjectCreateOptions } from './create-options'; import { DescribeSObjectResult } from './describe-result'; import { Query } from './query'; -import { Record } from './record'; +import { Record, RecordReference } from './record'; import { RecordResult } from './record-result'; import { Connection } from './connection'; import { SalesforceId } from './salesforce-id'; -export class SObject { - record(options: any, callback?: (err: Error, ret: any) => void): void; - update(record: Partial, options?: Object, callback?: (err: Error, ret: RecordResult) => void): Promise; - update(records: Partial[], options?: Object, callback?: (err: Error, ret: RecordResult[]) => void): Promise; - retrieve(ids: string | string[], callback?: (err: Error, ret: Record | Record[]) => void): Promise; - retrieve(ids: string | string[], options?: Object, callback?: (err: Error, ret: Record | Record[]) => void): Promise; - upsert(records: Record | Record[], extIdField: SalesforceId, options?: Object, callback?: (err: Error, ret: RecordResult) => void): Promise; - upsertBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; +export class SObject { + record(id: SalesforceId): RecordReference; + retrieve(id: SalesforceId, options?: Object, callback?:(err: Error, record: Record) => void): Promise>; + retrieve(ids: SalesforceId[], options?: Object, callback?: (err: Error, ret: Record[]) => void): Promise[]>; + update(record: Partial, options?: Object, callback?: (err: Error, ret: RecordResult) => void): Promise; + update(records: Partial[], options?: Object, callback?: (err: Error, ret: RecordResult[]) => void): Promise; + upsert(records: Record, extIdField: SalesforceId, options?: Object, callback?: (err: Error, ret: RecordResult) => void): Promise; + upsert(records: Record[], extIdField: SalesforceId, options?: Object, callback?: (err: Error, ret: RecordResult) => void): Promise; + upsertBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult[] | BatchResultInfo[]) => void): Batch; describeGlobal(callback: (err: Error, res: any) => void): void; describe$(callback: (err: Error, ret: DescribeSObjectResult) => void): void; describeGlobal$(callback: (err: Error, res: any) => void): void; @@ -29,39 +30,37 @@ export class SObject { findOne(query?: any, fields?: Object | string[] | string, options?: Object, callback?: (err: Error, ret: T) => void): void; approvalLayouts(callback?: (layoutInfo: ApprovalLayoutInfo) => void): Promise; - bulkload(operation: string, options?: { extIdField?: string }, input?: Record[] | stream.Stream[] | string[], callback?: (err: Error, ret: RecordResult) => void): Batch; + bulkload(operation: string, options?: { extIdField?: string }, input?: Record[] | stream.Stream[] | string[], callback?: (err: Error, ret: RecordResult) => void): Batch; compactLayouts(callback?: CompactLayoutInfo): Promise; count(conditions?: Object | string, callback?: (err: Error, num: number) => void): Promise; create(options: any | any[], callback?: (err: Error, ret: RecordResult | RecordResult[]) => void): Promise; - createBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; + createBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; del(ids: string | string[], callback?: (err: Error, ret: any) => void): void; destroy(ids: string | string[], callback?: (err: Error, ret: any) => void): void; delete(ids: string | string[], callback?: (err: Error, ret: any) => void): void; - deleteBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; - destroyBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; - destroyHardBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; + deleteBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; + destroyBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; + destroyHardBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; deleted(start: Date | string, end: Date | string, callback?: (info: DeletedRecordsInfo) => void): Promise; - deleteHardBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; + deleteHardBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; describe(callback?: (err: Error, ret: DescribeSObjectResult) => void): Promise; insert(options: any | any[], callback?: (err: Error, ret: RecordResult | RecordResult[]) => void): Promise; - insertBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; + insertBulk(input?: Record[] | stream.Stream | string, callback?: (err: Error, ret: RecordResult) => void): Batch; layouts(layoutName?: string, callback?: (err: Error, info: LayoutInfo) => void): Promise; listview(id: string): ListView; listviews(callback?: (err: Error, info: ListViewsInfo) => void): Promise; quickAction(actionName: string): QuickAction; quickActions(callback?: (err: Error, info: any) => void): Promise; recent(callback?: (err: Error, ret: RecordResult) => void): Promise; - select(field?: Object | string[] | string, callback?: (err: Error, ret: T[]) => void): Query; + select(callback?: (err: Error, ret: T[]) => void): Promise; + //TODO:use a typed pluck to turn `fields` into a subset of T's fields so that the output is slimmed down appropriately + select(fields?: (keyof T)[] | (keyof T), callback?: (err: Error, ret: Partial[]) => void): Promise[]>; } export interface ApprovalLayoutInfo { approvalLayouts: Object[]; } -export class Record extends Object { - constructor(connection: Connection, type: SObject, id: SalesforceId) -} - export class Batch extends stream.Writable { } @@ -86,7 +85,20 @@ export interface LayoutInfo { } export class ListView { - constructor(connection: Connection, type: SObject, id: SalesforceId) + constructor(connection: Connection, type: string, id: SalesforceId) +} + +export interface BatchInfo { + id: string; + jobId: string; + state: string; + stateMessage: string; +} + +export interface BatchResultInfo { + id: string; + batchId: string; + jobId: string; } export class ListViewsInfo { }