fix: support non-Error & non-String errors

This commit is contained in:
orion 2023-12-02 20:20:14 -06:00
parent 5db9c3e5b0
commit 540ffb2f78
Signed by: orion
GPG Key ID: 6D4165AE4C928719
23 changed files with 747 additions and 705 deletions

View File

@ -53,7 +53,7 @@ foreign import _clearPermissionOverrides :: BrowserContext -> Effect (Promise Un
foreign import _close :: BrowserContext -> Effect (Promise Unit)
incognito :: Create -> Browser -> Aff BrowserContext
incognito c b = Promise.toAffE $ _incognito (prepareCreate c) b
incognito c b = FFI.promiseToAff $ _incognito (prepareCreate c) b
incognito_ :: Browser -> Aff BrowserContext
incognito_ = incognito { proxyBypassList: Nothing, proxyServer: Nothing }
@ -62,10 +62,10 @@ default :: Browser -> BrowserContext
default = _default
overridePermissions :: String -> Set Permission -> BrowserContext -> Aff Unit
overridePermissions origin perms ctx = Promise.toAffE $ _overridePermissions origin (Set.toUnfoldable perms) ctx
overridePermissions origin perms ctx = FFI.promiseToAff $ _overridePermissions origin (Set.toUnfoldable perms) ctx
clearPermissionOverrides :: BrowserContext -> Aff Unit
clearPermissionOverrides = Promise.toAffE <<< _clearPermissionOverrides
clearPermissionOverrides = FFI.promiseToAff <<< _clearPermissionOverrides
close :: BrowserContext -> Aff Unit
close = Promise.toAffE <<< _close
close = FFI.promiseToAff <<< _close

View File

@ -117,4 +117,4 @@ get :: forall b. BrowserAccess b => b -> Effect Browser
get = _get <<< unsafeToForeign
close :: Browser -> Aff Unit
close = Promise.toAffE <<< _close
close = FFI.promiseToAff <<< _close

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,9 @@ import Control.Promise as Promise
import Effect (Effect)
import Effect.Aff (Aff)
import Puppeteer.Base (CDPSession)
import Puppeteer.FFI as FFI
foreign import _detach :: CDPSession -> Effect (Promise Unit)
detach :: CDPSession -> Aff Unit
detach = Promise.toAffE <<< _detach
detach = FFI.promiseToAff <<< _detach

View File

@ -17,30 +17,31 @@ import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign, unsafeToForeign)
import Puppeteer.Base (class EvalTarget, Handle)
import Puppeteer.FFI as FFI
foreign import _run :: forall @r. String -> Foreign -> Array Foreign -> Effect (Promise r)
foreign import _runh :: forall @r. String -> Foreign -> Array Foreign -> Effect (Promise (Handle r))
unsafeRunJs0 :: forall e @r. EvalTarget e => String -> e -> Aff r
unsafeRunJs0 js h = Promise.toAffE $ _run js (unsafeToForeign h) []
unsafeRunJs0 js h = FFI.promiseToAff $ _run js (unsafeToForeign h) []
unsafeRunJsHandle0 :: forall e @r. EvalTarget e => String -> e -> Aff (Handle r)
unsafeRunJsHandle0 js h = Promise.toAffE $ _runh js (unsafeToForeign h) []
unsafeRunJsHandle0 js h = FFI.promiseToAff $ _runh js (unsafeToForeign h) []
unsafeRunJs1 :: forall a e @r. EvalTarget e => String -> a -> e -> Aff r
unsafeRunJs1 js a h = Promise.toAffE $ _run js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJs1 js a h = FFI.promiseToAff $ _run js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJsHandle1 :: forall a e @r. EvalTarget e => String -> a -> e -> Aff (Handle r)
unsafeRunJsHandle1 js a h = Promise.toAffE $ _runh js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJsHandle1 js a h = FFI.promiseToAff $ _runh js (unsafeToForeign h) [ unsafeToForeign a ]
unsafeRunJs2 :: forall a b e @r. EvalTarget e => String -> a -> b -> e -> Aff r
unsafeRunJs2 js a b h = Promise.toAffE $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJs2 js a b h = FFI.promiseToAff $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJsHandle2 :: forall a b e @r. EvalTarget e => String -> a -> b -> e -> Aff (Handle r)
unsafeRunJsHandle2 js a b h = Promise.toAffE $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJsHandle2 js a b h = FFI.promiseToAff $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b ]
unsafeRunJs3 :: forall a b c e @r. EvalTarget e => String -> a -> b -> c -> e -> Aff r
unsafeRunJs3 js a b c h = Promise.toAffE $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]
unsafeRunJs3 js a b c h = FFI.promiseToAff $ _run js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]
unsafeRunJsHandle3 :: forall a b c e @r. EvalTarget e => String -> a -> b -> c -> e -> Aff (Handle r)
unsafeRunJsHandle3 js a b c h = Promise.toAffE $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]
unsafeRunJsHandle3 js a b c h = FFI.promiseToAff $ _runh js (unsafeToForeign h) [ unsafeToForeign a, unsafeToForeign b, unsafeToForeign c ]

