Code Monkey home page Code Monkey logo

js-api-client's Introduction

Typeform JavaScript SDK

Pull Request

JS Client wrapper for Typeform API

Table of contents

Installation

# install with yarn
yarn add @typeform/api-client

# install with npm
npm install @typeform/api-client --save

Usage

In your project

  1. Import client library
// If using ESM syntax
import { createClient } from '@typeform/api-client'
// If using CJS syntax
const { createClient } = require('@typeform/api-client')
  1. Create an instance with your personal token
const typeformAPI = createClient({ token: '<your token>' })

If your account is configured to store responses in the EU Data Center you can pass the apiBaseUrl as https://api.eu.typeform.com.

const typeformAPI = createClient(
  {
    token: '<your token>',
    apiBaseUrl: 'https://api.eu.typeform.com'
  }
)
  1. Use any of the methods available in the reference
// will retrieve all forms
typeformAPI.forms.list().then((response) => {
  // do what do you want with your typeforms
})

Note: You can also execute the client binary directly via command line in your project:

yarn typeform-api <method> [params]

See next section for more details.

Via command line

  1. Clone this repo on your machine

  2. Install all dependencies:

yarn install
  1. Set your personal token as TF_TOKEN env variable
export TF_TOKEN=tfp_XXXXXXXXXX
  1. Run the client:
yarn typeform-api <method> [params]

See reference for all available method names and their params.

Example usage:

yarn typeform-api forms.list
yarn typeform-api forms.get '{uid:"abcd1234"}'
yarn typeform-api themes.list '{pageSize:3}'

Reference

createClient({token})

  • Creates a new instance of Typeform's JS client
  • Returns an instance with the methods described below
const typeformClient = createClient({ token: '<your token>' })

// If what you are trying to access doesn't require a token, you can construct the client without any argument
const typeformAPI = createClient()

If your account is configured to store responses in the EU Data Center you can pass the apiBaseUrl as https://api.eu.typeform.com.

const typeformAPI = createClient(
  {
    token: '<your token>',
    apiBaseUrl: 'https://api.eu.typeform.com'
  }
)

Client returns the following properties:

  • forms
  • images
  • teams
  • workspaces
  • themes
  • responses
  • webhooks

Each one of them encapsulates the operations related to it (like listing, updating, deleting the resource).

Forms

forms.list({ page: 1, pageSize = 10, search = '', page })

  • Get a list of your typeforms
  • Returns a list of typeforms with the payload referenced here.
  • You can set page: "auto" to automatically fetch all pages if there are more. It fetches with maximum pageSize: 200.

forms.get({ uid })

  • Get a typeform by UID
  • Returns a typeform with the payload referenced here.

forms.create({ data = {} })

forms.update({ uid, data = {}, override = false })

  • Update a typeform by UID
  • Returns a typeform with the payload referenced here.

forms.delete({ uid })

  • Deletes a typeform by UID

forms.copy({ uid, workspaceUrl })

  • Copies an existing typeform with UID
  • workspaceUrl (optional) The URL of a workspace to copy the typeform into.

forms.messages.get({ uid })

  • Get custom messages of the typeform with the given UID

forms.messages.update({ uid })

  • Updates custom messages of the typeform with the given UID

Images

images.list()

  • Get your images collection

images.get({ id, size, backgroundSize, choiceSize })

  • Get custom image by ID
  • size: default, thumbnail, mobile
  • backgroundSize: default, thumbnail, mobile, tablet
  • choiceSize: default, thumbnail, supersize, supermobile, supersizefit, supermobilefit

images.add({ image, url, fileName })

  • Add an image to Typeform
  • image: Base64 code for the image. Note that base64 encoders may add descriptors to the code (such as data:image/png;base64,). Do not include these descriptors in your image string---include only the base64 code. Use this or url (below)
  • url: URL of the image. Use this or image (above)
  • fileName: File name for the image

images.delete({ id })

  • Deletes an image with the given ID

Themes

