diff --git a/.changeset/hot-crabs-clean.md b/.changeset/hot-crabs-clean.md new file mode 100644 index 00000000..923c5f87 --- /dev/null +++ b/.changeset/hot-crabs-clean.md @@ -0,0 +1,7 @@ +--- +'@flatfile/embedded-utils': patch +'@flatfile/react': patch +'@flatfile/vue': patch +--- + +Centralize and reuse utils from embedded-utils package diff --git a/package-lock.json b/package-lock.json index fcb17611..f1bc91af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,5 +1,5 @@ { - "name": "platform-sdk-mono", + "name": "flatfile-core-libraries", "lockfileVersion": 3, "requires": true, "packages": { @@ -58,33 +58,6 @@ "@types/node": "^18.16.0" } }, - "apps/getting-started/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "apps/getting-started/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "apps/getting-started/node_modules/axios": { "version": "0.27.2", "license": "MIT", @@ -261,33 +234,6 @@ "tslint-config-prettier": "^1.18.0" } }, - "apps/sandbox/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "apps/sandbox/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "apps/sandbox/node_modules/@types/node": { "version": "14.18.63", "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.63.tgz", @@ -368,31 +314,19 @@ "parcel": "^2.3.1" } }, - "apps/vanilla/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "apps/vanilla/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", + "apps/vanilla/node_modules/@flatfile/listener": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@flatfile/listener/-/listener-0.4.2.tgz", + "integrity": "sha512-2p0vlAlQ+FnMo5uC1oHdNwJWSlmNKmo/2HVA3Ued3h1nzmu5Zaag/kb+9rerRbxS1sSnyl/Kht6Mr/HWGXKJtA==", "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" + "ansi-colors": "^4.1.3", + "cross-fetch": "^4.0.0", + "flat": "^5.0.2", + "pako": "^2.1.0", + "wildcard-match": "^5.1.2" }, - "engines": { - "node": ">= 16" + "peerDependencies": { + "@flatfile/api": "^1.5.10" } }, "apps/vue": { @@ -3797,6 +3731,33 @@ "resolved": "packages/orm", "link": true }, + "node_modules/@flatfile/plugin-record-hook": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", + "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", + "dependencies": { + "@flatfile/api": "^1.6.3", + "@flatfile/hooks": "^1.3.1", + "@flatfile/listener": "^1.0.0", + "@flatfile/util-common": "^0.4.1", + "rollup-plugin-peer-deps-external": "^2.2.4" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@flatfile/plugin-record-hook/node_modules/@flatfile/util-common": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", + "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", + "dependencies": { + "@flatfile/api": "^1.6.3", + "@flatfile/listener": "^1.0.0" + }, + "engines": { + "node": ">= 16" + } + }, "node_modules/@flatfile/plugin-xlsx-extractor": { "version": "1.11.0", "resolved": "https://registry.npmjs.org/@flatfile/plugin-xlsx-extractor/-/plugin-xlsx-extractor-1.11.0.tgz", @@ -29601,33 +29562,6 @@ "node": ">=12" } }, - "packages/angular/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/angular/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "packages/angular/node_modules/@schematics/angular": { "version": "16.2.10", "dev": true, @@ -30124,7 +30058,7 @@ }, "packages/cli": { "name": "flatfile", - "version": "3.5.14", + "version": "3.6.0", "dependencies": { "@flatfile/cross-env-config": "^0.0.5", "@flatfile/listener": "^1.0.0", @@ -31189,6 +31123,7 @@ "dependencies": { "@flatfile/api": "^1.6.7", "@flatfile/listener": "^1.0.0", + "@flatfile/plugin-record-hook": "^1.3.0", "@flatfile/util-common": "^0.2.4", "pubnub": "^7.2.2" }, @@ -31715,33 +31650,6 @@ "node": ">=12" } }, - "packages/javascript/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/javascript/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "packages/javascript/node_modules/@jest/console": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", @@ -34846,33 +34754,6 @@ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0" } }, - "packages/react/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/react/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "packages/react/node_modules/@rollup/plugin-commonjs": { "version": "25.0.7", "resolved": "https://registry.npmjs.org/@rollup/plugin-commonjs/-/plugin-commonjs-25.0.7.tgz", @@ -35896,33 +35777,6 @@ "typescript": "^5.0.4" } }, - "packages/v2-shims/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/v2-shims/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "packages/v2-shims/node_modules/@jest/console": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", @@ -36943,33 +36797,6 @@ "vue-tsc": "^1.8.5" } }, - "packages/vue/node_modules/@flatfile/plugin-record-hook": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/plugin-record-hook/-/plugin-record-hook-1.4.1.tgz", - "integrity": "sha512-ME6vot5fuaIYYLLOjBGYRMoq/RiKUwfNXVlLycM2AnsUrRnhgrlwJQ8RizbNx5MkNp6SYOCXAcbFFdUqBXeC2w==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/hooks": "^1.3.1", - "@flatfile/listener": "^1.0.0", - "@flatfile/util-common": "^0.4.1", - "rollup-plugin-peer-deps-external": "^2.2.4" - }, - "engines": { - "node": ">= 12" - } - }, - "packages/vue/node_modules/@flatfile/util-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/@flatfile/util-common/-/util-common-0.4.1.tgz", - "integrity": "sha512-sf45sjL7+gcdB290a75U3hbT3KMY5oMHRcAExansGf64W1Ek7T+rFERclDcNtAJkJttj4wscpDgo4iL29DEWAg==", - "dependencies": { - "@flatfile/api": "^1.6.3", - "@flatfile/listener": "^1.0.0" - }, - "engines": { - "node": ">= 16" - } - }, "packages/vue/node_modules/@rollup/plugin-commonjs": { "version": "25.0.7", "dev": true, diff --git a/packages/embedded-utils/package.json b/packages/embedded-utils/package.json index 42e8aa26..383c575e 100644 --- a/packages/embedded-utils/package.json +++ b/packages/embedded-utils/package.json @@ -19,6 +19,7 @@ }, "dependencies": { "@flatfile/api": "^1.6.7", + "@flatfile/plugin-record-hook": "^1.3.0", "@flatfile/listener": "^1.0.0", "@flatfile/util-common": "^0.2.4", "pubnub": "^7.2.2" diff --git a/packages/react/src/utils/_tests_/addSpaceInfo.spec.ts b/packages/embedded-utils/src/_tests_/addSpaceInfo.spec.ts similarity index 93% rename from packages/react/src/utils/_tests_/addSpaceInfo.spec.ts rename to packages/embedded-utils/src/_tests_/addSpaceInfo.spec.ts index 8098d6bd..c37f9956 100644 --- a/packages/react/src/utils/_tests_/addSpaceInfo.spec.ts +++ b/packages/embedded-utils/src/_tests_/addSpaceInfo.spec.ts @@ -1,8 +1,8 @@ import { FlatfileClient } from '@flatfile/api' import { CreateWorkbookConfig, Workbook } from '@flatfile/api/api' import { Space } from '@flatfile/api/api/resources/spaces' -import { mockDocument, mockWorkbook } from '../../test/mocks' -import { addSpaceInfo } from '../addSpaceInfo' +import { mockDocument, mockWorkbook } from './mocks' +import { addSpaceInfo } from '../utils/addSpaceInfo' describe('addSpaceInfo', () => { beforeEach(() => { @@ -67,8 +67,11 @@ describe('addSpaceInfo', () => { await addSpaceInfo(mockSpaceProps, mockSpaceId, mockApi) expect(mockApi.workbooks.create).toHaveBeenCalledWith({ - ...mockWorkbook, - spaceId: mockSpaceId, + "actions": [], + "environmentId": "test-environment-id", + "name": "Test Workbook", + "sheets": [], + "spaceId": mockSpaceId, }) expect(mockApi.spaces.update).toHaveBeenCalledWith(mockSpaceId, { diff --git a/packages/react/src/utils/_tests_/authenticate.spec.ts b/packages/embedded-utils/src/_tests_/authenticate.spec.ts similarity index 93% rename from packages/react/src/utils/_tests_/authenticate.spec.ts rename to packages/embedded-utils/src/_tests_/authenticate.spec.ts index ffd8f778..93e273e4 100644 --- a/packages/react/src/utils/_tests_/authenticate.spec.ts +++ b/packages/embedded-utils/src/_tests_/authenticate.spec.ts @@ -1,5 +1,5 @@ import { FlatfileClient } from '@flatfile/api' -import { authenticate } from '../authenticate' +import { authenticate } from '../utils/authenticate' describe('authenticate', () => { beforeEach(() => { diff --git a/packages/react/src/utils/_tests_/initializeSpace.spec.ts b/packages/embedded-utils/src/_tests_/initializeSpace.spec.ts similarity index 91% rename from packages/react/src/utils/_tests_/initializeSpace.spec.ts rename to packages/embedded-utils/src/_tests_/initializeSpace.spec.ts index cf1e3eae..d5fd77d6 100644 --- a/packages/react/src/utils/_tests_/initializeSpace.spec.ts +++ b/packages/embedded-utils/src/_tests_/initializeSpace.spec.ts @@ -1,8 +1,7 @@ import { FlatfileClient } from '@flatfile/api' -import { Space } from '@flatfile/api/api/resources/spaces' import { ISpace } from '@flatfile/embedded-utils' -import { initializeSpace } from '../initializeSpace' -import { mockDocument, mockSpace } from '../../test/mocks' +import { initializeSpace } from '../utils/initializeSpace' +import { mockDocument, mockSpace } from './mocks' var authenticateMock: jest.Mock = jest.fn() var addSpaceInfoMock: jest.Mock = jest.fn() @@ -92,6 +91,6 @@ describe('initializeSpace', () => { const result = await initializeSpace(mockSpaceProps) - expect(result).toStrictEqual({ data: mockSpace }) + expect(result).toStrictEqual({ space: { data: mockSpace }, workbook: mockWorkbook }) }) }) diff --git a/packages/embedded-utils/src/_tests_/mocks.ts b/packages/embedded-utils/src/_tests_/mocks.ts new file mode 100644 index 00000000..979831a1 --- /dev/null +++ b/packages/embedded-utils/src/_tests_/mocks.ts @@ -0,0 +1,33 @@ +import { Workbook } from '@flatfile/api/api' +import { Space } from '@flatfile/api/api/resources/spaces/types' + +export const mockWorkbook: Workbook = { + id: 'wb-id', + environmentId: 'your-environment-id', + sheets: [], + name: 'Test Workbook', + actions: [], + spaceId: 'test-space-id', + createdAt: new Date('01/01/2000'), + updatedAt: new Date('01/01/2001'), +} + +export const mockDocument = { + id: 'doc-id', + title: 'Example-title', + body: 'Example-body', + createdAt: new Date('01/01/2000'), + updatedAt: new Date('01/01/2001'), +} + +export const mockSpace: Space = { + name: 'Test Space', + guestAuthentication: ['shared_link', 'magic_link'], + id: 'space-id', + environmentId: 'your-environment-id', + accessToken: 'access-token', + createdAt: new Date('01/01/2000'), + updatedAt: new Date('01/01/2001'), + isCollaborative: true, + guestLink: 'fake-url', +} \ No newline at end of file diff --git a/packages/embedded-utils/src/types/IReactSpaceProps.ts b/packages/embedded-utils/src/types/IReactSpaceProps.ts new file mode 100644 index 00000000..ab7c9477 --- /dev/null +++ b/packages/embedded-utils/src/types/IReactSpaceProps.ts @@ -0,0 +1,7 @@ +import React from 'react' +import { ISpace } from './Space' + +export type IReactSpaceProps = ISpace & { + error?: (error: Error | string) => React.ReactElement + loading?: React.ReactElement +} \ No newline at end of file diff --git a/packages/embedded-utils/src/types/index.ts b/packages/embedded-utils/src/types/index.ts index 8d05f056..128e0508 100644 --- a/packages/embedded-utils/src/types/index.ts +++ b/packages/embedded-utils/src/types/index.ts @@ -14,6 +14,7 @@ import { IThemeConfig } from './IThemeConfig' import { InitializePubnub } from './InitializePubnub' import { SpaceComponent } from './SpaceComponent' import { IThemeGenerator } from './ThemeGenerator' +import { IReactSpaceProps } from './IReactSpaceProps' export type { ISidebarConfig, @@ -29,6 +30,7 @@ export type { SimpleOnboarding, SpaceComponent, State, + IReactSpaceProps } export { DefaultSubmitSettings } diff --git a/packages/vue/src/utils/addSpaceInfo.ts b/packages/embedded-utils/src/utils/addSpaceInfo.ts similarity index 90% rename from packages/vue/src/utils/addSpaceInfo.ts rename to packages/embedded-utils/src/utils/addSpaceInfo.ts index e4025317..abcecca6 100644 --- a/packages/vue/src/utils/addSpaceInfo.ts +++ b/packages/embedded-utils/src/utils/addSpaceInfo.ts @@ -1,14 +1,12 @@ +import { NewSpaceFromPublishableKey } from '../types' import { FlatfileClient } from '@flatfile/api' -import { - NewSpaceFromPublishableKey, - getErrorMessage, -} from '@flatfile/embedded-utils' +import { getErrorMessage } from './getErrorMessage' -const addSpaceInfo = async ( +export const addSpaceInfo = async ( spaceProps: NewSpaceFromPublishableKey, spaceId: string, api: FlatfileClient -) => { +): Promise => { const { workbook, environmentId, diff --git a/packages/vue/src/utils/authenticate.ts b/packages/embedded-utils/src/utils/authenticate.ts similarity index 78% rename from packages/vue/src/utils/authenticate.ts rename to packages/embedded-utils/src/utils/authenticate.ts index d105c707..931a8f53 100644 --- a/packages/vue/src/utils/authenticate.ts +++ b/packages/embedded-utils/src/utils/authenticate.ts @@ -1,6 +1,6 @@ import { FlatfileClient } from '@flatfile/api' -const authenticate = ( +export const authenticate = ( key: string, apiUrl = 'https://platform.flatfile.com/api' ) => @@ -8,5 +8,3 @@ const authenticate = ( token: key, environment: `${apiUrl}/v1`, }) - -export default authenticate diff --git a/packages/embedded-utils/src/utils/createSimpleListener.ts b/packages/embedded-utils/src/utils/createSimpleListener.ts new file mode 100644 index 00000000..36671bda --- /dev/null +++ b/packages/embedded-utils/src/utils/createSimpleListener.ts @@ -0,0 +1,64 @@ +import api from '@flatfile/api' +import { FlatfileRecord } from '@flatfile/hooks' +import { recordHook } from '@flatfile/plugin-record-hook' +import { FlatfileEvent, FlatfileListener } from '@flatfile/listener' +import { SimpleOnboarding } from '../types' +import { JobHandler, SheetHandler } from './SubmitUtil' + +interface SimpleListenerType + extends Pick { + slug: string +} + +export const createSimpleListener = ({ + onRecordHook, + onSubmit, + slug, +}: SimpleListenerType) => + FlatfileListener.create((client: FlatfileListener) => { + if (onRecordHook) { + client.use( + recordHook( + slug, + async (record: FlatfileRecord, event?: FlatfileEvent) => + // @ts-ignore - something weird with the `data` prop and the types upstream in the packages being declared in different places, but overall this is fine + onRecordHook(record, event) + ) + ) + } + if (onSubmit) { + client.filter({ job: 'workbook:simpleSubmitAction' }, (configure: FlatfileListener) => { + configure.on('job:ready', async (event: FlatfileEvent) => { + const { jobId, spaceId, workbookId } = event.context + try { + await api.jobs.ack(jobId, { info: 'Starting job', progress: 10 }) + + const job = new JobHandler(jobId) + const { data: workbookSheets } = await api.sheets.list({ + workbookId, + }) + + // this assumes we are only allowing 1 sheet here (which we've talked about doing initially) + const sheet = new SheetHandler(workbookSheets[0].id) + + await onSubmit({ job, sheet }) + + await api.jobs.complete(jobId, { + outcome: { + message: 'complete', + }, + }) + await api.spaces.delete(spaceId) + } catch (error: any) { + if (jobId) { + await api.jobs.cancel(jobId) + } + if (spaceId) { + await api.spaces.delete(spaceId) + } + console.error('Error:', error.stack) + } + }) + }) + } + }) \ No newline at end of file diff --git a/packages/vue/src/utils/getSpace.ts b/packages/embedded-utils/src/utils/getSpace.ts similarity index 89% rename from packages/vue/src/utils/getSpace.ts rename to packages/embedded-utils/src/utils/getSpace.ts index 5bc847c3..0399ba56 100644 --- a/packages/vue/src/utils/getSpace.ts +++ b/packages/embedded-utils/src/utils/getSpace.ts @@ -1,18 +1,16 @@ -import { - ReusedSpaceWithAccessToken, - getErrorMessage, -} from '@flatfile/embedded-utils' -import authenticate from './authenticate' import { Flatfile } from '@flatfile/api' +import { ReusedSpaceWithAccessToken } from '../types' +import { authenticate } from './authenticate' +import { getErrorMessage } from './getErrorMessage' type IWorkbook = Pick< Flatfile.CreateWorkbookConfig, 'name' | 'sheets' | 'actions' > -const getSpace = async ( +export const getSpace = async ( spaceProps: ReusedSpaceWithAccessToken ): Promise<{ - space: any + space: Flatfile.SpaceResponse workbook?: IWorkbook }> => { const { diff --git a/packages/embedded-utils/src/utils/index.ts b/packages/embedded-utils/src/utils/index.ts index e6d1aa8c..607f1f1c 100644 --- a/packages/embedded-utils/src/utils/index.ts +++ b/packages/embedded-utils/src/utils/index.ts @@ -3,3 +3,8 @@ export { fetchEventToken, EventSubscriber } from './EventSubscriber' export { getErrorMessage } from './getErrorMessage' export { JobHandler, SheetHandler } from './SubmitUtil' export { createWorkbookFromSheet } from './createWorkbookFromSheet' +export { getSpace } from './getSpace' +export { createSimpleListener } from './createSimpleListener' +export { addSpaceInfo } from './addSpaceInfo' +export { initializeSpace } from './initializeSpace' +export { authenticate } from './authenticate' \ No newline at end of file diff --git a/packages/vue/src/utils/initializeSpace.ts b/packages/embedded-utils/src/utils/initializeSpace.ts similarity index 88% rename from packages/vue/src/utils/initializeSpace.ts rename to packages/embedded-utils/src/utils/initializeSpace.ts index 7e169ccf..ecd286ff 100644 --- a/packages/vue/src/utils/initializeSpace.ts +++ b/packages/embedded-utils/src/utils/initializeSpace.ts @@ -1,15 +1,13 @@ -import authenticate from './authenticate' -import { - getErrorMessage, - SimpleOnboarding, - createWorkbookFromSheet, -} from '@flatfile/embedded-utils' +import { SimpleOnboarding } from '../types' import { Flatfile } from '@flatfile/api' +import { authenticate } from './authenticate' +import { createWorkbookFromSheet } from './createWorkbookFromSheet' +import { getErrorMessage } from './getErrorMessage' export const initializeSpace = async ( flatfileOptions: SimpleOnboarding ): Promise<{ - space: any + space: Flatfile.SpaceResponse workbook?: Pick }> => { let space diff --git a/packages/react/src/components/InitSpace.tsx b/packages/react/src/components/InitSpace.tsx index 17b9b87f..21a440e6 100644 --- a/packages/react/src/components/InitSpace.tsx +++ b/packages/react/src/components/InitSpace.tsx @@ -1,16 +1,15 @@ import { - ISpace, InitState, - SpaceComponent, - State, + ReusedSpaceWithAccessToken, + SimpleOnboarding, + getSpace, + initializeSpace, + addSpaceInfo, + authenticate } from '@flatfile/embedded-utils' -import React, { JSX, useEffect, useRef, useState } from 'react' +import React, { JSX, useEffect, useState } from 'react' import { useCreateListener } from '../hooks/useCreateListener' import { IReactInitSpaceProps } from '../types' -import { addSpaceInfo } from '../utils/addSpaceInfo' -import { authenticate } from '../utils/authenticate' -import { getSpace } from '../utils/getSpace' -import { initializeSpace } from '../utils/initializeSpace' import ConfirmModal from './ConfirmCloseModal' import DefaultError from './Error' import { getContainerStyles, getIframeStyles } from './embeddedStyles' @@ -72,9 +71,12 @@ export const InitSpace = (props: IReactInitSpaceProps): JSX.Element => { const existingSpace = props.space && props.space.id - const { data } = existingSpace - ? await getSpace(props) - : await initializeSpace(props) + const result = + props.publishableKey && !existingSpace + ? await initializeSpace(props as SimpleOnboarding) + : await getSpace(props as ReusedSpaceWithAccessToken) + + const data = result?.space?.data if (!data) { throw new Error('Failed to initialize space') @@ -94,7 +96,7 @@ export const InitSpace = (props: IReactInitSpaceProps): JSX.Element => { throw new Error('Missing access token from space response') } - if (!existingSpace) { + if (props.publishableKey && !existingSpace) { const fullAccessApi = authenticate(accessToken, apiUrl) await addSpaceInfo(props, data.id, fullAccessApi) } diff --git a/packages/react/src/components/Space.tsx b/packages/react/src/components/Space.tsx index 24a80db5..db0731c0 100644 --- a/packages/react/src/components/Space.tsx +++ b/packages/react/src/components/Space.tsx @@ -1,9 +1,6 @@ -import { Flatfile } from '@flatfile/api' -import { ISpace, SpaceComponent } from '@flatfile/embedded-utils' +import { ISpace, SpaceComponent, authenticate, addSpaceInfo } from '@flatfile/embedded-utils' import React, { JSX, useEffect, useState } from 'react' import { useCreateListener } from '../hooks/useCreateListener' -import { addSpaceInfo } from '../utils/addSpaceInfo' -import { authenticate } from '../utils/authenticate' import ConfirmModal from './ConfirmCloseModal' import { getContainerStyles, diff --git a/packages/react/src/hooks/usePortal.tsx b/packages/react/src/hooks/usePortal.tsx index 16681c02..51538070 100644 --- a/packages/react/src/hooks/usePortal.tsx +++ b/packages/react/src/hooks/usePortal.tsx @@ -8,9 +8,8 @@ import { SheetHandler, createWorkbookFromSheet, DefaultSubmitSettings, + initializeSpace } from '@flatfile/embedded-utils' -import { initializeSpace } from '../utils/initializeSpace' -import { getSpace } from '../utils/getSpace' import { FlatfileRecord } from '@flatfile/hooks' import { FlatfileEvent, FlatfileListener } from '@flatfile/listener' import { recordHook } from '@flatfile/plugin-record-hook' @@ -106,9 +105,10 @@ export const usePortal = ( ) } } - const { data } = props.publishableKey - ? await initializeSpace(config) - : await getSpace(config) + + const result = props.publishableKey && await initializeSpace(props) + + const data = result && result?.space?.data if (!data) { throw new Error('Failed to initialize space') diff --git a/packages/react/src/hooks/useSpace.tsx b/packages/react/src/hooks/useSpace.tsx index 4610f852..6e1f0914 100644 --- a/packages/react/src/hooks/useSpace.tsx +++ b/packages/react/src/hooks/useSpace.tsx @@ -2,9 +2,7 @@ import React, { JSX, useEffect, useState } from 'react' import DefaultError from '../components/Error' import Space from '../components/Space' import Spinner from '../components/Spinner' -import { State } from '@flatfile/embedded-utils' -import { initializeSpace } from '../utils/initializeSpace' -import { getSpace } from '../utils/getSpace' +import { ReusedSpaceWithAccessToken, SimpleOnboarding, State, getSpace, initializeSpace } from '@flatfile/embedded-utils' import { IReactSpaceProps } from '../types' export const useSpace = (props: IReactSpaceProps): JSX.Element | null => { @@ -27,9 +25,13 @@ export const useSpace = (props: IReactSpaceProps): JSX.Element | null => { const initSpace = async () => { setCloseInstance(false) try { - const { data } = props.publishableKey - ? await initializeSpace(props) - : await getSpace(props) + const existingSpace = props.space && props.space.id + const result = + props.publishableKey && !existingSpace + ? await initializeSpace(props as SimpleOnboarding) + : await getSpace(props as ReusedSpaceWithAccessToken) + + const data = result?.space?.data if (!data) { throw new Error('Failed to initialize space') diff --git a/packages/react/src/hooks/useSpaceTrigger.tsx b/packages/react/src/hooks/useSpaceTrigger.tsx index 5fa8d2ca..8a285fcb 100644 --- a/packages/react/src/hooks/useSpaceTrigger.tsx +++ b/packages/react/src/hooks/useSpaceTrigger.tsx @@ -1,10 +1,8 @@ -import React, { JSX, useEffect, useState } from 'react' +import React, { JSX, useState } from 'react' import DefaultError from '../components/Error' import Space from '../components/Space' import Spinner from '../components/Spinner' -import { State } from '@flatfile/embedded-utils' -import { initializeSpace } from '../utils/initializeSpace' -import { getSpace } from '../utils/getSpace' +import { ReusedSpaceWithAccessToken, State, getSpace, initializeSpace } from '@flatfile/embedded-utils' import { IReactSpaceProps } from '../types' type IUseSpace = { OpenEmbed: () => Promise; Space: () => JSX.Element } @@ -26,9 +24,11 @@ export const initializeFlatfile = (props: IReactSpaceProps): IUseSpace => { setCloseInstance(false) try { setLoading(true) - const { data } = props.publishableKey + const result = props.publishableKey ? await initializeSpace(props) - : await getSpace(props) + : await getSpace(props as ReusedSpaceWithAccessToken) + + const data = result?.space?.data if (!data) { throw new Error('Failed to initialize space') @@ -44,18 +44,14 @@ export const initializeFlatfile = (props: IReactSpaceProps): IUseSpace => { throw new Error('Missing guest link from space response') } - setState((prevState) => ({ - ...prevState, - localSpaceId: spaceId, - spaceUrl: guestLink, - })) - if (!accessToken) { throw new Error('Missing access token from space response') } setState((prevState) => ({ ...prevState, + localSpaceId: spaceId, + spaceUrl: guestLink, accessTokenLocal: accessToken, })) setLoading(false) diff --git a/packages/react/src/utils/addSpaceInfo.ts b/packages/react/src/utils/addSpaceInfo.ts deleted file mode 100644 index 405eb242..00000000 --- a/packages/react/src/utils/addSpaceInfo.ts +++ /dev/null @@ -1,92 +0,0 @@ -import { Flatfile, FlatfileClient } from '@flatfile/api' -import { - createWorkbookFromSheet, - getErrorMessage, -} from '@flatfile/embedded-utils' -import { IReactSimpleOnboarding } from '../types/IReactSimpleOnboarding' - -// Given the space is created, add workbook, metadata and document to the space -export const addSpaceInfo = async ( - spaceProps: IReactSimpleOnboarding | any, - spaceId: string, - api: FlatfileClient -): Promise<{ - space: Flatfile.SpaceResponse - workbook: Flatfile.WorkbookResponse | undefined -}> => { - const { - workbook, - sheet, - environmentId, - document, - themeConfig, - sidebarConfig, - spaceInfo, - userInfo, - spaceBody, - } = spaceProps - let localWorkbook - - try { - if (!workbook && sheet) { - const createdWorkbook = createWorkbookFromSheet(sheet) - localWorkbook = await api.workbooks.create({ - spaceId, - environmentId, - ...createdWorkbook, - }) - - if (!localWorkbook || !localWorkbook.data || !localWorkbook.data.id) { - throw new Error('Failed to create workbook') - } - } - if (workbook) { - localWorkbook = await api.workbooks.create({ - spaceId, - environmentId, - ...workbook, - }) - - if (!localWorkbook || !localWorkbook.data || !localWorkbook.data.id) { - throw new Error('Failed to create workbook') - } - } - - const updatedSpace = await api.spaces.update(spaceId, { - environmentId, - metadata: { - theme: themeConfig, - sidebarConfig: sidebarConfig ? sidebarConfig : { showSidebar: false }, - userInfo, - spaceInfo, - ...(spaceBody?.metadata || {}), - }, - }) - - if (!updatedSpace) { - throw new Error('Failed to update space') - } - - if (document) { - const createdDocument = await api.documents.create(spaceId, { - title: document.title, - body: document.body, - }) - - if ( - !createdDocument || - !createdDocument.data || - !createdDocument.data.id - ) { - throw new Error('Failed to create document') - } - } - return { - space: updatedSpace, - workbook: localWorkbook, - } - } catch (error) { - const message = getErrorMessage(error) - throw new Error(`Error adding workbook to space: ${message}`) - } -} diff --git a/packages/react/src/utils/authenticate.ts b/packages/react/src/utils/authenticate.ts deleted file mode 100644 index 2c12205a..00000000 --- a/packages/react/src/utils/authenticate.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { FlatfileClient } from '@flatfile/api' - -export const authenticate = ( - key: string, - apiUrl: string = 'https://platform.flatfile.com/api' -) => { - /** - * Instantiating this class with an incorrect key will not throw, - * it will only throw when trying to access internal methods - */ - return new FlatfileClient({ - token: key, - environment: `${apiUrl}/v1`, - }) -} diff --git a/packages/react/src/utils/getSpace.tsx b/packages/react/src/utils/getSpace.tsx deleted file mode 100644 index 7a8acd37..00000000 --- a/packages/react/src/utils/getSpace.tsx +++ /dev/null @@ -1,50 +0,0 @@ -import { Flatfile } from '@flatfile/api' -import { getErrorMessage } from '@flatfile/embedded-utils' -import { authenticate } from './authenticate' -import { IReactSpaceProps } from '../types' - -export const getSpace = async ( - spaceProps: IReactSpaceProps -): Promise => { - const { - space, - apiUrl, - environmentId, - spaceUrl = 'https://spaces.flatfile.com/', - } = spaceProps - let spaceResponse - try { - if (!space?.id) { - throw new Error('Missing required ID for Space') - } - if (!space?.accessToken) { - throw new Error('Missing required accessToken for Space') - } - - if (!environmentId) { - throw new Error('Missing required environment id') - } - - const limitedAccessApi = authenticate(space?.accessToken, apiUrl) - try { - spaceResponse = await limitedAccessApi.spaces.get(space?.id) - } catch (error) { - throw new Error(`Failed to get space: ${getErrorMessage(error)}`) - } - - if (!spaceResponse.data.accessToken) { - throw new Error('Failed to retrieve accessToken') - } - - if (!spaceResponse.data.guestLink) { - const guestLink = `${spaceUrl}space/${space?.id}?token=${spaceResponse.data.accessToken}` - spaceResponse.data.guestLink = guestLink - } - - return spaceResponse - } catch (error) { - const message = getErrorMessage(error) - console.error(`Failed to initialize space: ${message}`) - throw error - } -} diff --git a/packages/react/src/utils/initializeSpace.tsx b/packages/react/src/utils/initializeSpace.tsx deleted file mode 100644 index be770024..00000000 --- a/packages/react/src/utils/initializeSpace.tsx +++ /dev/null @@ -1,69 +0,0 @@ -import { Flatfile } from '@flatfile/api' -import { IReactSpaceProps } from '../types' -import { authenticate } from './authenticate' -import { getErrorMessage } from '@flatfile/embedded-utils' - -export const initializeSpace = async ( - flatfileOptions: IReactSpaceProps -): Promise => { - let space - const { - publishableKey, - environmentId, - name = 'Embedded Space', - spaceBody, - apiUrl, - spaceUrl = 'https://spaces.flatfile.com/', - workbook, - } = flatfileOptions - - try { - if (!publishableKey) { - throw new Error('Missing required publishable key') - } - - if (!environmentId) { - throw new Error('Missing required environment id') - } - - const limitedAccessApi = authenticate(publishableKey, apiUrl) - const spaceRequestBody = { - name, - autoConfigure: false, - labels: ['embedded'], - ...spaceBody, - } - - if (!workbook) { - spaceRequestBody.autoConfigure = true - } - try { - space = await limitedAccessApi.spaces.create({ - environmentId, - ...spaceRequestBody, - }) - } catch (error) { - throw new Error(`Failed to create space: ${getErrorMessage(error)}`) - } - - if (!space) { - throw new Error( - `Failed to create space: Error parsing token: ${publishableKey}` - ) - } - if (!space.data.accessToken) { - throw new Error('Failed to retrieve accessToken') - } - - if (!space.data.guestLink) { - const guestLink = `${spaceUrl}space/${space.data.id}?token=${space.data.accessToken}` - space.data.guestLink = guestLink - } - - return space - } catch (error) { - const message = getErrorMessage(error) - console.error(`Failed to initialize space: ${message}`) - throw error - } -} diff --git a/packages/vue/src/components/SpaceC.vue b/packages/vue/src/components/SpaceC.vue index 42a25c7e..d1fc72fb 100644 --- a/packages/vue/src/components/SpaceC.vue +++ b/packages/vue/src/components/SpaceC.vue @@ -59,11 +59,13 @@ import { ref, watch, onMounted, onUnmounted } from 'vue' import { Flatfile } from '@flatfile/api' import ConfirmModal from './ConfirmCloseModal.vue' -import authenticate from '../utils/authenticate' import { Browser, FlatfileEvent } from '@flatfile/listener' -import addSpaceInfo from '../utils/addSpaceInfo' +import { + addSpaceInfo, + createSimpleListener, + authenticate +} from '@flatfile/embedded-utils' import { getIframeStyles, getContainerStyles } from './embeddedStyles' -import { createSimpleListener } from '../utils/createSimpleListener' export default { props: { diff --git a/packages/vue/src/components/UseSpace.vue b/packages/vue/src/components/UseSpace.vue index 1eeb93df..ea929eac 100644 --- a/packages/vue/src/components/UseSpace.vue +++ b/packages/vue/src/components/UseSpace.vue @@ -32,7 +32,9 @@