Skip to content

Commit

Permalink
Update TS types (#23)
Browse files Browse the repository at this point in the history
* Update TS types

* make the linter happy

* Added misssing fields to the LoginOptions type

* add typecheck to github actions

* remove unecessary path updates

* remove optional only installation in GA
  • Loading branch information
bmuller authored Apr 26, 2024
1 parent 75fe6fd commit d9de3f1
Show file tree
Hide file tree
Showing 9 changed files with 75 additions and 111 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ jobs:
with:
node-version: ${{ env.NODE_VERSION }}
cache: pnpm
- run: pnpm install --no-optional
- run: pnpm install
- run: pnpm lint
- run: pnpm test
- run: pnpm build
- run: pnpm typecheck
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
"scripts": {
"build": "pnpm --filter '@parallelmarkets/*' build",
"lint": "pnpm -r lint",
"test": "pnpm -r test"
"test": "pnpm -r test",
"typecheck": "pnpm -r typecheck"
},
"keywords": [
"ParallelMarkets"
Expand Down
1 change: 1 addition & 0 deletions packages/react/src/__tests__/index-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import React from 'react'
import { ParallelProvider, PassportButton } from '../index'

const ParallelMock = {
getProfile: (cb, _eb) => cb({}),
getLoginStatus: (cb) => cb({}),
subscribe: () => null,
unsubscribe: () => null,
Expand Down
25 changes: 3 additions & 22 deletions packages/react/src/index.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import React, { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react'
import ButtonImg from './medium-passport-button.svg'

import { ParallelApiRecord, loadParallel } from '@parallelmarkets/vanilla'
import type { AuthCallbackResult, Parallel } from '@parallelmarkets/vanilla'
import { ProfileApiResponse } from './profile_api_types'

export * from './profile_api_types'
import { loadParallel } from '@parallelmarkets/vanilla'
import type { AuthCallbackResult, ProfileApiResponse } from '@parallelmarkets/vanilla'

type LoadParallelPromise = ReturnType<typeof loadParallel>
type LoadParallelResult = Awaited<ReturnType<typeof loadParallel>>
Expand All @@ -29,22 +26,6 @@ const isPromise = (thing: unknown): thing is PromiseLike<unknown> => {
return typeof (thing as PromiseLike<unknown>)?.then === 'function'
}

// The Embed API works with callback functions. This wrapper converts them to promises.
const promisifyApiCall = <ResultType extends ParallelApiRecord>(parallel: Parallel, endpoint: string) => {
return () => {
// This promise resolves with the type of the API's Success Callback function's first Parameter
return new Promise<ResultType>((resolve, reject) => {
parallel.api(
endpoint,
(result) => {
resolve(result as ResultType)
},
reject,
)
})
}
}

export const useParallel = () => {
const { parallel: parallelPromise } = useContext(ParallelContext)
const [parallel, setParallel] = useState<LoadParallelResult>(null)
Expand Down Expand Up @@ -104,7 +85,7 @@ export const useParallel = () => {
parallel,
error,
loginStatus,
getProfile: promisifyApiCall<ProfileApiResponse>(parallel, '/profile'),
getProfile: new Promise<ProfileApiResponse>(parallel.getProfile),
login: parallel.login,
logout: parallel.logout,
}
Expand Down
36 changes: 0 additions & 36 deletions packages/react/src/profile_api_types.ts

This file was deleted.

13 changes: 7 additions & 6 deletions packages/vanilla/src/__tests__/index-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,23 @@ declare global {
}

global.window.Parallel = {
get _config() {
return window.config
},
init: ({ on_init, ...params }: ParallelConfig) => {
window.config = params
on_init?.()
},
api: () => null,
getLoginStatus: () => null,
getProfile: () => null,
login: () => null,
logout: () => null,
unsubscribe: () => null,
subscribe: () => null,
showButton: () => null,
hideButton: () => null,
unsubscribe: () => null,
getLoginStatus: () => null,
subscribeWithButton: () => null,
_appendLoadContext: () => null,
get _config() {
return window.config
},
}

test('Configuration is set correctly', async () => {
Expand Down
29 changes: 0 additions & 29 deletions packages/vanilla/src/common_api_types.ts

This file was deleted.

1 change: 0 additions & 1 deletion packages/vanilla/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { Parallel, ParallelConfig } from './types'

export * from './types'
export * from './common_api_types'

const V2_URL = 'https://app.parallelmarkets.com/sdk/v2/parallel.js'
let parallelPromise: Promise<Parallel | null> | undefined
Expand Down
74 changes: 59 additions & 15 deletions packages/vanilla/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
import { type BusinessType } from './common_api_types'
export type EntityKind = 'individual' | 'business'

export type BusinessType =
| 'Public Charity'
| 'Private Foundation'
| 'S Corporation'
| 'C Corporation'
| 'Irrevocable Trust'
| 'Revocable Trust'
| 'Family Office'
| 'Limited Liability Company'
| 'Limited Partnership'

/* eslint-disable @typescript-eslint/no-explicit-any */
type AuthResponse = {
Expand All @@ -16,17 +27,19 @@ export type AuthCallbackResult = {
errorDescription?: string
}

// https://developer.parallelmarkets.com/docs/server/scopes
export type ParallelScope = 'profile' | 'accreditation_status' | 'identity' | 'blockchain'
// https://developer.parallelmarkets.com/docs/javascript/configuration#scopes
export type ParallelScope = 'profile' | 'accreditation_status' | 'identity'

// https://developer.parallelmarkets.com/docs/javascript/configuration
type EmbedParallelConfig = {
flow_type: 'embed'
embed_into_id: string
}

type OverlayRedirectParallelConfig = {
flow_type: 'overlay' | 'redirect'
}

export type ParallelConfig = (EmbedParallelConfig | OverlayRedirectParallelConfig) & {
client_id?: string
environment?: 'production' | 'demo'
Expand All @@ -40,21 +53,47 @@ export type ParallelConfig = (EmbedParallelConfig | OverlayRedirectParallelConfi
raw_config?: Record<string, any>
}

export type IndividualProfile = {
email: string
first_name: string
last_name: string
}

export type BusinessProfile = {
name: string
business_type: BusinessType
primary_contact: IndividualProfile
}

export type ProfileApiResponse = {
id: string
type: EntityKind
profile: IndividualProfile | BusinessProfile
user_id: string
user_profile: IndividualProfile
user_providing_for: 'self' | 'controlled-business' | 'other-individual'
access_expires_at: string | null
access_revoked_by: 'subject' | 'partner' | 'system' | null
available_scopes: Array<ParallelScope>
}

type GetProfileSuccessCallbackFunc = (_result: ProfileApiResponse) => void

type GetProfileFailureCallbackFunc = (_result: { error: unknown }) => void

type AuthSuccessCallbackFunc = (_result: AuthCallbackResult) => void
type AuthFailureCallbackFunc = (_result: { error: unknown }) => void

// TODO: implement this
export type ParallelApiRecord = Record<string, any>
export type ParallelApiSuccessCallback = (_response: ParallelApiRecord) => void
export type ParallelApiErrorCallback = (_reason: any) => void
type AuthFailureCallbackFunc = (_result: { error: unknown }) => void

type SubscribeEvents = 'auth.login' | 'auth.logout' | 'auth.statusChange' | 'auth.authResponseChange'

type OAuthErrorCode =
| 'invalid_request'
| 'invalid_client'
| 'invalid_grant'
| 'unauthorized_client'
| 'unsupported_grant_type'

type SubscriptionEvent = {
status: 'not_authorized' | 'unknown' | 'connected'
error?: OAuthErrorCode
Expand All @@ -67,37 +106,42 @@ type SubscriptionEvent = {
refresh_expires_in: number
}
}

type SubscriptionHandler = (_response: SubscriptionEvent) => void

export interface LoginOptions {
email?: string
first_name?: string
last_name?: string
external_id?: string
expected_entity_id?: string
expected_entity_type?: 'self' | BusinessType
expected_business_name?: string
partner_supporting?: string
ref_code?: string
redirect_uri_signature?: string
required_entity_id?: string
}

export interface Parallel {
init(_options: ParallelConfig): void
_config: ParallelConfig
getLoginStatus: (_callback: AuthSuccessCallbackFunc) => void
getProfile: (_successFunc: GetProfileSuccessCallbackFunc, _errorFunc: GetProfileFailureCallbackFunc) => void
login: (_options?: LoginOptions) => void
logout: () => void
subscribeWithButton: (_successFunc: AuthSuccessCallbackFunc, _errorFunc: AuthFailureCallbackFunc) => void
unsubscribe: (_event: SubscribeEvents, _callback: SubscriptionHandler) => void
subscribe: (_event: SubscribeEvents, _callback: SubscriptionHandler) => void
showButton: () => void
hideButton: () => void
api: (_endpoint: string, _callback: ParallelApiSuccessCallback, _errback: ParallelApiErrorCallback) => void
subscribe: (_event: SubscribeEvents, _callback: SubscriptionHandler) => void
unsubscribe: (_event: SubscribeEvents, _callback: SubscriptionHandler) => void
getLoginStatus: (_callback: AuthSuccessCallbackFunc) => void
subscribeWithButton: (_successFunc: AuthSuccessCallbackFunc, _errorFunc: AuthFailureCallbackFunc) => void
_appendLoadContext: (_context: string) => void
_config: ParallelConfig
}

declare global {
interface Window {
// parallel.js must be loaded directly from app.parallelmarkets.com/sdk/v2/parallel.js
// which places a `Paralell` object at the window level
// which places a `Parallel` object at the window level
Parallel?: Parallel
}
}

0 comments on commit d9de3f1

Please sign in to comment.