themes.list({ page, pageSize })

  • Gets your themes collection
  • page: default 1
    • set page: "auto" to automatically fetch all pages if there are more, it fetches with maximum pageSize: 200
  • pageSize: default 10`

themes.get({ id })

  • Gets a theme for the given ID

themes.create({ background, colors, font, hasTransparentButton, name })

  • Creates a theme with the given configuration
  • See more details of the payload in the documentation

themes.update({ id, background, colors, font, hasTransparentButton, name })

  • Updates a theme with the given configuration, requires id
  • See more details of the payload in the documentation

themes.delete({ id })

  • Deletes the theme with the given ID

Workspaces

workspaces.add({ name })

  • Create a workspace.
  • name: Name of the new workspace.

workspaces.addMembers({ id, members })

  • Add members to a workspace for the given ID
  • id: Unique ID for the workspace.
  • members: string or an array that should be the email of the user
  • Adding multiple members at once is possible using an array of emails

workspaces.delete({ id })

  • Delete a workspace.
  • id: Unique ID for the workspace.

workspaces.get({ id })

  • Retrieve a workspace.
  • id: Unique ID for the workspace.

workspaces.list({ page, pageSize, search })

  • Retrieve all workspaces in your account.
  • page: The page of results to retrieve. Default 1 is the first page of results.
    • set page: "auto" to automatically fetch all pages if there are more, it fetches with maximum pageSize: 200
  • pageSize: Number of results to retrieve per page. Default is 10. Maximum is 200.
  • search: Returns items that contain the specified string.

workspaces.removeMembers({ id, members })

  • Remove members from a workspace for the given ID
  • members: string or an array that should be the email of the user
  • Removing multiple members at once is possible using an array of emails

workspaces.update({ id, data })

  • Update a workspace.
  • id: Unique ID for the workspace.
  • data: Patch operation to perform in an array structure. See more details in the documentation

Responses

responses.delete({ uid, ids })

  • Delete responses to a form.
  • uid: Unique ID for the form.
  • ids: Tokens of the responses to delete. You can list up to 1000 tokens. Accepts either a string or an array of strings.

responses.list({ uid, pageSize, since, until, after, before, ids, completed, sort, query, fields })

  • Returns form responses and date and time of form landing and submission.
  • uid: Unique ID for the form.
  • pageSize: Maximum number of responses. Default value is 25. Maximum value is 1000.
  • page: Set to "auto" to automatically fetch all pages if there are more. It fetches with maximum pageSize: 1000. The after value is ignored when automatic paging is enabled. The responses will be sorted in the order that our system processed them (instead of the default order, submitted_at). Note that it does not accept numeric value to identify page number.
  • since: Limit request to responses submitted since the specified date and time. In ISO 8601 format, UTC time, to the second, with T as a delimiter between the date and time.
  • until: Limit request to responses submitted until the specified date and time. In ISO 8601 format, UTC time, to the second, with T as a delimiter between the date and time.
  • after: Limit request to responses submitted after the specified token. If you use the after parameter, the responses will be sorted in the order that our system processed them (instead of the default order, submitted_at).
  • before: Limit request to responses submitted before the specified token. If you use the before parameter, the responses will be sorted in the order that our system processed them (instead of the default order, submitted_at).
  • ids: Limit request to the specified ids. Accepts either a string or an array of strings.
  • completed: true if form was submitted. Otherwise, false.
  • sort: Order of responses. Currently, responses are automatically sorted by submitted_at,desc---the date they were submitted, from newest to oldest. We plan to add more options for sort order soon.
  • query: Limit request to only responses that that include the specified string. You can specify any string as the query value. The string will be escaped, and the query will include Hidden Fields.
  • fields: Limit request to only responses for the specified fields. Accepts either a string or an array of strings.
  • For parameter details check the documentation

Insights

insights.summary({ uid })

  • Returns form level and individual question level insights for a given form.
  • uid: Unique ID for the form.

Webhooks

webhooks.create({ uid, tag, url, enabled = false, secret, verifySSL })

  • Create a webhook.
  • uid: Unique ID for the form.
  • tag: Unique name you want to use for the webhook.
  • url: Webhook URL.
  • enabled: true if you want to send responses to the webhook immediately. Otherwise, false.
  • secret: If specified, will be used to sign the webhook payload with HMAC SHA256, so that you can verify that it came from Typeform. (Recommended to add security)
  • verifySSL: true if you want Typeform to verify SSL certificates when delivering payloads.

webhooks.delete({ uid, tag })

  • Delete a webhook.
  • uid: Unique ID for the form.
  • tag: Unique name of the webhook.

webhooks.get({ uid, tag })

  • Get details for a webhook with the given tag
  • uid: Unique ID for the form.
  • tag: tag of the webhook created

webhooks.list({ uid })

  • Retrieve all webhooks for the specified typeform.
  • uid: Unique ID for the form.

webhooks.update({ uid, tag, url, enabled = false, secret, verifySSL })

  • Update a webhook.
  • uid: Unique ID for the form.
  • tag: Unique name you want to use for the webhook.
  • url: Webhook URL.
  • enabled: true if you want to send responses to the webhook immediately. Otherwise, false.
  • secret: If specified, will be used to sign the webhook payload with HMAC SHA256, so that you can verify that it came from Typeform.
  • verifySSL: true if you want Typeform to verify SSL certificates when delivering payloads.

webhooks.toggle({ uid, tag, enabled })

  • Turn on or off a webhook.
  • uid: Unique ID for the form.
  • tag: tag of the webhook created.
  • enabled: true or false.

Examples

Update specific typeform property, as referenced here

typeformClient.forms
  .update({
    uid: 'asdf',
    data: [
      {
        op: 'replace',
        path: '/title',
        value: 'new title',
      },
    ],
  })
  .then((response) => {
    //...
  })

Update the whole typeform

typeformClient.forms
  .update({
    uid: 'asdf',
    override: true,
    data: {
      title: newTitle,
      theme: {
        href: 'https://api.typeform.com/themes/6lPNE6',
      },
    },
  })
  .then((response) => {
    //...
  })

Note: The theme property applies a theme to the form. If you don't specify a value for the 'theme' property, Typeform applies a new copy of the default theme to the form, even if you already have a copy of the default theme applied to this form.

Uploading an image

typeformClient.images
  .add({
    image: 'bGRqZmxzZGpmbHNoZmtoc2RrZmpoc2tqZA==',
    mediaType: 'image/gif',
    fileName: 'newimage.gif',
  })
  .then((response) => {
    //...
  })

Getting the thumbnail of an image

typeformClient.images
  .get({ id: 'asdf', size: 'thumbnail' })
  .then((response) => {
    //...
  })

Testing

To run unit tests.

yarn install

# Runs unit tests
yarn test:unit

Suggestions or feedback

Feel free to open a Github issue.

js-api-client's People

Contributors

beomseo avatar blackpanther99 avatar gierlas avatar gurpreetatwal avatar ivanovyordan avatar jepser avatar jwtd avatar kb-typeform avatar lexswed avatar lussn avatar mathio avatar michaelsolati avatar michizhou avatar mohammadhh avatar mumpo avatar nathan78906 avatar nicolaslwilson avatar picsoung avatar rubentypeform avatar seti-tf avatar snyk-bot avatar sshah98 avatar strikerrus avatar supertinou avatar tf-scott avatar tf-security avatar thr44 avatar trapped avatar vrybas avatar xespona avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

js-api-client's Issues

Consistency between API and SDK (Form page size)

On Create API, to retrieve forms.

/forms endpoint on the api forms.list function in the SDK.

parameter for page size is page_size in the API, but pageSize in the SDK.
Not really consistent.

What should be done?

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Support for auth flow for apps (get `temporary_authorization_code`, `access_token`, `refresh_token`)

Description

Handling the refresh token mechanism could be cumbersome. Let's simplify it for developers.

Context

Developers are free to decide when access tokens issued for their apps will expire. The default is 7 days.
On the OAuth payload, we send back an expires_in property to tell when the token expires. This is a timestamp.
We also send back a refresh_token that needs to be used to request a new token.

Possible Solution

two functions, one to check if there is a need to renew token, and one to renew it.

client.needToRefreshToken(expires_in)
client.refreshToken(refresh_token)

##Questions
Should we rewrite the Client object to store also the client id and client secret details about an app?
What should be the interface for those functions?

The automated release is failing 🚨

🚨 The automated release from the master branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit the master branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


The push permission to the Git repository is required.

semantic-release cannot push the version tag to the branch master on remote Git repository.

Please refer to the authentication configuration documentation to configure the Git credentials on your CI environment.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

The automated release is failing 🚨

🚨 The automated release from the beta branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you can benefit from your bug fixes and new features again.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can fix this πŸ’ͺ.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the beta branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here are some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


No npm token specified.

An npm token must be created and set in the NPM_TOKEN environment variable on your CI environment.

Please make sure to create an npm token and to set it in the NPM_TOKEN environment variable on your CI environment. The token must allow to publish to the registry https://registry.npmjs.org/.


Good luck with your project ✨

Your semantic-release bot πŸ“¦πŸš€

Add create API for forms

At the moment the create form endpoint is not covered by this SDK.

Would be awesome if it was.

after ignored when listing responses

When listing responses, it always return the same results, no matter what the after parameter is:

client.responses.list({
  uid: 'LOJytd',
  page_size: 25,
  after: '8f2794e1b3842d500430a6d8b412059a'
})

or

client.responses.list({
  uid: 'LOJytd',
  page_size: 25
})

It even returns the same list when the parameter after is not a real token.

Type incorrect for choice under ansers

Description

Choice is defined as

      choice?: {
        label?: string
        other?: string
      }
``` under Response. However the choice that comes back from the API contains an ID looking like 

      choice: {
        id: 'eq9kDOfvqmEe',
        label: 'Improve my day to day vitality'
      }