View File

@ -20,3 +20,15 @@ export const _maybeToUndefined = mton => m => {
const n = mton(m)
return n === null ? undefined : n
}
/** @type {(_: unknown) => string} */
export const anyToString = a =>
typeof a === 'string'
? a
: typeof a === 'undefined'
? 'undefined'
: a === null
? 'null'
: a instanceof Array
? JSON.stringify(a.map(i => anyToString(i)))
: a.toString()

View File

@ -1,9 +1,12 @@
module Puppeteer.FFI (mapToRecord, maybeToUndefined, mergeRecords, unsafeMaybeToUndefined, makeMap) where
module Puppeteer.FFI (mapToRecord, maybeToUndefined, mergeRecords, unsafeMaybeToUndefined, makeMap, promiseToAff) where
import Prelude
import Control.Monad.Except (runExcept)
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Array as Array
import Data.Foldable (foldl)
import Data.Either (either)
import Data.FoldableWithIndex (foldlWithIndex)
import Data.Map (Map)
import Data.Map as Map
@ -11,10 +14,15 @@ import Data.Maybe (Maybe)
import Data.Nullable (Nullable)
import Data.Nullable as Nullable
import Data.Tuple (Tuple(..))
import Foreign (Foreign)
import Effect (Effect)
import Effect.Aff (Aff)
import Effect.Class (liftEffect)
import Effect.Exception (error)
import Foreign (Foreign, unsafeReadTagged)
import Simple.JSON (class WriteForeign)
foreign import mergeRecords :: Array Foreign -> Foreign
foreign import anyToString :: Foreign -> String
foreign import _mapToRecord :: forall a. Array { k :: String, v :: a } -> Foreign
foreign import _maybeToUndefined :: forall a. (Maybe a -> Nullable a) -> Maybe a -> Foreign
@ -29,3 +37,12 @@ maybeToUndefined = _maybeToUndefined Nullable.toNullable
unsafeMaybeToUndefined :: forall a. Maybe a -> Foreign
unsafeMaybeToUndefined = _maybeToUndefined Nullable.toNullable
promiseToAff :: forall a. Effect (Promise a) -> Aff a
promiseToAff =
let
err e = either (const $ error $ anyToString e) identity
$ runExcept
$ unsafeReadTagged "Error" e
in
flip bind (Promise.toAff' err) <<< liftEffect

View File

@ -66,7 +66,7 @@ foreign import _clone :: forall a. Handle a -> Effect (Promise a)
foreign import _getProperties :: forall a. Handle a -> Effect (Promise (Array { k :: String, v :: (Handle Foreign) }))
clone :: forall a. WriteForeign a => ReadForeign a => Handle a -> Aff a
clone = Promise.toAffE <<< _clone
clone = FFI.promiseToAff <<< _clone
findFirst :: forall a b sel. IsElement a => Selector sel b => sel -> Handle a -> Aff (Maybe (Handle b))
findFirst q h = do
@ -74,49 +74,49 @@ findFirst q h = do
pure $ head els
findAll :: forall a b sel. IsElement a => Selector sel b => sel -> Handle a -> Aff (Array (Handle b))
findAll q h = Promise.toAffE $ _find (Selector.toCSS q) h
findAll q h = FFI.promiseToAff $ _find (Selector.toCSS q) h
click :: forall a. IsElement a => Handle a -> Aff Unit
click h = Promise.toAffE $ _click h
click h = FFI.promiseToAff $ _click h
boundingBox :: forall a. IsElement a => Handle a -> Aff (Maybe BoundingBox)
boundingBox = map Nullable.toMaybe <<< Promise.toAffE <<< _boundingBox
boundingBox = map Nullable.toMaybe <<< FFI.promiseToAff <<< _boundingBox
hover :: forall a. IsElement a => Handle a -> Aff Unit
hover = Promise.toAffE <<< _hover
hover = FFI.promiseToAff <<< _hover
isHidden :: forall a. IsElement a => Handle a -> Aff Boolean
isHidden = Promise.toAffE <<< _isHidden
isHidden = FFI.promiseToAff <<< _isHidden
isVisible :: forall a. IsElement a => Handle a -> Aff Boolean
isVisible = Promise.toAffE <<< _isVisible
isVisible = FFI.promiseToAff <<< _isVisible
isIntersectingViewport :: forall a. IsElement a => Handle a -> Aff Boolean
isIntersectingViewport = Promise.toAffE <<< _isIntersectingViewport
isIntersectingViewport = FFI.promiseToAff <<< _isIntersectingViewport
drop :: forall a b. IsElement a => IsElement b => Handle a -> Handle b -> Aff Unit
drop a = Promise.toAffE <<< _drop a
drop a = FFI.promiseToAff <<< _drop a
screenshot :: forall a. IsElement a => ScreenshotOptions -> Handle a -> Aff Buffer
screenshot o = Promise.toAffE <<< _screenshot (prepareScreenshotOptions o)
screenshot o = FFI.promiseToAff <<< _screenshot (prepareScreenshotOptions o)
scrollIntoView :: forall a. IsElement a => Handle a -> Aff Unit
scrollIntoView = Promise.toAffE <<< _scrollIntoView
scrollIntoView = FFI.promiseToAff <<< _scrollIntoView
select :: forall a. IsElement a => Array String -> Handle a -> Aff Unit
select a = Promise.toAffE <<< _select a
select a = FFI.promiseToAff <<< _select a
tap :: forall a. IsElement a => Handle a -> Aff Unit
tap = Promise.toAffE <<< _tap
tap = FFI.promiseToAff <<< _tap
uploadFile :: Array FilePath -> Handle HTML.HTMLInputElement -> Aff Unit
uploadFile a = Promise.toAffE <<< _uploadFile a
uploadFile a = FFI.promiseToAff <<< _uploadFile a
waitForSelector :: forall a b s. Selector s b => IsElement a => s -> Handle a -> Aff (Handle b)
waitForSelector s = Promise.toAffE <<< _waitForSelector (Selector.toCSS s)
waitForSelector s = FFI.promiseToAff <<< _waitForSelector (Selector.toCSS s)
getProperties :: forall a. Handle a -> Aff (Map String (Handle Foreign))
getProperties = map FFI.makeMap <<< Promise.toAffE <<< _getProperties
getProperties = map FFI.makeMap <<< FFI.promiseToAff <<< _getProperties
toHTML :: forall a. Handle a -> Aff (Maybe (Handle HTMLElement))
toHTML h = do

View File

@ -16,6 +16,7 @@ import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Context(..), Keyboard)
import Puppeteer.Base (Keyboard) as X
import Puppeteer.FFI as FFI
import Simple.JSON (writeImpl)
type DownHint :: Symbol
@ -27,18 +28,18 @@ foreign import _press :: Foreign -> Nullable Int -> Keyboard -> Effect (Promise
foreign import _type :: String -> Nullable Int -> Keyboard -> Effect (Promise Unit)
up :: Key -> Keyboard -> Aff Unit
up k kb = Promise.toAffE $ _up (prepareKey k) kb
up k kb = FFI.promiseToAff $ _up (prepareKey k) kb
down :: Key -> Keyboard -> Aff (Context DownHint)
down k kb = do
Promise.toAffE $ _down (prepareKey k) kb
FFI.promiseToAff $ _down (prepareKey k) kb
pure $ Context (\_ -> up k kb)
press :: Key -> Keyboard -> Aff Unit
press k kb = Promise.toAffE $ _press (prepareKey k) Nullable.null kb
press k kb = FFI.promiseToAff $ _press (prepareKey k) Nullable.null kb
doType :: String -> Keyboard -> Aff Unit
doType s kb = Promise.toAffE $ _type s Nullable.null kb
doType s kb = FFI.promiseToAff $ _type s Nullable.null kb
data KeyMod
= KeyModMetaLeft

View File

@ -19,6 +19,7 @@ import Effect (Effect)
import Effect.Aff (Aff)
import Prim.Row (class Nub, class Union)
import Puppeteer.Base (Mouse)
import Puppeteer.FFI as FFI
import Record (merge, modify) as Record
import Type.Prelude (Proxy(..))
@ -41,42 +42,46 @@ type MouseMoveOptions r = (steps :: Number | r)
type MouseOptions r = (button :: MouseButton | r)
type MouseClickOptions r = (count :: Int, delay :: Number | MouseOptions r)
foreign import scrollImpl :: Mouse -> {deltaX :: Number, deltaY :: Number} -> Effect (Promise Unit)
foreign import clickImpl :: Mouse -> {x :: Number, y :: Number} -> {button :: String, count :: Int, delay :: Number} -> Effect (Promise Unit)
foreign import downImpl :: Mouse -> String -> Effect (Promise Unit)
foreign import upImpl :: Mouse -> String -> Effect (Promise Unit)
foreign import moveImpl :: Mouse -> {x :: Number, y :: Number} -> {steps :: Number} -> Effect (Promise Unit)
foreign import scrollImpl :: Mouse -> { deltaX :: Number, deltaY :: Number } -> Effect (Promise Unit)
foreign import clickImpl :: Mouse -> { x :: Number, y :: Number } -> { button :: String, count :: Int, delay :: Number } -> Effect (Promise Unit)
foreign import downImpl :: Mouse -> String -> Effect (Promise Unit)
foreign import upImpl :: Mouse -> String -> Effect (Promise Unit)
foreign import moveImpl :: Mouse -> { x :: Number, y :: Number } -> { steps :: Number } -> Effect (Promise Unit)
scroll :: forall options missing. Union options missing (MouseWheelOptions ()) => Union options (MouseWheelOptions ()) (MouseWheelOptions ()) => Record options -> Mouse -> Aff Unit
scroll options mouse = Promise.toAffE
$ scrollImpl mouse
$ Record.merge options {deltaX: 0.0, deltaY: 0.0}
scroll options mouse = FFI.promiseToAff
$ scrollImpl mouse
$ Record.merge options { deltaX: 0.0, deltaY: 0.0 }
down :: MouseButton -> Mouse -> Aff Unit
down btn mouse = Promise.toAffE $ downImpl mouse (mouseButtonToString btn)
down btn mouse = FFI.promiseToAff $ downImpl mouse (mouseButtonToString btn)
up :: MouseButton -> Mouse -> Aff Unit
up btn mouse = Promise.toAffE $ upImpl mouse (mouseButtonToString btn)
up btn mouse = FFI.promiseToAff $ upImpl mouse (mouseButtonToString btn)
moveTo :: forall options missing fullU. Nub fullU (MouseMoveOptions ())
=> Union options missing (MouseMoveOptions ())
=> Union options (MouseMoveOptions ()) fullU
=> Record options
-> Mouse
-> {x :: Number, y :: Number}
-> Aff Unit
moveTo opts mouse xy = Promise.toAffE
$ moveImpl mouse xy
$ Record.merge opts {steps: 1.0}
moveTo
:: forall options missing fullU
. Nub fullU (MouseMoveOptions ())
=> Union options missing (MouseMoveOptions ())
=> Union options (MouseMoveOptions ()) fullU
=> Record options
-> Mouse
-> { x :: Number, y :: Number }
-> Aff Unit
moveTo opts mouse xy = FFI.promiseToAff
$ moveImpl mouse xy
$ Record.merge opts { steps: 1.0 }
click :: forall options missing fullU. Nub fullU (MouseClickOptions ())
=> Union options missing (MouseClickOptions ())
=> Union options (MouseClickOptions ()) fullU
=> Record options
-> Mouse
-> {x :: Number, y :: Number}
-> Aff Unit
click opts mouse xy = Promise.toAffE
$ clickImpl mouse xy
$ Record.modify (Proxy @"button") mouseButtonToString
$ Record.merge opts {button: MouseLeft, count: 1, delay: 0.0}
click
:: forall options missing fullU
. Nub fullU (MouseClickOptions ())
=> Union options missing (MouseClickOptions ())
=> Union options (MouseClickOptions ()) fullU
=> Record options
-> Mouse
-> { x :: Number, y :: Number }
-> Aff Unit
click opts mouse xy = FFI.promiseToAff
$ clickImpl mouse xy
$ Record.modify (Proxy @"button") mouseButtonToString
$ Record.merge opts { button: MouseLeft, count: 1, delay: 0.0 }

View File

@ -93,23 +93,23 @@ set { name, value, url, domain, path, secure, sameSite, expires } p =
, expires: map (unwrap <<< Instant.unInstant) expires
}
in
Promise.toAffE $ _set o p
FFI.promiseToAff $ _set o p
delete :: CookieDelete -> Page -> Aff Unit
delete { name, url, domain, path } p =
let
o = writeImpl { name, url: FFI.maybeToUndefined url, domain: FFI.maybeToUndefined domain, path: FFI.maybeToUndefined path }
in
Promise.toAffE $ _delete o p
FFI.promiseToAff $ _delete o p
listForCurrentPage :: Page -> Aff (Array Cookie)
listForCurrentPage = map (Array.catMaybes <<< map cookieRaw) <<< Promise.toAffE <<< _list []
listForCurrentPage = map (Array.catMaybes <<< map cookieRaw) <<< FFI.promiseToAff <<< _list []
listForUrl :: URL -> Page -> Aff (Array Cookie)
listForUrl = listForUrls <<< pure
listForUrls :: NonEmptyArray URL -> Page -> Aff (Array Cookie)
listForUrls urls p = map (Array.catMaybes <<< map cookieRaw) $ Promise.toAffE $ _list (Array.NonEmpty.toArray urls) p
listForUrls urls p = map (Array.catMaybes <<< map cookieRaw) $ FFI.promiseToAff $ _list (Array.NonEmpty.toArray urls) p
cookieRaw :: CookieRaw -> Maybe Cookie
cookieRaw { domain, expires, path, url, name, value, sameSite, secure } = do

