From e3bdd3342d5d992dbb4db0e52de405ca37de90d4 Mon Sep 17 00:00:00 2001 From: Dinesh Kashikar Date: Wed, 10 Jan 2024 13:56:14 +0530 Subject: [PATCH 1/5] added QRcode block --- .../forge/blocks/qrcode/actions/displayQr.ts | 37 +++++++++++++++++++ packages/forge/blocks/qrcode/index.ts | 11 ++++++ packages/forge/blocks/qrcode/logo.tsx | 16 ++++++++ packages/forge/blocks/qrcode/package.json | 18 +++++++++ packages/forge/blocks/qrcode/tsconfig.json | 10 +++++ packages/forge/repository/index.ts | 1 + packages/forge/schemas/index.ts | 2 + packages/forge/schemas/package.json | 3 +- pnpm-lock.yaml | 29 +++++++++++++++ 9 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 packages/forge/blocks/qrcode/actions/displayQr.ts create mode 100644 packages/forge/blocks/qrcode/index.ts create mode 100644 packages/forge/blocks/qrcode/logo.tsx create mode 100644 packages/forge/blocks/qrcode/package.json create mode 100644 packages/forge/blocks/qrcode/tsconfig.json diff --git a/packages/forge/blocks/qrcode/actions/displayQr.ts b/packages/forge/blocks/qrcode/actions/displayQr.ts new file mode 100644 index 0000000000..3d9a256a44 --- /dev/null +++ b/packages/forge/blocks/qrcode/actions/displayQr.ts @@ -0,0 +1,37 @@ +import { createAction, option } from "@typebot.io/forge"; +import qrcode from "qrcode-generator"; + + +export const displayQr = createAction({ + name: 'Display Qr', + options: option.object({ + qrvalue: option.string.layout({ + label: 'Qr Code', + helperText: 'QR code to show' + }), + qrlink: option.string.layout({ + label: 'Qr link', + helperText: 'Link to goto on tapping QR code' + }), + }), + run: { + web: { + displayEmbedBubble: { + parseInitFunction: ({ options }) => { + if (!options.qrvalue) throw new Error('Missing Qr Code') + var qr = qrcode(8, 'L'); + qr.addData(options.qrvalue); + qr.make(); + const qrvalue = qr.createDataURL(); + return { + args: { + qrvalue: qrvalue, + qrlink: options.qrlink ?? null + }, + content: `let qr = document.createElement("img");qr.src = qrvalue;qr.classList.add('w-full');; let link = document.createElement("a"); link.href = qrlink; link.target = '_blank'; link.appendChild(qr); typebotElement.appendChild(qrlink ? link : qr);`, + } + }, + }, + } + }, +}) diff --git a/packages/forge/blocks/qrcode/index.ts b/packages/forge/blocks/qrcode/index.ts new file mode 100644 index 0000000000..539abdea25 --- /dev/null +++ b/packages/forge/blocks/qrcode/index.ts @@ -0,0 +1,11 @@ +import { createBlock } from '@typebot.io/forge' +import { QrcodeLogo } from './logo' +import { displayQr } from './actions/displayQr' + +export const qrcode = createBlock({ + id: 'qrcode', + name: 'QRcode', + tags: ['QR Code', 'Scan'], + LightLogo: QrcodeLogo, + actions: [displayQr] +}) diff --git a/packages/forge/blocks/qrcode/logo.tsx b/packages/forge/blocks/qrcode/logo.tsx new file mode 100644 index 0000000000..01aaf50221 --- /dev/null +++ b/packages/forge/blocks/qrcode/logo.tsx @@ -0,0 +1,16 @@ +import React from 'react' + +export const QrcodeLogo = (props: React.SVGProps) => ( + + + + +) diff --git a/packages/forge/blocks/qrcode/package.json b/packages/forge/blocks/qrcode/package.json new file mode 100644 index 0000000000..b2f444b66b --- /dev/null +++ b/packages/forge/blocks/qrcode/package.json @@ -0,0 +1,18 @@ +{ + "name": "@typebot.io/qrcode-block", + "version": "1.0.0", + "description": "", + "main": "index.ts", + "keywords": [], + "license": "ISC", + "devDependencies": { + "@typebot.io/forge": "workspace:*", + "@typebot.io/lib": "workspace:*", + "@typebot.io/tsconfig": "workspace:*", + "@types/react": "18.2.15", + "typescript": "5.3.2" + }, + "dependencies": { + "qrcode-generator": "^1.4.4" + } +} diff --git a/packages/forge/blocks/qrcode/tsconfig.json b/packages/forge/blocks/qrcode/tsconfig.json new file mode 100644 index 0000000000..1eb9c77172 --- /dev/null +++ b/packages/forge/blocks/qrcode/tsconfig.json @@ -0,0 +1,10 @@ +{ + "extends": "@typebot.io/tsconfig/base.json", + "include": ["**/*.ts", "**/*.tsx"], + "exclude": ["node_modules"], + "compilerOptions": { + "lib": ["ESNext", "DOM"], + "noEmit": true, + "jsx": "react" + } +} diff --git a/packages/forge/repository/index.ts b/packages/forge/repository/index.ts index 87264298c4..afa12b3f06 100644 --- a/packages/forge/repository/index.ts +++ b/packages/forge/repository/index.ts @@ -4,4 +4,5 @@ export const enabledBlocks = [ 'zemantic-ai', 'cal-com', 'chat-node', + 'qrcode', ] as const diff --git a/packages/forge/schemas/index.ts b/packages/forge/schemas/index.ts index 90d8a3ff34..ac4b5d5f2f 100644 --- a/packages/forge/schemas/index.ts +++ b/packages/forge/schemas/index.ts @@ -1,4 +1,5 @@ // Do not edit this file manually +import { qrcode } from '@typebot.io/qrcode-block' import { chatNode } from '@typebot.io/chat-node-block' import { calCom } from '@typebot.io/cal-com-block' import { zemanticAi } from '@typebot.io/zemantic-ai-block' @@ -16,6 +17,7 @@ export const forgedBlocks = [ zemanticAi, calCom, chatNode, + qrcode, ] as BlockDefinition<(typeof enabledBlocks)[number], any, any>[] export type ForgedBlockDefinition = (typeof forgedBlocks)[number] diff --git a/packages/forge/schemas/package.json b/packages/forge/schemas/package.json index 8540163343..12e8bad888 100644 --- a/packages/forge/schemas/package.json +++ b/packages/forge/schemas/package.json @@ -12,6 +12,7 @@ "@typebot.io/openai-block": "workspace:*", "@typebot.io/zemantic-ai-block": "workspace:*", "@typebot.io/cal-com-block": "workspace:*", - "@typebot.io/chat-node-block": "workspace:*" + "@typebot.io/chat-node-block": "workspace:*", + "@typebot.io/qrcode-block": "workspace:*" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 533800c6a1..ef7f0e369d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1231,6 +1231,28 @@ importers: specifier: 5.3.2 version: 5.3.2 + packages/forge/blocks/qrcode: + dependencies: + qrcode-generator: + specifier: ^1.4.4 + version: 1.4.4 + devDependencies: + '@typebot.io/forge': + specifier: workspace:* + version: link:../../core + '@typebot.io/lib': + specifier: workspace:* + version: link:../../../lib + '@typebot.io/tsconfig': + specifier: workspace:* + version: link:../../../tsconfig + '@types/react': + specifier: 18.2.15 + version: 18.2.15 + typescript: + specifier: 5.3.2 + version: 5.3.2 + packages/forge/blocks/zemanticAi: devDependencies: '@typebot.io/forge': @@ -1302,6 +1324,9 @@ importers: '@typebot.io/openai-block': specifier: workspace:* version: link:../blocks/openai + '@typebot.io/qrcode-block': + specifier: workspace:* + version: link:../blocks/qrcode '@typebot.io/zemantic-ai-block': specifier: workspace:* version: link:../blocks/zemanticAi @@ -18033,6 +18058,10 @@ packages: resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} dev: true + /qrcode-generator@1.4.4: + resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} + dev: false + /qs@6.11.0: resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} engines: {node: '>=0.6'} From c44fd07aad54fb8aed18a649925ffe840908b239 Mon Sep 17 00:00:00 2001 From: Dinesh Kashikar Date: Wed, 10 Jan 2024 15:48:16 +0530 Subject: [PATCH 2/5] changed QR Code generator to a convertor --- .../forge/blocks/qrcode/actions/convertQr.ts | 35 ++++++ .../forge/blocks/qrcode/actions/displayQr.ts | 37 ------ packages/forge/blocks/qrcode/index.ts | 6 +- packages/forge/blocks/qrcode/logo.tsx | 8 +- packages/forge/blocks/qrcode/package.json | 5 +- pnpm-lock.yaml | 108 ++++++++++++++++-- 6 files changed, 142 insertions(+), 57 deletions(-) create mode 100644 packages/forge/blocks/qrcode/actions/convertQr.ts delete mode 100644 packages/forge/blocks/qrcode/actions/displayQr.ts diff --git a/packages/forge/blocks/qrcode/actions/convertQr.ts b/packages/forge/blocks/qrcode/actions/convertQr.ts new file mode 100644 index 0000000000..49b39d27b8 --- /dev/null +++ b/packages/forge/blocks/qrcode/actions/convertQr.ts @@ -0,0 +1,35 @@ +import { createAction, option } from "@typebot.io/forge"; +import QRCode from 'qrcode' + +export const convertQr = createAction({ + name: 'Convert Qr', + options: option.object({ + qrvalue: option.string.layout({ + label: 'Data', + isRequired: true, + helperText: 'Data to convert into QR Code' + }), + saveQrcodeInVariableId: option.string.layout({ + label: 'QR Code', + inputType: 'variableDropdown', + }), + }), + getSetVariableIds: (options) => + options.saveQrcodeInVariableId ? [options.saveQrcodeInVariableId] : [], + run: { + server: async ({ options, variables, logs }) => { + if (!options.qrvalue) return logs.add('Qr code value is empty') + if (!options.saveQrcodeInVariableId) + return logs.add('Qr Code save variable is empty') + + let qrcode = '' + try { + qrcode = await QRCode.toDataURL(options.qrvalue) + } catch (error) { + return logs.add(`${error}`) + } + + variables.set(options.saveQrcodeInVariableId, qrcode) + }, + }, +}) diff --git a/packages/forge/blocks/qrcode/actions/displayQr.ts b/packages/forge/blocks/qrcode/actions/displayQr.ts deleted file mode 100644 index 3d9a256a44..0000000000 --- a/packages/forge/blocks/qrcode/actions/displayQr.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { createAction, option } from "@typebot.io/forge"; -import qrcode from "qrcode-generator"; - - -export const displayQr = createAction({ - name: 'Display Qr', - options: option.object({ - qrvalue: option.string.layout({ - label: 'Qr Code', - helperText: 'QR code to show' - }), - qrlink: option.string.layout({ - label: 'Qr link', - helperText: 'Link to goto on tapping QR code' - }), - }), - run: { - web: { - displayEmbedBubble: { - parseInitFunction: ({ options }) => { - if (!options.qrvalue) throw new Error('Missing Qr Code') - var qr = qrcode(8, 'L'); - qr.addData(options.qrvalue); - qr.make(); - const qrvalue = qr.createDataURL(); - return { - args: { - qrvalue: qrvalue, - qrlink: options.qrlink ?? null - }, - content: `let qr = document.createElement("img");qr.src = qrvalue;qr.classList.add('w-full');; let link = document.createElement("a"); link.href = qrlink; link.target = '_blank'; link.appendChild(qr); typebotElement.appendChild(qrlink ? link : qr);`, - } - }, - }, - } - }, -}) diff --git a/packages/forge/blocks/qrcode/index.ts b/packages/forge/blocks/qrcode/index.ts index 539abdea25..98d0df8f09 100644 --- a/packages/forge/blocks/qrcode/index.ts +++ b/packages/forge/blocks/qrcode/index.ts @@ -1,11 +1,11 @@ import { createBlock } from '@typebot.io/forge' import { QrcodeLogo } from './logo' -import { displayQr } from './actions/displayQr' +import { convertQr } from './actions/convertQr' export const qrcode = createBlock({ id: 'qrcode', name: 'QRcode', - tags: ['QR Code', 'Scan'], + tags: ['QR Code'], LightLogo: QrcodeLogo, - actions: [displayQr] + actions: [convertQr] }) diff --git a/packages/forge/blocks/qrcode/logo.tsx b/packages/forge/blocks/qrcode/logo.tsx index 01aaf50221..1b78e03062 100644 --- a/packages/forge/blocks/qrcode/logo.tsx +++ b/packages/forge/blocks/qrcode/logo.tsx @@ -3,13 +3,13 @@ import React from 'react' export const QrcodeLogo = (props: React.SVGProps) => ( diff --git a/packages/forge/blocks/qrcode/package.json b/packages/forge/blocks/qrcode/package.json index b2f444b66b..04cc529846 100644 --- a/packages/forge/blocks/qrcode/package.json +++ b/packages/forge/blocks/qrcode/package.json @@ -10,9 +10,10 @@ "@typebot.io/lib": "workspace:*", "@typebot.io/tsconfig": "workspace:*", "@types/react": "18.2.15", + "@types/qrcode": "^1.5.3", "typescript": "5.3.2" }, "dependencies": { - "qrcode-generator": "^1.4.4" + "qrcode": "^1.5.3" } -} +} \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ef7f0e369d..4286ec07c1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -1233,9 +1233,9 @@ importers: packages/forge/blocks/qrcode: dependencies: - qrcode-generator: - specifier: ^1.4.4 - version: 1.4.4 + qrcode: + specifier: ^1.5.3 + version: 1.5.3 devDependencies: '@typebot.io/forge': specifier: workspace:* @@ -1246,6 +1246,9 @@ importers: '@typebot.io/tsconfig': specifier: workspace:* version: link:../../../tsconfig + '@types/qrcode': + specifier: ^1.5.3 + version: 1.5.3 '@types/react': specifier: 18.2.15 version: 18.2.15 @@ -7925,6 +7928,12 @@ packages: /@types/prop-types@15.7.8: resolution: {integrity: sha512-kMpQpfZKSCBqltAJwskgePRaYRFukDkm1oItcAbC3gNELR20XIBcN9VRgg4+m8DKsTfkWeA4m4Imp4DDuWy7FQ==} + /@types/qrcode@1.5.3: + resolution: {integrity: sha512-TgVHRrlG9b3CHrVCS7slp57H+KhazcDFJbxz2Q5FXYd7RmA4OVdPKrzXcVnW6B19ywrp3YPmqYcfohGfc9te9g==} + dependencies: + '@types/node': 20.10.1 + dev: true + /@types/qs@6.9.7: resolution: {integrity: sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==} dev: true @@ -10601,7 +10610,6 @@ packages: /camelcase@5.3.1: resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} engines: {node: '>=6'} - dev: true /camelcase@6.3.0: resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} @@ -10825,6 +10833,14 @@ packages: /client-only@0.0.1: resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + /cliui@6.0.0: + resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} + dependencies: + string-width: 4.2.3 + strip-ansi: 6.0.1 + wrap-ansi: 6.2.0 + dev: false + /cliui@7.0.4: resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} dependencies: @@ -11446,6 +11462,11 @@ packages: dependencies: ms: 2.1.2 + /decamelize@1.2.0: + resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} + engines: {node: '>=0.10.0'} + dev: false + /decimal.js@10.4.3: resolution: {integrity: sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==} dev: true @@ -11652,6 +11673,10 @@ packages: md5: 2.3.0 dev: false + /dijkstrajs@1.0.3: + resolution: {integrity: sha512-qiSlmBq9+BCdCA/L46dw8Uy93mloxsPSbwnm5yrKn2vMPiy8KyAskTF6zuV/j5BMsmOGZDPs7KjU+mjb670kfA==} + dev: false + /dir-glob@3.0.1: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} @@ -11831,6 +11856,10 @@ packages: create-emotion: 10.0.27 dev: false + /encode-utf8@1.0.3: + resolution: {integrity: sha512-ucAnuBEhUK4boH2HjVYG5Q2mQyPorvv0u/ocS+zhdw0S8AlHYY+GOFhP1Gio5z4icpP2ivFSvhtFjQi8+T9ppw==} + dev: false + /encodeurl@1.0.2: resolution: {integrity: sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==} engines: {node: '>= 0.8'} @@ -13013,7 +13042,6 @@ packages: dependencies: locate-path: 5.0.0 path-exists: 4.0.0 - dev: true /find-up@5.0.0: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} @@ -15205,7 +15233,6 @@ packages: engines: {node: '>=8'} dependencies: p-locate: 4.1.0 - dev: true /locate-path@6.0.0: resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} @@ -17155,7 +17182,6 @@ packages: engines: {node: '>=6'} dependencies: p-try: 2.2.0 - dev: true /p-limit@3.1.0: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} @@ -17168,7 +17194,6 @@ packages: engines: {node: '>=8'} dependencies: p-limit: 2.3.0 - dev: true /p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} @@ -17207,7 +17232,6 @@ packages: /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} engines: {node: '>=6'} - dev: true /pad@2.3.0: resolution: {integrity: sha512-lxrgnOG5AXmzMRT1O5urWtYFxHnFSE+QntgTHij1nvS4W+ubhQLmQRHmZXDeEvk9I00itAixLqU9Q6fE0gW3sw==} @@ -17369,6 +17393,11 @@ packages: hasBin: true dev: true + /pngjs@5.0.0: + resolution: {integrity: sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==} + engines: {node: '>=10.13.0'} + dev: false + /portfinder@1.0.32: resolution: {integrity: sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==} engines: {node: '>= 0.12.0'} @@ -18058,8 +18087,15 @@ packages: resolution: {integrity: sha512-LA0Y9kxMYv47GIPJy6MI84fqTd2HmYZI83W/kM/SkKfDlajnZYfmXFTxkbY+xSBPkLJxltMa9hIkmdc29eguMA==} dev: true - /qrcode-generator@1.4.4: - resolution: {integrity: sha512-HM7yY8O2ilqhmULxGMpcHSF1EhJJ9yBj8gvDEuZ6M+KGJ0YY2hKpnXvRD+hZPLrDVck3ExIGhmPtSdcjC+guuw==} + /qrcode@1.5.3: + resolution: {integrity: sha512-puyri6ApkEHYiVl4CFzo1tDkAZ+ATcnbJrJ6RiBM1Fhctdn/ix9MTE3hRph33omisEbC/2fcfemsseiKgBPKZg==} + engines: {node: '>=10.13.0'} + hasBin: true + dependencies: + dijkstrajs: 1.0.3 + encode-utf8: 1.0.3 + pngjs: 5.0.0 + yargs: 15.4.1 dev: false /qs@6.11.0: @@ -18650,6 +18686,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /require-main-filename@2.0.0: + resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} + dev: false + /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} dev: true @@ -18991,6 +19031,10 @@ packages: transitivePeerDependencies: - supports-color + /set-blocking@2.0.0: + resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + dev: false + /set-function-name@2.0.1: resolution: {integrity: sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==} engines: {node: '>= 0.4'} @@ -21052,6 +21096,10 @@ packages: is-string: 1.0.7 is-symbol: 1.0.4 + /which-module@2.0.1: + resolution: {integrity: sha512-iBdZ57RDvnOR9AGBhML2vFZf7h8vmBjhoaZqODJBFWHVtKkDmKuHai3cx5PgVMrX5YDNp27AofYbAwctSS+vhQ==} + dev: false + /which-typed-array@1.1.11: resolution: {integrity: sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==} engines: {node: '>= 0.4'} @@ -21083,6 +21131,15 @@ packages: string-width: 5.1.2 dev: false + /wrap-ansi@6.2.0: + resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + string-width: 4.2.3 + strip-ansi: 6.0.1 + dev: false + /wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -21186,6 +21243,10 @@ packages: engines: {node: '>=0.4'} dev: true + /y18n@4.0.3: + resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} + dev: false + /y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -21208,6 +21269,14 @@ packages: resolution: {integrity: sha512-N/lyzTPaJasoDmfV7YTrYCI0G/3ivm/9wdG0aHuheKowWQwGTsK0Eoiw6utmzAnI6pkJa0DUVygvp3spqqEKXg==} engines: {node: '>= 14'} + /yargs-parser@18.1.3: + resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} + engines: {node: '>=6'} + dependencies: + camelcase: 5.3.1 + decamelize: 1.2.0 + dev: false + /yargs-parser@20.2.9: resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} engines: {node: '>=10'} @@ -21217,6 +21286,23 @@ packages: engines: {node: '>=12'} dev: true + /yargs@15.4.1: + resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} + engines: {node: '>=8'} + dependencies: + cliui: 6.0.0 + decamelize: 1.2.0 + find-up: 4.1.0 + get-caller-file: 2.0.5 + require-directory: 2.1.1 + require-main-filename: 2.0.0 + set-blocking: 2.0.0 + string-width: 4.2.3 + which-module: 2.0.1 + y18n: 4.0.3 + yargs-parser: 18.1.3 + dev: false + /yargs@16.2.0: resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} engines: {node: '>=10'} From 2ef763be7989326a75ed55a8f9b826c34bc6e31b Mon Sep 17 00:00:00 2001 From: Dinesh Kashikar Date: Wed, 10 Jan 2024 15:58:06 +0530 Subject: [PATCH 3/5] Update error messages while logging Made the error messages more user-friendly Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- packages/forge/blocks/qrcode/actions/convertQr.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/forge/blocks/qrcode/actions/convertQr.ts b/packages/forge/blocks/qrcode/actions/convertQr.ts index 49b39d27b8..de3f712406 100644 --- a/packages/forge/blocks/qrcode/actions/convertQr.ts +++ b/packages/forge/blocks/qrcode/actions/convertQr.ts @@ -18,9 +18,9 @@ export const convertQr = createAction({ options.saveQrcodeInVariableId ? [options.saveQrcodeInVariableId] : [], run: { server: async ({ options, variables, logs }) => { - if (!options.qrvalue) return logs.add('Qr code value is empty') + if (!options.qrvalue) return logs.add('QR code value is empty. Please provide the data to be encoded into the QR code.') if (!options.saveQrcodeInVariableId) - return logs.add('Qr Code save variable is empty') + return logs.add('QR Code save variable is not specified. Please select a variable to save the generated QR code.') let qrcode = '' try { From f9d35713ae0333b0a4789cf376b7f25be55b3bff Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Wed, 10 Jan 2024 17:56:50 +0100 Subject: [PATCH 4/5] =?UTF-8?q?:recycle:=20(qrCode)=20Rename=20to=20proper?= =?UTF-8?q?=20camel=20case=20and=20generate=20ima=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../forge/blocks/qrcode/actions/convertQr.ts | 35 ---------------- .../qrcode/actions/generateQrCodeImage.ts | 41 +++++++++++++++++++ packages/forge/blocks/qrcode/index.ts | 16 ++++---- packages/forge/blocks/qrcode/logo.tsx | 35 ++++++++++------ packages/forge/core/index.ts | 5 ++- packages/forge/core/types.ts | 5 ++- packages/forge/repository/index.ts | 2 +- packages/forge/schemas/index.ts | 4 +- 8 files changed, 81 insertions(+), 62 deletions(-) delete mode 100644 packages/forge/blocks/qrcode/actions/convertQr.ts create mode 100644 packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts diff --git a/packages/forge/blocks/qrcode/actions/convertQr.ts b/packages/forge/blocks/qrcode/actions/convertQr.ts deleted file mode 100644 index de3f712406..0000000000 --- a/packages/forge/blocks/qrcode/actions/convertQr.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { createAction, option } from "@typebot.io/forge"; -import QRCode from 'qrcode' - -export const convertQr = createAction({ - name: 'Convert Qr', - options: option.object({ - qrvalue: option.string.layout({ - label: 'Data', - isRequired: true, - helperText: 'Data to convert into QR Code' - }), - saveQrcodeInVariableId: option.string.layout({ - label: 'QR Code', - inputType: 'variableDropdown', - }), - }), - getSetVariableIds: (options) => - options.saveQrcodeInVariableId ? [options.saveQrcodeInVariableId] : [], - run: { - server: async ({ options, variables, logs }) => { - if (!options.qrvalue) return logs.add('QR code value is empty. Please provide the data to be encoded into the QR code.') - if (!options.saveQrcodeInVariableId) - return logs.add('QR Code save variable is not specified. Please select a variable to save the generated QR code.') - - let qrcode = '' - try { - qrcode = await QRCode.toDataURL(options.qrvalue) - } catch (error) { - return logs.add(`${error}`) - } - - variables.set(options.saveQrcodeInVariableId, qrcode) - }, - }, -}) diff --git a/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts b/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts new file mode 100644 index 0000000000..d6627908b4 --- /dev/null +++ b/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts @@ -0,0 +1,41 @@ +import { createAction, option } from '@typebot.io/forge' +import { toBuffer as generateQrCodeBuffer } from 'qrcode' +import { uploadFileToBucket } from '@typebot.io/lib/s3/uploadFileToBucket' +import { createId } from '@typebot.io/lib/createId' + +export const generateQrCode = createAction({ + name: 'Generate a QR Code', + options: option.object({ + data: option.string.layout({ + label: 'Data', + helperText: + 'This can be a URL, or any text data you want to encode into a QR code.', + }), + saveQrcodeInVariableId: option.string.layout({ + label: 'Save QR code image URL', + inputType: 'variableDropdown', + }), + }), + getSetVariableIds: (options) => + options.saveQrcodeInVariableId ? [options.saveQrcodeInVariableId] : [], + run: { + server: async ({ options, variables, logs }) => { + if (!options.data) + return logs.add( + 'QR code value is empty. Please provide the data to be encoded into the QR code.' + ) + if (!options.saveQrcodeInVariableId) + return logs.add( + 'QR Code save variable is not specified. Please select a variable to save the generated QR code.' + ) + + const url = await uploadFileToBucket({ + file: await generateQrCodeBuffer(options.data), + key: `tmp/qrcodes/${createId() + createId()}.png`, + mimeType: 'image/png', + }) + + variables.set(options.saveQrcodeInVariableId, url) + }, + }, +}) diff --git a/packages/forge/blocks/qrcode/index.ts b/packages/forge/blocks/qrcode/index.ts index 98d0df8f09..99687d8e0b 100644 --- a/packages/forge/blocks/qrcode/index.ts +++ b/packages/forge/blocks/qrcode/index.ts @@ -1,11 +1,11 @@ import { createBlock } from '@typebot.io/forge' -import { QrcodeLogo } from './logo' -import { convertQr } from './actions/convertQr' +import { QrCodeLogo } from './logo' +import { generateQrCode } from './actions/generateQrCodeImage' -export const qrcode = createBlock({ - id: 'qrcode', - name: 'QRcode', - tags: ['QR Code'], - LightLogo: QrcodeLogo, - actions: [convertQr] +export const qrCode = createBlock({ + id: 'qr-code', + name: 'QR code', + tags: [], + LightLogo: QrCodeLogo, + actions: [generateQrCode], }) diff --git a/packages/forge/blocks/qrcode/logo.tsx b/packages/forge/blocks/qrcode/logo.tsx index 1b78e03062..15563c0553 100644 --- a/packages/forge/blocks/qrcode/logo.tsx +++ b/packages/forge/blocks/qrcode/logo.tsx @@ -1,16 +1,27 @@ import React from 'react' -export const QrcodeLogo = (props: React.SVGProps) => ( - - - +export const QrCodeLogo = (props: React.SVGProps) => ( + + + + + + + + + + + + + ) diff --git a/packages/forge/core/index.ts b/packages/forge/core/index.ts index 5756ca70c7..8ace97a62f 100644 --- a/packages/forge/core/index.ts +++ b/packages/forge/core/index.ts @@ -1,3 +1,4 @@ +import { ZodRawShape } from 'zod' import { AuthDefinition, BlockDefinition, ActionDefinition } from './types' import { z } from './zod' @@ -18,8 +19,8 @@ export const createBlock = < export const createAction = < A extends AuthDefinition, - BaseOptions extends z.ZodObject, - O extends z.ZodObject + BaseOptions extends z.ZodObject = z.ZodObject<{}>, + O extends z.ZodObject = z.ZodObject<{}> >( actionDefinition: { auth?: A diff --git a/packages/forge/core/types.ts b/packages/forge/core/types.ts index 64f6b9247b..8e1b98b824 100644 --- a/packages/forge/core/types.ts +++ b/packages/forge/core/types.ts @@ -1,5 +1,6 @@ import { SVGProps } from 'react' import { z } from './zod' +import { ZodRawShape } from 'zod' export type VariableStore = { get: (variableId: string) => string | (string | null)[] | null | undefined @@ -28,8 +29,8 @@ export type ReadOnlyVariableStore = Omit export type ActionDefinition< A extends AuthDefinition, - BaseOptions extends z.ZodObject, - Options extends z.ZodObject = z.ZodObject<{}> + BaseOptions extends z.ZodObject = z.ZodObject<{}>, + Options extends z.ZodObject = z.ZodObject<{}> > = { name: string fetchers?: FetcherDefinition & z.infer>[] diff --git a/packages/forge/repository/index.ts b/packages/forge/repository/index.ts index afa12b3f06..5c60ee65a5 100644 --- a/packages/forge/repository/index.ts +++ b/packages/forge/repository/index.ts @@ -4,5 +4,5 @@ export const enabledBlocks = [ 'zemantic-ai', 'cal-com', 'chat-node', - 'qrcode', + 'qr-code', ] as const diff --git a/packages/forge/schemas/index.ts b/packages/forge/schemas/index.ts index ac4b5d5f2f..5c3e922fe0 100644 --- a/packages/forge/schemas/index.ts +++ b/packages/forge/schemas/index.ts @@ -1,5 +1,5 @@ // Do not edit this file manually -import { qrcode } from '@typebot.io/qrcode-block' +import { qrCode } from '@typebot.io/qrcode-block' import { chatNode } from '@typebot.io/chat-node-block' import { calCom } from '@typebot.io/cal-com-block' import { zemanticAi } from '@typebot.io/zemantic-ai-block' @@ -17,7 +17,7 @@ export const forgedBlocks = [ zemanticAi, calCom, chatNode, - qrcode, + qrCode, ] as BlockDefinition<(typeof enabledBlocks)[number], any, any>[] export type ForgedBlockDefinition = (typeof forgedBlocks)[number] From f3f71e35af326fe88ff66ca0ea40c8027176778c Mon Sep 17 00:00:00 2001 From: Baptiste Arnaud Date: Thu, 11 Jan 2024 08:07:41 +0100 Subject: [PATCH 5/5] :recycle: Refacto some more non camel case attributes --- .../blocks/qrcode/actions/generateQrCodeImage.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts b/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts index d6627908b4..f1506fb922 100644 --- a/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts +++ b/packages/forge/blocks/qrcode/actions/generateQrCodeImage.ts @@ -11,22 +11,22 @@ export const generateQrCode = createAction({ helperText: 'This can be a URL, or any text data you want to encode into a QR code.', }), - saveQrcodeInVariableId: option.string.layout({ + saveUrlInVariableId: option.string.layout({ label: 'Save QR code image URL', inputType: 'variableDropdown', }), }), getSetVariableIds: (options) => - options.saveQrcodeInVariableId ? [options.saveQrcodeInVariableId] : [], + options.saveUrlInVariableId ? [options.saveUrlInVariableId] : [], run: { server: async ({ options, variables, logs }) => { if (!options.data) return logs.add( - 'QR code value is empty. Please provide the data to be encoded into the QR code.' + 'QR code data is empty. Please provide the data to be encoded into the QR code.' ) - if (!options.saveQrcodeInVariableId) + if (!options.saveUrlInVariableId) return logs.add( - 'QR Code save variable is not specified. Please select a variable to save the generated QR code.' + 'QR code image URL is not specified. Please select a variable to save the generated QR code image.' ) const url = await uploadFileToBucket({ @@ -35,7 +35,7 @@ export const generateQrCode = createAction({ mimeType: 'image/png', }) - variables.set(options.saveQrcodeInVariableId, url) + variables.set(options.saveUrlInVariableId, url) }, }, })