Adding insights api

Description

Hi, can you please add support to insights api with typescripts?
Also, is there an option to add parameters to the api, such as: since, until...

Context

It will be very useful and kind of complete the sdk.

Possible Solution

I implement it by myself with the rest api so its basically straightforward as the other Implementations.

Screenshots

Improved error message: "The pyaload is invalid"

Description

I've received the below error without much detail when calling forms.create.

Error: The payload is invalid.
>      at /Users/fooboo/Deploy/Agentnoon/node_modules/@typeform/api-client/dist/index.cjs.js:3663:27
>      at processTicksAndRejections (internal/process/task_queues.js:95:5)
>      at async /Users/fooboo/Deploy/Agentnoon/functions/node_modules/firebase-functions/lib/common/providers/https.js:385:26
>      at async runFunction (/Users/fooboo/.nvm/versions/node/v14.18.1/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:533:9)
>      at async runHTTPS (/Users/fooboo/.nvm/versions/node/v14.18.1/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:559:5)
>      at async handler (/Users/fooboo/.nvm/versions/node/v14.18.1/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:479:17)

Turns out, my workspace property was incorrect. But it'd have been nice if the API provided more details on which part of the payload is incorrect.

Thanks!
Dave

Form interface does not match api results

Description

Form interface does not match api response

        Types of property 'formConfigBlob' are incompatible.
          Object literal may only specify known properties, and 'self' does not exist in type 'Form'.