View File

@ -16,13 +16,13 @@ module Puppeteer.Page.Emulate
import Prelude
import Control.Promise (Promise)
import Control.Promise as Promise
import Data.Maybe (Maybe)
import Data.Newtype (class Newtype, unwrap)
import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Context(..), Handle, Page)
import Puppeteer.Base (Context(..), Page)
import Puppeteer.FFI as FFI
import Simple.JSON (undefined, writeImpl)
type NetworkConditions =
@ -93,41 +93,41 @@ type IdleHint :: Symbol
type IdleHint = "User idling is being emulated. Invoking `Puppeteer.closeContext` will undo this emulation."
device :: Device -> Page -> Aff Unit
device d p = Promise.toAffE $ _emulate (_knownDevice <<< knownDeviceString $ d) p
device d p = FFI.promiseToAff $ _emulate (_knownDevice <<< knownDeviceString $ d) p
cpuThrottling :: ThrottleFactor -> Page -> Aff (Context CpuThrottleHint)
cpuThrottling t p = do
Promise.toAffE $ _cpuThrottling (unwrap t) p
pure $ Context (\_ -> Promise.toAffE $ _cpuThrottling 1.0 p)
FFI.promiseToAff $ _cpuThrottling (unwrap t) p
pure $ Context (\_ -> FFI.promiseToAff $ _cpuThrottling 1.0 p)
idle :: Idle -> Page -> Aff (Context IdleHint)
idle UserInactive p = map (const $ Context (\_ -> unidle p)) <<< Promise.toAffE <<< _idle (writeImpl { isUserActive: false, isScreenUnlocked: true }) $ p
idle ScreenLocked p = map (const $ Context (\_ -> unidle p)) <<< Promise.toAffE <<< _idle (writeImpl { isScreenUnlocked: false, isUserActive: false }) $ p
idle UserInactive p = map (const $ Context (\_ -> unidle p)) <<< FFI.promiseToAff <<< _idle (writeImpl { isUserActive: false, isScreenUnlocked: true }) $ p
idle ScreenLocked p = map (const $ Context (\_ -> unidle p)) <<< FFI.promiseToAff <<< _idle (writeImpl { isScreenUnlocked: false, isUserActive: false }) $ p
idle NotIdle p = map (const mempty) $ unidle p
unidle :: Page -> Aff Unit
unidle = void <<< Promise.toAffE <<< _idle undefined
unidle = void <<< FFI.promiseToAff <<< _idle undefined
print :: Page -> Aff (Context PrintHint)
print p = do
Promise.toAffE $ _emulatePrint p
pure $ Context (\_ -> Promise.toAffE $ _unemulatePrint p)
FFI.promiseToAff $ _emulatePrint p
pure $ Context (\_ -> FFI.promiseToAff $ _unemulatePrint p)
network :: NetworkConditions -> Page -> Aff (Context NetworkHint)
network n p = do
Promise.toAffE $ _emulateNetwork n p
pure $ Context (\_ -> Promise.toAffE $ _unemulateNetwork p)
FFI.promiseToAff $ _emulateNetwork n p
pure $ Context (\_ -> FFI.promiseToAff $ _unemulateNetwork p)
--| https://pptr.dev/api/puppeteer.page.emulatetimezone
timezone :: String -> Page -> Aff (Context TimezoneHint)
timezone tz p = do
Promise.toAffE $ _emulateTimezone tz p
pure $ Context (\_ -> Promise.toAffE $ _unemulateTimezone p)
FFI.promiseToAff $ _emulateTimezone tz p
pure $ Context (\_ -> FFI.promiseToAff $ _unemulateTimezone p)
visionDeficiency :: VisionDeficiency -> Page -> Aff (Context VisionDeficiencyHint)
visionDeficiency d p = do
Promise.toAffE $ _emulateVisionDeficiency (visionDeficiencyString d) p
pure $ Context (\_ -> Promise.toAffE $ _unemulateVisionDeficiency p)
FFI.promiseToAff $ _emulateVisionDeficiency (visionDeficiencyString d) p
pure $ Context (\_ -> FFI.promiseToAff $ _unemulateVisionDeficiency p)
data VisionDeficiency
= BlurredVision

