Web extensions API services

Using injected API services for developing web extensions.

Using API services in web extensions

The web extension has access to services that are injected into the page to facilitate communication with Skedulo’s API.

These services have their appropriate type definitions (for Typescript) defined in the src/Services/Services.ts boilerplate file.

You can use this file to get direct references to everything injected in the web extension.

Variables

Skedulo updates the injected services in your environment using environment variables.

As we update the injected services we will also periodically update the boilerplate files.

The following is a list of all variables that are injected into web extensions.

Variables

Services: {
graphQL: {
   fetch<T>(operation: GraphQLRequest, endpoint?: string): Promise<T>
   mutate(operation: GraphQLRequest, endpoint?: string): Promise<GraphQLMutationResult>
   fetchMetadataFor(model: string): Promise<IntrospectionModelType>
 },
 metadata: {
   fetchVocabulary(): Promise<Vocabulary>
 },
 errorClasses: {
   GraphQLNetworkError: GraphQLError,
   GraphQLExecutionError: GraphQLError
 }
}

// All live data observables present in the web app.  Allows for listening to changes in
// certain objects.
Channels: 
  realtime: IRealtimeChannel
}


context: {
  url: string
  hash?: string

  // The reference UID of the context the page is loaded under
  // This enables pages to have any object as a context in future
  referenceUID?: string
  
  // Only for backwards compatibility, superseded by referenceUID
  jobId?: string
  resourceUID?: string
}

// Query parameters
params: { [param: string]: any }

// Any route parts past the root of the page in the URL (split by '/')
routes: string[]

credentials: {
  apiServer: string
  apiAccessToken: string 
  vendor: {
    type: string
    url: string
    token: string // Access token for the vendor
  }
}

navigation: {
  // Register a handler to listen to changes in the route
  registerRouteHandler: (handler: (scopedRouteState: { routes: string | string[], params: any }) => void) => void
  
  // Set the route path past the page root (safely changes route without changing the base domain)
  setParentRoute: (route: string) => void
}

profile: {
  tenantId: authData.profile['https://api.skedulo.com/organization_id']
  userId: authData.profile['https://api.skedulo.com/ven'].user_id
  username: authData.profile['https://api.skedulo.com/username']
  roles: authData.profile['https://api.skedulo.com/roles']
}
  • Services.graphQL: This service allows you to send queries to Skedulo’s GraphQL API. This is the primary method of retrieving, consuming and updating data from a web extension. Refer to src/Services/DataServices.ts for usage examples. This also exposes a method for retrieving GraphQL introspection data for any given model if required.

  • Services.metadata: This service allows you to fetch data from our metadata API.

  • Services.errorClasses: This is a map that lists all possible errors that can be thrown while interacting with the available services.

    For example, a GraphQLExecutionError can occur if there is an error in the defined query. You can use these classes (if needed) to pattern-match (instanceof checks) in Promise catch blocks for easy and contextual error handling.

  • Context: The reference UID of the context under which the page is loaded.

    For example, when loading a web extension with a defined page URL of /jobs with a URL in the format /jobs/001419c0-62d8-4176-b95c-13d8b68da908, the context parameter in this case would be the ID that was requested, i.e., 001419c0-62d8-4176-b95c-13d8b68da908.

  • skedInjected: This is the global variable injected into a web extension in production. You can use the provided credentials to create a HTTP instance for making requests to any Skedulo API.

Nested types

RealtimeJobChangeSet = Pick<Job, 'UID' | 'JobStatus' | 'Urgency' | 'Locked' | 'Start' | 'Duration' | 'End' | 'Address' | 'GeoLatitude' | 'GeoLongitude'>
RealtimeJobAllocationChangeSet = Pick<IJobAllocation, 'UID' | 'Status' | 'JobId' | 'ResourceId'>
ExtendedRealtimeJobAllocation = RealtimeJobAllocation & { JobId: string, ResourceId: string }

interface IRealtimeChannel {
  getJobStream: () => Observable<RealtimeJobChangeSet[]>,
  getJobAllocationStream: () => Observable<RealtimeJobAllocationChangeSet[]>,
  getUpdatedJobStream: () => Observable<RealtimeJobChangeSet[]>,
  getCreatedJobStream: () => Observable<RealtimeJobChangeSet[]>,
  getUpdatedJobAllocationStream: () => Observable<RealtimeJobAllocationChangeSet[]>,
  getCreatedJobAllocationStream: () => Observable<RealtimeJobAllocationChangeSet[]>
}

This approach allows you to provide credentials and context that is used to instantiate services for the page and allows you to access the Skedulo GraphQL schema.


Last modified May 22, 2020: Eng 10524/sdk (#34) (5c9e4f8)