Expected Behavior

self should be included as a property in Form interface

Your Environment

  • Client Version: latest
  • Node.js Version: 20+
  • Operating System and Version: MacOS Sonoma v14

Form deletion throws error

Hello,

Deleting a form throw the following error:

FetchError: invalid json response body at https://api.typeform.com/forms/Uq4A3F reason: Unexpected end of JSON input

Am I wrong or 204 No Content responses are not handled ?

`Response` type is missing pagination data

Description

I'm trying to paginate through the output of typeform.responses.list, but for some reason, the Response type does not include the token field, that is required for the before and after parameters of list endpoint.

Expected Behavior

The typings match the return values of the API.

Current Behavior

The typings are incomplete and hacks like (response as any).token are necessary to access the data we need.

Possible Solution

Correct the typings to match the API.

Steps to Reproduce

n/a

Screenshots

n/a

Your Environment

  • Client Version: 2.4.1
  • Node.js Version: v18.16.1
  • NPM Version: 9.5.1

127.0.0.1/CORS access issue

Hey guys, trying to use the api wrapper locally but encountering a few issues. Stack is Flask + React. Error I'm getting is:

Uncaught (in promise) Error: Couldn't make requestAccess to XMLHttpRequest at 'https://api.typeform.com/forms' from origin 'http://127.0.0.1:3000' has been blocked by CORS policy