View File

@ -49,10 +49,10 @@ foreign import _accept :: Foreign -> Dialog -> Effect (Promise Unit)
foreign import _type :: Dialog -> String
dismiss :: Dialog -> Aff Unit
dismiss = Promise.toAffE <<< _dismiss
dismiss = FFI.promiseToAff <<< _dismiss
accept :: Maybe String -> Dialog -> Aff Unit
accept s = Promise.toAffE <<< _accept (FFI.maybeToUndefined s)
accept s = FFI.promiseToAff <<< _accept (FFI.maybeToUndefined s)
dialogType :: Dialog -> DialogType
dialogType = dialogTypeOfString <<< _type

View File

@ -102,7 +102,7 @@ foreign import _screenshot :: Foreign -> Page -> Effect (Promise Buffer)
foreign import _pdf :: Foreign -> Page -> Effect (Promise Buffer)
screenshot :: ScreenshotOptions -> Page -> Aff Buffer
screenshot o = Promise.toAffE <<< _screenshot (prepareScreenshotOptions o)
screenshot o = FFI.promiseToAff <<< _screenshot (prepareScreenshotOptions o)
pdf :: PdfOptions -> Page -> Aff Buffer
pdf o = Promise.toAffE <<< _pdf (preparePdfOptions o)
pdf o = FFI.promiseToAff <<< _pdf (preparePdfOptions o)

View File

@ -92,13 +92,13 @@ headers :: Request -> Effect (Map String String)
headers = map FFI.makeMap <<< _headers
abort :: Context InterceptRequestsHint -> ErrorCode -> Request -> Aff Unit
abort _ e = Promise.toAffE <<< _abort (errorCodeString e)
abort _ e = FFI.promiseToAff <<< _abort (errorCodeString e)
continue :: Context InterceptRequestsHint -> ContinueRequestOverrides -> Request -> Aff Unit
continue _ o = Promise.toAffE <<< _continue (prepareContinueRequestOverrides o)
continue _ o = FFI.promiseToAff <<< _continue (prepareContinueRequestOverrides o)
respond :: Context InterceptRequestsHint -> RespondToRequest -> Request -> Aff Unit
respond _ r = Promise.toAffE <<< _respond (prepareRespondToRequest r)
respond _ r = FFI.promiseToAff <<< _respond (prepareRespondToRequest r)
failure :: Request -> Effect (Maybe String)
failure = map (map _.errorText <<< Nullable.toMaybe) <<< _failure

View File

@ -12,6 +12,7 @@ import Effect.Aff (Aff)
import Foreign (Foreign)
import Node.Buffer (Buffer)
import Puppeteer.Base (Request, Response)
import Puppeteer.FFI as FFI
import Simple.JSON (readImpl)
foreign import request :: Response -> Effect Request
@ -27,13 +28,13 @@ foreign import _remoteAddressIp :: Response -> Effect Foreign
foreign import _remoteAddressPort :: Response -> Effect Foreign
bodyBuffer :: Response -> Aff Buffer
bodyBuffer = Promise.toAffE <<< _bodyBuffer
bodyBuffer = FFI.promiseToAff <<< _bodyBuffer
bodyJson :: Response -> Aff Foreign
bodyJson = Promise.toAffE <<< _bodyJson
bodyJson = FFI.promiseToAff <<< _bodyJson
bodyText :: Response -> Aff String
bodyText = Promise.toAffE <<< _bodyText
bodyText = FFI.promiseToAff <<< _bodyText
remoteAddressIp :: Response -> Effect (Maybe String)
remoteAddressIp = map (hush <<< runExcept) <<< map readImpl <<< _remoteAddressIp