const typeformAPI = createClient({ token: "myToken" })

function getFormData() {
    typeformAPI.forms
    .list()
    .then(response => {
      console.log(response);
    })    
}


export default function TypeformQuickQuote() {
    
    return (
        <div>
            <h3>Typeform Quick Quote</h3>
            <div>{getFormData()}</div>
        </div>
    )
}

What am I missing here?

Choice interface doesn't match API results

Description

Response.answers.choice.other was removed in 1.12.1. However, if you have a Multiple Choice with Multiple selection disabled and "Other" option enabled, the API still returns in the structure:

"choice": { "id": "other", "other": "foo bar" }

Expected Behavior

I would expect the API's interfaces allow a developer to collect answer.choice.other if the API returns that structure.

Possible Solution

Could add other field to Choice interface.

Steps to Reproduce

With a Multiple Choice answer with Multiple selection disabled and "Other" option enabled, it was previously read by using answer.choice.other but this no longer compiles.

Your Environment

  • Client Version: 1.12.1 thru at least 1.15.2

workspace.addMembers - content_type_invalid

Hey πŸ‘‹

When using the SDK to add members to a workspace

typeform.workspaces.addMembers({
        id: WORKSPACE_ID,
        members: [email]
      }).then(function(result){
        console.log("add member result", result)
      }).catch(function(error){
        console.log("add member error", error)
      })

I receive this error

{ code: 'content_type_invalid',
  description: '() are not valid content types for this request, try any of (application/json)',
  help: 'https://developer.typeform.com' }

Looking at the code I don't see anything about content-type.

Best

Request: More descriptive errors when a failure occurs

Description

Should an error occur (including but not limited to a networking timeout), the client throws a pretty generic error that makes troubleshooting pretty difficult.

See https://github.com/Typeform/js-api-client/blob/master/src/create-client.ts#L39.

Context

I recently worked on a project where I was hitting this error case, and it was very difficult to pinpoint the cause of the issue. Having a more descriptive error would have been really helpful.

Possible Solution

Handle all the axios error cases and form more descriptive errors - something along the lines of the following:

        .catch((error: any) => {
          if (error && error.response && error.response.data && error.response.data.description) {
            throw new Error(`Internal error - ${error.response.data.description}`)
          } else if (error.response) {
            const resp = error.response
            throw new Error(`"status": "${resp.status}", "data": "${resp.data}"`)
          } else if (error.request) {
            const url = error.config.url
            const httpSummary = {
              message: error.message,
              errno: error.errorSummary,
              code: error.code,
              syscall: error.syscall,
              address: error.address,
              port: error.port,
              url: url.substr(0, url.indexOf('?')) // Don't log query params
            }

            throw new Error(JSON.stringify(httpSummary))
          } else {
            throw new Error(`Internal error - request set up error: ${error.message}`)
          }
        })

Knowing the specific http request/status causing the error would be really helpful.

Global Leak

When you run Mocha with --check-leaks your tests are going to fail because the isomorphic-fetch library mutates the global fetch.

Error: global leaks detected: fetch, Response, Headers, Request

Add types for Typescript

Description

Add typescript types to this library.
Preferably in the form of a built in .d.ts file or otherwise as a separate @types/typeform package.