View File

@ -44,18 +44,18 @@ type InterceptRequestsHint = "Requests are being intercepted. Invoking `Puppetee
bypassCsp :: Page -> Aff (Context BypassCSPHint)
bypassCsp p = do
Promise.toAffE $ _bypassCsp p
pure $ Context (\_ -> Promise.toAffE $ _unbypassCsp p)
FFI.promiseToAff $ _bypassCsp p
pure $ Context (\_ -> FFI.promiseToAff $ _unbypassCsp p)
disableCache :: Page -> Aff (Context DisableCacheHint)
disableCache p = do
Promise.toAffE $ _disableCache p
pure $ Context (\_ -> Promise.toAffE $ _enableCache p)
FFI.promiseToAff $ _disableCache p
pure $ Context (\_ -> FFI.promiseToAff $ _enableCache p)
interceptRequests :: Page -> Aff (Context InterceptRequestsHint)
interceptRequests p = do
Promise.toAffE $ _interceptRequests p
pure (Context $ \_ -> Promise.toAffE $ _uninterceptRequests p)
FFI.promiseToAff $ _interceptRequests p
pure (Context $ \_ -> FFI.promiseToAff $ _uninterceptRequests p)
interceptNextRequest :: (Context InterceptRequestsHint -> Request -> Aff Unit) -> Page -> Aff Unit
interceptNextRequest cb p = do
@ -66,4 +66,4 @@ interceptNextRequest cb p = do
pure unit
sendExtraHeaders :: Map String String -> Page -> Aff Unit
sendExtraHeaders h = Promise.toAffE <<< _sendExtraHeaders (FFI.mapToRecord h)
sendExtraHeaders h = FFI.promiseToAff <<< _sendExtraHeaders (FFI.mapToRecord h)

View File

@ -11,6 +11,7 @@ import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (LifecycleEvent(..), Page, URL, duplexLifecycleEvent, duplexWrite)
import Puppeteer.FFI as FFI
import Puppeteer.HTTP as HTTP
foreign import _forward :: Foreign -> Page -> Effect (Promise (Maybe HTTP.Response))
@ -19,16 +20,16 @@ foreign import _reload :: Foreign -> Page -> Effect (Promise (Maybe HTTP.Respons
foreign import _to :: String -> Foreign -> Page -> Effect (Promise (Maybe HTTP.Response))
forward :: LifecycleEvent -> Page -> Aff (Maybe HTTP.Response)
forward ev = Promise.toAffE <<< _forward (duplexWrite duplexLifecycleEvent ev)
forward ev = FFI.promiseToAff <<< _forward (duplexWrite duplexLifecycleEvent ev)
back :: LifecycleEvent -> Page -> Aff (Maybe HTTP.Response)
back ev = Promise.toAffE <<< _back (duplexWrite duplexLifecycleEvent ev)
back ev = FFI.promiseToAff <<< _back (duplexWrite duplexLifecycleEvent ev)
to :: LifecycleEvent -> Page -> URL -> Aff (Maybe HTTP.Response)
to ev p u = Promise.toAffE $ _to u (duplexWrite duplexLifecycleEvent ev) p
to ev p u = FFI.promiseToAff $ _to u (duplexWrite duplexLifecycleEvent ev) p
reload :: LifecycleEvent -> Page -> Aff (Maybe HTTP.Response)
reload ev = Promise.toAffE <<< _reload (duplexWrite duplexLifecycleEvent ev)
reload ev = FFI.promiseToAff <<< _reload (duplexWrite duplexLifecycleEvent ev)
forward_ :: Page -> Aff (Maybe HTTP.Response)
forward_ = forward Load

View File

@ -18,6 +18,7 @@ import Effect (Effect)
import Effect.Aff (Aff)
import Foreign (Foreign)
import Puppeteer.Base (Context(..), Handle, LifecycleEvent, Page, duplexWrite, duplexLifecycleEvent)
import Puppeteer.FFI as FFI
import Puppeteer.Selector (class Selector, toCSS)
newtype NetworkIdleFor = NetworkIdleFor Milliseconds
@ -39,13 +40,13 @@ navigation ev p = do
pure $ Context (\_ -> Promise.toAff $ promise)
networkIdle :: NetworkIdleFor -> Page -> Aff Unit
networkIdle i = Promise.toAffE <<< _networkIdle (unwrap $ unwrap i)
networkIdle i = FFI.promiseToAff <<< _networkIdle (unwrap $ unwrap i)
selector :: forall s e. Selector s e => s -> Page -> Aff (Handle e)
selector s = Promise.toAffE <<< _selectorToExist (toCSS s)
selector s = FFI.promiseToAff <<< _selectorToExist (toCSS s)
selectorToBeVisible :: forall s e. Selector s e => s -> Page -> Aff (Handle e)
selectorToBeVisible s = Promise.toAffE <<< _selector (toCSS s)
selectorToBeVisible s = FFI.promiseToAff <<< _selector (toCSS s)
selectorToBeHidden :: forall s e. Selector s e => s -> Page -> Aff Unit
selectorToBeHidden s = Promise.toAffE <<< _selectorToBeHidden (toCSS s)
selectorToBeHidden s = FFI.promiseToAff <<< _selectorToBeHidden (toCSS s)

View File

@ -42,6 +42,7 @@ import Foreign (Foreign, unsafeToForeign)
import Node.Path (FilePath)
import Puppeteer.Base (Page) as X
import Puppeteer.Base (class PageProducer, CDPSession, Handle, Keyboard, LifecycleEvent, Mouse, Page, URL, Viewport, duplexLifecycleEvent, duplexViewport, duplexWrite)
import Puppeteer.FFI as FFI
import Puppeteer.Handle (unsafeCoerceHandle)
import Puppeteer.Selector (class Selector, toCSS)
import Simple.JSON (readImpl, undefined, writeImpl)
@ -120,48 +121,48 @@ foreign import _title :: Page -> Effect (Promise String)
foreign import _viewport :: Page -> Foreign
new :: forall b. PageProducer b => b -> Aff Page
new = Promise.toAffE <<< _newPage <<< unsafeToForeign
new = FFI.promiseToAff <<< _newPage <<< unsafeToForeign
createCDPSession :: Page -> Aff CDPSession
createCDPSession = Promise.toAffE <<< _createCDPSession
createCDPSession = FFI.promiseToAff <<< _createCDPSession
authenticate :: { username :: String, password :: String } -> Page -> Aff Unit
authenticate creds = Promise.toAffE <<< _authenticate creds
authenticate creds = FFI.promiseToAff <<< _authenticate creds
all :: forall b. PageProducer b => b -> Aff (Array Page)
all = Promise.toAffE <<< _all <<< unsafeToForeign
all = FFI.promiseToAff <<< _all <<< unsafeToForeign
findAll :: forall s e. Selector s e => s -> Page -> Aff (Array (Handle e))
findAll s = Promise.toAffE <<< _findAll (toCSS s)
findAll s = FFI.promiseToAff <<< _findAll (toCSS s)
findFirst :: forall s e. Selector s e => s -> Page -> Aff (Maybe (Handle e))
findFirst s = map Array.head <<< findAll s
addScriptTag :: AddScript -> Page -> Aff (Handle HTMLScriptElement)
addScriptTag a = Promise.toAffE <<< _addScriptTag (prepareAddScript a)
addScriptTag a = FFI.promiseToAff <<< _addScriptTag (prepareAddScript a)
addStyleTag :: forall s e. AddStyle s e => s -> Page -> Aff (Handle e)
addStyleTag a h = do
t <- Promise.toAffE $ _addStyleTag (prepareAddStyle a) h
t <- FFI.promiseToAff $ _addStyleTag (prepareAddStyle a) h
pure $ unsafeCoerceHandle t
bringToFront :: Page -> Aff Unit
bringToFront = Promise.toAffE <<< _bringToFront
bringToFront = FFI.promiseToAff <<< _bringToFront
close :: Page -> Aff Unit
close = Promise.toAffE <<< _close
close = FFI.promiseToAff <<< _close
content :: Page -> Aff String
content = Promise.toAffE <<< _content
content = FFI.promiseToAff <<< _content
setContent :: String -> LifecycleEvent -> Page -> Aff Unit
setContent s ev = Promise.toAffE <<< _setContent s (duplexWrite duplexLifecycleEvent ev)
setContent s ev = FFI.promiseToAff <<< _setContent s (duplexWrite duplexLifecycleEvent ev)
setViewport :: Viewport -> Page -> Aff Unit
setViewport vp = Promise.toAffE <<< _setViewport (duplexWrite duplexViewport vp)
setViewport vp = FFI.promiseToAff <<< _setViewport (duplexWrite duplexViewport vp)
title :: Page -> Aff String
title = Promise.toAffE <<< _title
title = FFI.promiseToAff <<< _title
viewport :: Page -> Maybe Viewport
viewport = hush <<< runExcept <<< readImpl <<< _viewport

View File

@ -65,7 +65,7 @@ install :: forall (r :: Row Type). AdBlockOptions -> Puppeteer r -> Effect (Pupp
install o p = _install (prepareOptions o) p
blocker :: forall (r :: Row Type). Puppeteer (adblock :: AdBlockPlugin | r) -> Aff AdBlocker
blocker = Promise.toAffE <<< _blocker
blocker = FFI.promiseToAff <<< _blocker
cspInjectedH :: EventEmitter.EventHandle0 AdBlocker
cspInjectedH = EventEmitter.EventHandle "csp-injected" identity

View File

@ -291,24 +291,24 @@ infos f = do
findCaptchas :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Aff (Array CaptchaInfoMaybeFiltered)
findCaptchas _ p = do
f <- Promise.toAffE $ _findCaptchas p
f <- FFI.promiseToAff $ _findCaptchas p
liftEither $ infos f
getSolutions :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Array CaptchaInfo -> Aff (Array CaptchaSolution)
getSolutions _ p is = do
f <- Promise.toAffE $ _getSolutions p (writeImpl $ duplexWrite duplexInfo <$> is)
f <- FFI.promiseToAff $ _getSolutions p (writeImpl $ duplexWrite duplexInfo <$> is)
{ solutions } <- liftEither $ read @({ solutions :: Array Foreign }) f
liftEither $ for solutions $ duplexRead duplexSoln
enterSolutions :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Array CaptchaSolution -> Aff (Array CaptchaSolved)
enterSolutions _ p sols = do
f <- Promise.toAffE $ _enterSolutions p (writeImpl $ duplexWrite duplexSoln <$> sols)
f <- FFI.promiseToAff $ _enterSolutions p (writeImpl $ duplexWrite duplexSoln <$> sols)
{ solved } <- liftEither $ read @({ solved :: Array Foreign }) f
liftEither $ for solved $ duplexRead duplexSolved
solveCaptchas :: forall (r :: Row Type). Puppeteer (captcha :: CaptchaPlugin | r) -> Page -> Aff SolveResult
solveCaptchas _ p = do
f <- Promise.toAffE $ _solveCaptchas p
f <- FFI.promiseToAff $ _solveCaptchas p
{ solved, solutions } <- liftEither $ read @({ solved :: Array Foreign, solutions :: Array Foreign }) f
captchas <- liftEither $ infos f
liftEither do

View File

@ -169,25 +169,25 @@ foreign import _launch :: forall p. Foreign -> Puppeteer p -> Effect (Promise Br
--| [`PuppeteerExtra`](https://github.com/berstend/puppeteer-extra/blob/master/packages/puppeteer-extra/src/index.ts)
--| [`PuppeteerNode`](https://pptr.dev/api/puppeteer.puppeteernode)
new :: Aff (Puppeteer ())
new = Promise.toAffE _puppeteer
new = FFI.promiseToAff _puppeteer
--| Connect to an existing browser instance
--|
--| [`PuppeteerNode#connect`](https://pptr.dev/api/puppeteer.puppeteernode.connect)
connect :: forall p. Connect -> Puppeteer p -> Aff Browser
connect c = Promise.toAffE <<< _connect (prepareConnectOptions c)
connect c = FFI.promiseToAff <<< _connect (prepareConnectOptions c)
connect_ :: forall p. Puppeteer p -> Aff Browser
connect_ = Promise.toAffE <<< _connect (prepareLaunchOptions launchDefault)
connect_ = FFI.promiseToAff <<< _connect (prepareLaunchOptions launchDefault)
--| Launch a new browser instance
--|
--| [`PuppeteerNode#launch`](https://pptr.dev/api/puppeteer.puppeteernode.launch)
launch :: forall p. Launch -> Puppeteer p -> Aff Browser
launch l = Promise.toAffE <<< _launch (prepareLaunchOptions l)
launch l = FFI.promiseToAff <<< _launch (prepareLaunchOptions l)
launch_ :: forall p. Puppeteer p -> Aff Browser
launch_ = Promise.toAffE <<< _launch (prepareLaunchOptions launchDefault)
launch_ = FFI.promiseToAff <<< _launch (prepareLaunchOptions launchDefault)
launchNonHeadless :: forall p. Puppeteer p -> Aff Browser
launchNonHeadless = Promise.toAffE <<< _launch (prepareLaunchOptions $ launchDefault { headless = false })
launchNonHeadless = FFI.promiseToAff <<< _launch (prepareLaunchOptions $ launchDefault { headless = false })