Context

In #25, @MichaelSolati pushed a complete rewrite of the library.

Rather than changing the current codebase, a type definition of the current API would be more than adequate!
It would benefit Typeform's API ecosystem, current and potential developers to have a strict, public type definition of the API.

Possible Solution

Breifly looking at src, it seems this library isn't automatically generated based of a spec (correct me if i'm wrong).
The README is well defined though. Assuming there's some sort of internal definition for the backend, it could be useful to manually or automatically generate the type surface.

Current Solution

//@ts-ignore ... πŸ˜’
import { createClient } from '@typeform/api-client'

API returns incorrectly sorted duplicate entries

Hey !

I'm not sure if this is intended behavior but while trying to extract all answers I'm getting duplicate values. However, I get different behaviors with different paginations.


Basically, I have ~50 forms with some containing thousands of answers. When trying to get answers for each forms, I sometimes get duplicate values when my pagination is above 100. Furthermore, I don't get the same duplicates if I sort the answers by default or not.

Below is an example of fetching the answers for a form with a few thousands answers:

[
  { /* non duplicate answer */ },
  {
    "landing_id": "0796d29dcdd7f8a55378eec5ad2e87cf",
    "token": "0796d29dcdd7f8a55378eec5ad2e87cf",
    "response_id": "0796d29dcdd7f8a55378eec5ad2e87cf",
    "landed_at": "2019-04-18T08:42:34Z",
    "submitted_at": "2019-04-18T08:43:34Z",
    "metadata": {
      "user_agent": "...",
      "platform": "other",
      "referer": "https://xxx.typeform.com/to/abc",
      "network_id": "abc",
      "browser": "default"
    },
    "answers": [{
      "field": {
        "id": "123",
        "type": "picture_choice",
        "ref": "c4c30a62-447e-4a9a-9571-c03d03f778eb"
      },
      "type": "choice",
      "choice": {
        "label": "2"
      }
    }]
  },
  { /* non duplicate answers with incoherent sorting* */ },
  {
    "landing_id": "0796d29dcdd7f8a55378eec5ad2e87cf",
    "token": "0796d29dcdd7f8a55378eec5ad2e87cf",
    "response_id": "0796d29dcdd7f8a55378eec5ad2e87cf",
    "landed_at": "2019-04-18T08:42:34Z",
    "submitted_at": "2019-04-18T08:43:34Z",
    "metadata": {
      "user_agent": "...",
      "platform": "other",
      "referer": "https://xxx.typeform.com/to/abc",
      "network_id": "abc",
      "browser": "default"
    },
    "answers": [{
      "field": {
        "id": "123",
        "type": "picture_choice",
        "ref": "c4c30a62-447e-4a9a-9571-c03d03f778eb"
      },
      "type": "choice",
      "choice": {
        "label": "2"
      }
    }]
  },
]

*incoherent sorting means here that a few entries after the duplicate one are correctly sorted (in this case with the default sort) but will jump to a seemingly random date after. Also note that the duplicate entries have the same dates but are not one after the other.

To get each page, I do the following:
const { total_items, items } = await client.responses.list({ uid, before, completed: true })

Thanks for the help, wish y'all a nice day

Typeform API client not compatible with Cloudflare workers / Vercel edge runtime

The current version of the Typeform API client does not run well on a Cloudflare worker / Vercel edge runtime. Creating a client result in the following error:

ReferenceError: window is not defined
    at (../../../../node_modules/.pnpm/@[email protected]/node_modules/@typeform/api-client/dist/typeform-api.js:1:209)
    at (../../../../node_modules/.pnpm/@[email protected]/node_modules/@typeform/api-client/dist/typeform-api.js:1:68)
    at (../../../../node_modules/.pnpm/@[email protected]/node_modules/@typeform/api-client/dist/typeform-api.js:1:170)
...

This is most probably caused by the (3 year old..) dependency to Axios. A switch to fetch should not only resolve the compatibility issue, but render the project free from build dependencies.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.