From 5cfd2d65553f1f0d9ecd1e478cafc492b7ea11e5 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 23 Aug 2022 14:23:12 +0200 Subject: [PATCH 01/12] http-api package --- packages/http-api/LICENSE | 21 ++++++++++++++++++++ packages/http-api/package.json | 32 ++++++++++++++++++++++++++++++ packages/http-api/src/index.d.ts | 7 +++++++ packages/http-api/src/index.ts | 34 ++++++++++++++++++++++++++++++++ packages/http-api/tsconfig.json | 17 ++++++++++++++++ yarn.lock | 18 +++++++++++++++++ 6 files changed, 129 insertions(+) create mode 100644 packages/http-api/LICENSE create mode 100644 packages/http-api/package.json create mode 100644 packages/http-api/src/index.d.ts create mode 100644 packages/http-api/src/index.ts create mode 100644 packages/http-api/tsconfig.json diff --git a/packages/http-api/LICENSE b/packages/http-api/LICENSE new file mode 100644 index 0000000000..1f6edad9a7 --- /dev/null +++ b/packages/http-api/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Webstudio + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/http-api/package.json b/packages/http-api/package.json new file mode 100644 index 0000000000..2e2fa66088 --- /dev/null +++ b/packages/http-api/package.json @@ -0,0 +1,32 @@ +{ + "name": "@webstudio-is/http-api", + "version": "0.0.1", + "description": "Webstudio HTTP API", + "author": "Webstudio ", + "homepage": "https://webstudio.is", + "scripts": { + "dev": "tsup src/index.ts --format esm,cjs --watch --out-dir=lib", + "build": "rm -fr lib && tsc", + "typecheck": "tsc --noEmit", + "lint": "eslint ./src --ext .ts,.tsx --max-warnings 0", + "checks": "yarn typecheck && yarn lint" + }, + "devDependencies": { + "@types/isomorphic-fetch": "^0.0.36", + "tsup": "^6.1.3", + "typescript": "^4.6.2" + }, + "peerDependencies": {}, + "dependencies": { + "isomorphic-fetch": "^3.0.0" + }, + "main": "lib/index.js", + "types": "lib/index.d.ts", + "files": [ + "lib/*", + "README.md", + "!*.test.*" + ], + "license": "MIT", + "private": false +} diff --git a/packages/http-api/src/index.d.ts b/packages/http-api/src/index.d.ts new file mode 100644 index 0000000000..3185eb209b --- /dev/null +++ b/packages/http-api/src/index.d.ts @@ -0,0 +1,7 @@ +export type IncludeTypes = "tree" | "props" | "breakpoints"; +export type Includes = { [include in IncludeTypes]: T }; +export type Project = { + tree?: string; + props?: string; + breakpoints?: string; +}; diff --git a/packages/http-api/src/index.ts b/packages/http-api/src/index.ts new file mode 100644 index 0000000000..3093ca45ed --- /dev/null +++ b/packages/http-api/src/index.ts @@ -0,0 +1,34 @@ +import isoMorphicFetch from "isomorphic-fetch"; +import type { Includes, Project } from "./index.d"; + +const protocol = process.env.NODE_ENV === "production" ? "https" : "http"; + +const fetch = async (url: string, options?: any) => { + const response = await isoMorphicFetch(url, options); + const contentType = response.headers.get("content-type"); + if (contentType && contentType.indexOf("application/json") !== -1) { + return response.json(); + } else { + return response.text(); + } +}; + +const loadProjectFromRest = async ( + host: string, + projectId: string, + include: Includes = { tree: true, props: true, breakpoints: true } +): Promise => { + const domain = `${protocol}://${host}`; + const [tree, props, breakpoints] = await Promise.all([ + include.tree && fetch(`${domain}/rest/tree/${projectId}`), + include.props && fetch(`${domain}/rest/props/${projectId}`), + include.breakpoints && fetch(`${domain}/rest/breakpoints/${projectId}`), + ]); + return { + tree, + props, + breakpoints, + }; +}; + +export { loadProjectFromRest }; diff --git a/packages/http-api/tsconfig.json b/packages/http-api/tsconfig.json new file mode 100644 index 0000000000..eb77362863 --- /dev/null +++ b/packages/http-api/tsconfig.json @@ -0,0 +1,17 @@ +// Extends can't use node's resolution rn https://github.com/dividab/tsconfig-paths/issues/209#issuecomment-1177261091 +{ + "extends": "../../node_modules/@webstudio-is/tsconfig/base.json", + "include": ["./src/**/*.ts", "./src/**/*.tsx"], + "compilerOptions": { + "lib": ["DOM", "DOM.Iterable", "ES2020"], + "module": "commonjs", + "jsx": "react-jsx", + "target": "ES2020", + "strict": true, + "baseUrl": ".", + "paths": { + "~/*": ["./src/*"] + }, + "outDir": "./lib" + } +} diff --git a/yarn.lock b/yarn.lock index 22cf874352..c9c32a8cf1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5030,6 +5030,11 @@ resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.1.tgz#2d024eace950c836d9e3335a66b97960ae41d022" integrity sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q== +"@types/isomorphic-fetch@^0.0.36": + version "0.0.36" + resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.36.tgz#3a6d8f63974baf26b10fd1314db910633108a769" + integrity sha512-ulw4d+vW1HKn4oErSmNN2HYEcHGq0N1C5exlrMM0CRqX1UUpFhGb5lwiom5j9KN3LBJJDLRmYIZz1ghm7FIzZw== + "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" @@ -11275,6 +11280,14 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== +isomorphic-fetch@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" + integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== + dependencies: + node-fetch "^2.6.1" + whatwg-fetch "^3.4.1" + isomorphic-unfetch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" @@ -17733,6 +17746,11 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" +whatwg-fetch@^3.4.1: + version "3.6.2" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" + integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== + whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" From 342142152b3c0aeaf404babbd17a20c942188a06 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 23 Aug 2022 14:27:13 +0200 Subject: [PATCH 02/12] github action for http-api --- .github/workflows/http-api.yml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 .github/workflows/http-api.yml diff --git a/.github/workflows/http-api.yml b/.github/workflows/http-api.yml new file mode 100644 index 0000000000..74ddb3e1b3 --- /dev/null +++ b/.github/workflows/http-api.yml @@ -0,0 +1,16 @@ +name: Design System Publish +on: + push: + paths: + - "packages/http-api/**/*" + - ".github/workflows/http-api.yml" + - ".github/actions/publish/action.yaml" +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: ./.github/actions/publish + with: + package: "./packages/http-api/package.json" + token: ${{ secrets.NPM_TOKEN }} From 7d86b0fe219b96675632648065768f7bea0b59c2 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 23 Aug 2022 14:50:02 +0200 Subject: [PATCH 03/12] fix: github action for http-api & the api --- .github/workflows/http-api.yml | 2 +- packages/http-api/package.json | 2 +- packages/http-api/src/index.ts | 15 +++++++++------ 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/.github/workflows/http-api.yml b/.github/workflows/http-api.yml index 74ddb3e1b3..5bd515415c 100644 --- a/.github/workflows/http-api.yml +++ b/.github/workflows/http-api.yml @@ -1,4 +1,4 @@ -name: Design System Publish +name: HTTP API Publish on: push: paths: diff --git a/packages/http-api/package.json b/packages/http-api/package.json index 2e2fa66088..23a3f6eeab 100644 --- a/packages/http-api/package.json +++ b/packages/http-api/package.json @@ -1,6 +1,6 @@ { "name": "@webstudio-is/http-api", - "version": "0.0.1", + "version": "0.0.2", "description": "Webstudio HTTP API", "author": "Webstudio ", "homepage": "https://webstudio.is", diff --git a/packages/http-api/src/index.ts b/packages/http-api/src/index.ts index 3093ca45ed..e9e4befb22 100644 --- a/packages/http-api/src/index.ts +++ b/packages/http-api/src/index.ts @@ -2,7 +2,6 @@ import isoMorphicFetch from "isomorphic-fetch"; import type { Includes, Project } from "./index.d"; const protocol = process.env.NODE_ENV === "production" ? "https" : "http"; - const fetch = async (url: string, options?: any) => { const response = await isoMorphicFetch(url, options); const contentType = response.headers.get("content-type"); @@ -13,11 +12,15 @@ const fetch = async (url: string, options?: any) => { } }; -const loadProjectFromRest = async ( - host: string, - projectId: string, - include: Includes = { tree: true, props: true, breakpoints: true } -): Promise => { +const loadProjectFromRest = async ({ + projectId, + host = process.env.DESIGNER_HOST || "localhost:3000", + include = { tree: true, props: true, breakpoints: true }, +}: { + projectId: string; + host?: string; + include?: Includes; +}): Promise => { const domain = `${protocol}://${host}`; const [tree, props, breakpoints] = await Promise.all([ include.tree && fetch(`${domain}/rest/tree/${projectId}`), From 2eb9781776c4b419b1f0df002775290793a5fdd7 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 23 Aug 2022 15:28:06 +0200 Subject: [PATCH 04/12] fix: rename http-api to http-client --- .github/workflows/{http-api.yml => http-client.yml} | 8 ++++---- packages/{http-api => http-client}/LICENSE | 0 packages/http-client/README.md | 1 + packages/{http-api => http-client}/package.json | 8 ++++---- packages/{http-api => http-client}/src/index.d.ts | 0 packages/{http-api => http-client}/src/index.ts | 0 packages/{http-api => http-client}/tsconfig.json | 0 7 files changed, 9 insertions(+), 8 deletions(-) rename .github/workflows/{http-api.yml => http-client.yml} (60%) rename packages/{http-api => http-client}/LICENSE (100%) create mode 100644 packages/http-client/README.md rename packages/{http-api => http-client}/package.json (85%) rename packages/{http-api => http-client}/src/index.d.ts (100%) rename packages/{http-api => http-client}/src/index.ts (100%) rename packages/{http-api => http-client}/tsconfig.json (100%) diff --git a/.github/workflows/http-api.yml b/.github/workflows/http-client.yml similarity index 60% rename from .github/workflows/http-api.yml rename to .github/workflows/http-client.yml index 5bd515415c..f47cb1aedd 100644 --- a/.github/workflows/http-api.yml +++ b/.github/workflows/http-client.yml @@ -1,9 +1,9 @@ -name: HTTP API Publish +name: HTTP Client Publish on: push: paths: - - "packages/http-api/**/*" - - ".github/workflows/http-api.yml" + - "packages/http-client/**/*" + - ".github/workflows/http-client.yml" - ".github/actions/publish/action.yaml" jobs: publish: @@ -12,5 +12,5 @@ jobs: - uses: actions/checkout@v3 - uses: ./.github/actions/publish with: - package: "./packages/http-api/package.json" + package: "./packages/http-client/package.json" token: ${{ secrets.NPM_TOKEN }} diff --git a/packages/http-api/LICENSE b/packages/http-client/LICENSE similarity index 100% rename from packages/http-api/LICENSE rename to packages/http-client/LICENSE diff --git a/packages/http-client/README.md b/packages/http-client/README.md new file mode 100644 index 0000000000..23f15ec25c --- /dev/null +++ b/packages/http-client/README.md @@ -0,0 +1 @@ +# Webstudio HTTP Client diff --git a/packages/http-api/package.json b/packages/http-client/package.json similarity index 85% rename from packages/http-api/package.json rename to packages/http-client/package.json index 23a3f6eeab..f5785a95b6 100644 --- a/packages/http-api/package.json +++ b/packages/http-client/package.json @@ -1,7 +1,7 @@ { - "name": "@webstudio-is/http-api", - "version": "0.0.2", - "description": "Webstudio HTTP API", + "name": "@webstudio-is/http-client", + "version": "0.0.1", + "description": "Webstudio HTTP Client", "author": "Webstudio ", "homepage": "https://webstudio.is", "scripts": { @@ -28,5 +28,5 @@ "!*.test.*" ], "license": "MIT", - "private": false + "private": true } diff --git a/packages/http-api/src/index.d.ts b/packages/http-client/src/index.d.ts similarity index 100% rename from packages/http-api/src/index.d.ts rename to packages/http-client/src/index.d.ts diff --git a/packages/http-api/src/index.ts b/packages/http-client/src/index.ts similarity index 100% rename from packages/http-api/src/index.ts rename to packages/http-client/src/index.ts diff --git a/packages/http-api/tsconfig.json b/packages/http-client/tsconfig.json similarity index 100% rename from packages/http-api/tsconfig.json rename to packages/http-client/tsconfig.json From b554040a94301311741c42b85d40d820ca4a928b Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 23 Aug 2022 15:39:07 +0200 Subject: [PATCH 05/12] test: gh action --- .github/actions/publish/action.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/actions/publish/action.yaml b/.github/actions/publish/action.yaml index 24a129d324..5bea36841d 100644 --- a/.github/actions/publish/action.yaml +++ b/.github/actions/publish/action.yaml @@ -19,6 +19,9 @@ runs: - name: Install Dependencies run: yarn install shell: bash + - name: Build Dependencies + run: yarn build + shell: bash - uses: JS-DevTools/npm-publish@v1 with: token: ${{ inputs.token }} From 963f3ab65049b589b0a8e23cc243672afe2eeccd Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 12 Sep 2022 10:11:19 +0200 Subject: [PATCH 06/12] test: Add tests --- packages/http-client/jest.config.js | 1 + packages/http-client/package.json | 6 ++++-- packages/http-client/src/index.d.ts | 16 +++++++++++++--- packages/http-client/src/index.test.ts | 26 ++++++++++++++++++++++++++ packages/http-client/src/index.ts | 15 ++++++++++----- yarn.lock | 18 ------------------ 6 files changed, 54 insertions(+), 28 deletions(-) create mode 100644 packages/http-client/jest.config.js create mode 100644 packages/http-client/src/index.test.ts diff --git a/packages/http-client/jest.config.js b/packages/http-client/jest.config.js new file mode 100644 index 0000000000..4eeecbaf4e --- /dev/null +++ b/packages/http-client/jest.config.js @@ -0,0 +1 @@ +module.exports = require("@webstudio-is/jest-config"); diff --git a/packages/http-client/package.json b/packages/http-client/package.json index f5785a95b6..154c15b97c 100644 --- a/packages/http-client/package.json +++ b/packages/http-client/package.json @@ -6,19 +6,21 @@ "homepage": "https://webstudio.is", "scripts": { "dev": "tsup src/index.ts --format esm,cjs --watch --out-dir=lib", + "test": "jest", "build": "rm -fr lib && tsc", "typecheck": "tsc --noEmit", "lint": "eslint ./src --ext .ts,.tsx --max-warnings 0", "checks": "yarn typecheck && yarn lint" }, "devDependencies": { - "@types/isomorphic-fetch": "^0.0.36", + "@webstudio-is/jest-config": "*", + "@webstudio-is/prisma-client": "*", "tsup": "^6.1.3", "typescript": "^4.6.2" }, "peerDependencies": {}, "dependencies": { - "isomorphic-fetch": "^3.0.0" + "isomorphic-unfetch": "^3.1.0" }, "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/packages/http-client/src/index.d.ts b/packages/http-client/src/index.d.ts index 3185eb209b..f5d8eb37b7 100644 --- a/packages/http-client/src/index.d.ts +++ b/packages/http-client/src/index.d.ts @@ -1,7 +1,17 @@ export type IncludeTypes = "tree" | "props" | "breakpoints"; export type Includes = { [include in IncludeTypes]: T }; export type Project = { - tree?: string; - props?: string; - breakpoints?: string; + tree: { + id: string; + root: { + comopnent: string; + id: string; + cssRules: Array; + children: Array; + }; + } & { errors: string }; + props: Array & { errors: string }; + breakpoints: Array<{ label: string; minWidtrh: number; id: string }> & { + errors: string; + }; }; diff --git a/packages/http-client/src/index.test.ts b/packages/http-client/src/index.test.ts new file mode 100644 index 0000000000..cdca00f77e --- /dev/null +++ b/packages/http-client/src/index.test.ts @@ -0,0 +1,26 @@ +import { loadProjectFromRest } from "./index"; + +const existingProject = "ab3619d3-831f-46f8-abb6-609558cffd99"; +const notPublishedProject = "7ec397c6-b3d0-4967-9073-9d83623fcf8e"; +const nonExistingProject = "1"; + +describe("getProjectDetails", () => { + test("loads existing project", async () => { + const response = await loadProjectFromRest({ projectId: existingProject }); + expect(response.tree.id).toBeTruthy(); + }); + test("loads non-existing project", async () => { + const response = await loadProjectFromRest({ + projectId: nonExistingProject, + }); + expect(response.tree.errors).toBe("Project required"); + }); + test("loads not published project", async () => { + const response = await loadProjectFromRest({ + projectId: notPublishedProject, + }); + expect(response.tree.errors).toBe( + "Site needs to be published, production tree ID is null." + ); + }); +}); diff --git a/packages/http-client/src/index.ts b/packages/http-client/src/index.ts index e9e4befb22..e4ba6dbda8 100644 --- a/packages/http-client/src/index.ts +++ b/packages/http-client/src/index.ts @@ -1,14 +1,19 @@ -import isoMorphicFetch from "isomorphic-fetch"; +import isoMorphicFetch from "isomorphic-unfetch"; import type { Includes, Project } from "./index.d"; const protocol = process.env.NODE_ENV === "production" ? "https" : "http"; + const fetch = async (url: string, options?: any) => { const response = await isoMorphicFetch(url, options); - const contentType = response.headers.get("content-type"); - if (contentType && contentType.indexOf("application/json") !== -1) { - return response.json(); + if (response.ok) { + const contentType = response.headers.get("content-type"); + if (contentType && contentType.indexOf("application/json") !== -1) { + return response.json(); + } else { + return response.text(); + } } else { - return response.text(); + throw new Error(response.statusText); } }; diff --git a/yarn.lock b/yarn.lock index c9c32a8cf1..22cf874352 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5030,11 +5030,6 @@ resolved "https://registry.yarnpkg.com/@types/is-function/-/is-function-1.0.1.tgz#2d024eace950c836d9e3335a66b97960ae41d022" integrity sha512-A79HEEiwXTFtfY+Bcbo58M2GRYzCr9itHWzbzHVFNEYCcoU/MMGwYYf721gBrnhpj1s6RGVVha/IgNFnR0Iw/Q== -"@types/isomorphic-fetch@^0.0.36": - version "0.0.36" - resolved "https://registry.yarnpkg.com/@types/isomorphic-fetch/-/isomorphic-fetch-0.0.36.tgz#3a6d8f63974baf26b10fd1314db910633108a769" - integrity sha512-ulw4d+vW1HKn4oErSmNN2HYEcHGq0N1C5exlrMM0CRqX1UUpFhGb5lwiom5j9KN3LBJJDLRmYIZz1ghm7FIzZw== - "@types/istanbul-lib-coverage@*", "@types/istanbul-lib-coverage@^2.0.0", "@types/istanbul-lib-coverage@^2.0.1": version "2.0.4" resolved "https://registry.yarnpkg.com/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz#8467d4b3c087805d63580480890791277ce35c44" @@ -11280,14 +11275,6 @@ isobject@^4.0.0: resolved "https://registry.yarnpkg.com/isobject/-/isobject-4.0.0.tgz#3f1c9155e73b192022a80819bacd0343711697b0" integrity sha512-S/2fF5wH8SJA/kmwr6HYhK/RI/OkhD84k8ntalo0iJjZikgq1XFvR5M8NPT1x5F7fBwCG3qHfnzeP/Vh/ZxCUA== -isomorphic-fetch@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-3.0.0.tgz#0267b005049046d2421207215d45d6a262b8b8b4" - integrity sha512-qvUtwJ3j6qwsF3jLxkZ72qCgjMysPzDfeV240JHiGZsANBYd+EEuu35v7dfrJ9Up0Ak07D7GGSkGhCHTqg/5wA== - dependencies: - node-fetch "^2.6.1" - whatwg-fetch "^3.4.1" - isomorphic-unfetch@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/isomorphic-unfetch/-/isomorphic-unfetch-3.1.0.tgz#87341d5f4f7b63843d468438128cb087b7c3e98f" @@ -17746,11 +17733,6 @@ whatwg-encoding@^1.0.5: dependencies: iconv-lite "0.4.24" -whatwg-fetch@^3.4.1: - version "3.6.2" - resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-3.6.2.tgz#dced24f37f2624ed0281725d51d0e2e3fe677f8c" - integrity sha512-bJlen0FcuU/0EMLrdbJ7zOnW6ITZLrZMIarMUVmdKtsGvZna8vxKYaexICWPfZ8qwf9fzNq+UEIZrnSaApt6RA== - whatwg-mimetype@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz#3d4b1e0312d2079879f826aff18dbeeca5960fbf" From d97c7ec91dc2b7f68096c089b5faee02a4b811a3 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 12 Sep 2022 10:15:22 +0200 Subject: [PATCH 07/12] fix: github actions for http-client --- .github/workflows/http-client.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/http-client.yml b/.github/workflows/http-client.yml index f47cb1aedd..30e13efc67 100644 --- a/.github/workflows/http-client.yml +++ b/.github/workflows/http-client.yml @@ -1,10 +1,12 @@ -name: HTTP Client Publish +name: HTTP Client on: push: paths: - "packages/http-client/**/*" - ".github/workflows/http-client.yml" - ".github/actions/publish/action.yaml" + branches: + - main jobs: publish: runs-on: ubuntu-latest @@ -12,5 +14,6 @@ jobs: - uses: actions/checkout@v3 - uses: ./.github/actions/publish with: - package: "./packages/http-client/package.json" + workdir: ./packages/http-client + filter: "@webstudio-is/http-client" token: ${{ secrets.NPM_TOKEN }} From 8264864a031929b07eaa174027d71516ebfdb938 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 12 Sep 2022 10:24:05 +0200 Subject: [PATCH 08/12] fix: no any type --- packages/http-client/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/http-client/src/index.ts b/packages/http-client/src/index.ts index e4ba6dbda8..c01032d33b 100644 --- a/packages/http-client/src/index.ts +++ b/packages/http-client/src/index.ts @@ -3,7 +3,7 @@ import type { Includes, Project } from "./index.d"; const protocol = process.env.NODE_ENV === "production" ? "https" : "http"; -const fetch = async (url: string, options?: any) => { +const fetch = async (url: string, options?: RequestInit) => { const response = await isoMorphicFetch(url, options); if (response.ok) { const contentType = response.headers.get("content-type"); From 7ad79a8bcc639060d632d5c686f2c7b78ffd42fe Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 12 Sep 2022 10:49:24 +0200 Subject: [PATCH 09/12] Update Readme.md --- packages/http-client/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/http-client/README.md b/packages/http-client/README.md index 23f15ec25c..7d9c4877ad 100644 --- a/packages/http-client/README.md +++ b/packages/http-client/README.md @@ -1 +1,3 @@ # Webstudio HTTP Client + +Enables to optimize the http calls to Webstudio API. From 12ae85b5c1c3d51da01f9dabf24550edd5742ef1 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 12 Sep 2022 11:27:28 +0200 Subject: [PATCH 10/12] fix: types & export fn name --- packages/http-client/package.json | 1 + packages/http-client/src/index.d.ts | 21 ++++++++++----------- packages/http-client/src/index.test.ts | 8 ++++---- packages/http-client/src/index.ts | 4 ++-- yarn.lock | 5 +++++ 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/packages/http-client/package.json b/packages/http-client/package.json index 154c15b97c..42d6e31228 100644 --- a/packages/http-client/package.json +++ b/packages/http-client/package.json @@ -14,6 +14,7 @@ }, "devDependencies": { "@webstudio-is/jest-config": "*", + "@webstudio-is/react-sdk": "*", "@webstudio-is/prisma-client": "*", "tsup": "^6.1.3", "typescript": "^4.6.2" diff --git a/packages/http-client/src/index.d.ts b/packages/http-client/src/index.d.ts index f5d8eb37b7..178b0828c3 100644 --- a/packages/http-client/src/index.d.ts +++ b/packages/http-client/src/index.d.ts @@ -1,17 +1,16 @@ +import type { + BaseInstance, + Breakpoint, + UserProp, +} from "@webstudio-is/react-sdk"; + export type IncludeTypes = "tree" | "props" | "breakpoints"; export type Includes = { [include in IncludeTypes]: T }; + export type Project = { - tree: { - id: string; - root: { - comopnent: string; - id: string; - cssRules: Array; - children: Array; - }; - } & { errors: string }; - props: Array & { errors: string }; - breakpoints: Array<{ label: string; minWidtrh: number; id: string }> & { + tree: BaseInstance & { errors: string }; + props: Array & { errors: string }; + breakpoints: Array & { errors: string; }; }; diff --git a/packages/http-client/src/index.test.ts b/packages/http-client/src/index.test.ts index cdca00f77e..0381dd59ea 100644 --- a/packages/http-client/src/index.test.ts +++ b/packages/http-client/src/index.test.ts @@ -1,4 +1,4 @@ -import { loadProjectFromRest } from "./index"; +import { loadProject } from "./index"; const existingProject = "ab3619d3-831f-46f8-abb6-609558cffd99"; const notPublishedProject = "7ec397c6-b3d0-4967-9073-9d83623fcf8e"; @@ -6,17 +6,17 @@ const nonExistingProject = "1"; describe("getProjectDetails", () => { test("loads existing project", async () => { - const response = await loadProjectFromRest({ projectId: existingProject }); + const response = await loadProject({ projectId: existingProject }); expect(response.tree.id).toBeTruthy(); }); test("loads non-existing project", async () => { - const response = await loadProjectFromRest({ + const response = await loadProject({ projectId: nonExistingProject, }); expect(response.tree.errors).toBe("Project required"); }); test("loads not published project", async () => { - const response = await loadProjectFromRest({ + const response = await loadProject({ projectId: notPublishedProject, }); expect(response.tree.errors).toBe( diff --git a/packages/http-client/src/index.ts b/packages/http-client/src/index.ts index c01032d33b..27b85cdd65 100644 --- a/packages/http-client/src/index.ts +++ b/packages/http-client/src/index.ts @@ -17,7 +17,7 @@ const fetch = async (url: string, options?: RequestInit) => { } }; -const loadProjectFromRest = async ({ +const loadProject = async ({ projectId, host = process.env.DESIGNER_HOST || "localhost:3000", include = { tree: true, props: true, breakpoints: true }, @@ -39,4 +39,4 @@ const loadProjectFromRest = async ({ }; }; -export { loadProjectFromRest }; +export { loadProject }; diff --git a/yarn.lock b/yarn.lock index 618e51585d..ed5b477038 100644 --- a/yarn.lock +++ b/yarn.lock @@ -17021,6 +17021,11 @@ typescript@4.7.4: resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.7.4.tgz#1a88596d1cf47d59507a1bcdfb5b9dfe4d488235" integrity sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ== +typescript@^4.6.2: + version "4.8.3" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.8.3.tgz#d59344522c4bc464a65a730ac695007fdb66dd88" + integrity sha512-goMHfm00nWPa8UvR/CPSvykqf6dVV8x/dp0c5mFTMTIu0u0FlGWRioyy7Nn0PGAdHxpJZnuO/ut+PpQ8UiHAig== + uglify-js@^3.1.4: version "3.16.2" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.16.2.tgz#0481e1dbeed343ad1c2ddf3c6d42e89b7a6d4def" From 568d5eddc8f40eb452d1740aea49df8024c2ddd0 Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Mon, 12 Sep 2022 11:41:03 +0200 Subject: [PATCH 11/12] fix: polyfill fetch --- packages/http-client/package.json | 2 +- packages/http-client/src/fetch-polyfill.ts | 6 ++++ packages/http-client/src/index.ts | 28 ++++++----------- yarn.lock | 36 +++++++++++++++++++++- 4 files changed, 51 insertions(+), 21 deletions(-) create mode 100644 packages/http-client/src/fetch-polyfill.ts diff --git a/packages/http-client/package.json b/packages/http-client/package.json index 42d6e31228..bb0e953424 100644 --- a/packages/http-client/package.json +++ b/packages/http-client/package.json @@ -21,7 +21,7 @@ }, "peerDependencies": {}, "dependencies": { - "isomorphic-unfetch": "^3.1.0" + "node-fetch": "^3.2.10" }, "main": "lib/index.js", "types": "lib/index.d.ts", diff --git a/packages/http-client/src/fetch-polyfill.ts b/packages/http-client/src/fetch-polyfill.ts new file mode 100644 index 0000000000..a2a7307ea8 --- /dev/null +++ b/packages/http-client/src/fetch-polyfill.ts @@ -0,0 +1,6 @@ +import fetch from "node-fetch"; + +if (globalThis.fetch === undefined) { + // @ts-expect-error node-fetch doesn't implement a complete spec + globalThis.fetch = fetch; +} diff --git a/packages/http-client/src/index.ts b/packages/http-client/src/index.ts index 27b85cdd65..acebfe2724 100644 --- a/packages/http-client/src/index.ts +++ b/packages/http-client/src/index.ts @@ -1,22 +1,8 @@ -import isoMorphicFetch from "isomorphic-unfetch"; +import "./fetch-polyfill"; import type { Includes, Project } from "./index.d"; const protocol = process.env.NODE_ENV === "production" ? "https" : "http"; -const fetch = async (url: string, options?: RequestInit) => { - const response = await isoMorphicFetch(url, options); - if (response.ok) { - const contentType = response.headers.get("content-type"); - if (contentType && contentType.indexOf("application/json") !== -1) { - return response.json(); - } else { - return response.text(); - } - } else { - throw new Error(response.statusText); - } -}; - const loadProject = async ({ projectId, host = process.env.DESIGNER_HOST || "localhost:3000", @@ -26,11 +12,15 @@ const loadProject = async ({ host?: string; include?: Includes; }): Promise => { - const domain = `${protocol}://${host}`; + const baseUrl = new URL("/", `${protocol}://${host}`); + const treeUrl = new URL(`/rest/tree/${projectId}`, baseUrl); + const propsUrl = new URL(`/rest/props/${projectId}`, baseUrl); + const breakpointsUrl = new URL(`/rest/breakpoints/${projectId}`, baseUrl); + const [tree, props, breakpoints] = await Promise.all([ - include.tree && fetch(`${domain}/rest/tree/${projectId}`), - include.props && fetch(`${domain}/rest/props/${projectId}`), - include.breakpoints && fetch(`${domain}/rest/breakpoints/${projectId}`), + include.tree && (await fetch(treeUrl)).json(), + include.props && (await fetch(propsUrl)).json(), + include.breakpoints && (await fetch(breakpointsUrl)).json(), ]); return { tree, diff --git a/yarn.lock b/yarn.lock index ed5b477038..3ac831866e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7762,6 +7762,11 @@ data-uri-to-buffer@^3.0.1: resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636" integrity sha512-WboRycPNsVw3B3TL559F7kuBUM4d8CgMEvk6xEJlOp7OBPjt6G7z8WMWlD2rOFZLk6OYfFIUGsCOWzcQH9K2og== +data-uri-to-buffer@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-4.0.0.tgz#b5db46aea50f6176428ac05b73be39a57701a64b" + integrity sha512-Vr3mLBA8qWmcuschSLAOogKgQ/Jwxulv3RNE4FXnYWRGujzrRWQI4m12fQqRkwX06C0KanhLr4hK+GydchZsaA== + data-urls@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-2.0.0.tgz#156485a72963a970f5d5821aaf642bef2bf2db9b" @@ -9468,6 +9473,14 @@ fb-watchman@^2.0.0: dependencies: bser "2.1.1" +fetch-blob@^3.1.2, fetch-blob@^3.1.4: + version "3.2.0" + resolved "https://registry.yarnpkg.com/fetch-blob/-/fetch-blob-3.2.0.tgz#f09b8d4bbd45adc6f0c20b7e787e793e309dcce9" + integrity sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ== + dependencies: + node-domexception "^1.0.0" + web-streams-polyfill "^3.0.3" + fetch-retry@^5.0.2: version "5.0.3" resolved "https://registry.yarnpkg.com/fetch-retry/-/fetch-retry-5.0.3.tgz#edfa3641892995f9afee94f25b168827aa97fe3d" @@ -9704,6 +9717,13 @@ format@^0.2.0: resolved "https://registry.yarnpkg.com/format/-/format-0.2.2.tgz#d6170107e9efdc4ed30c9dc39016df942b5cb58b" integrity sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww== +formdata-polyfill@^4.0.10: + version "4.0.10" + resolved "https://registry.yarnpkg.com/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz#24807c31c9d402e002ab3d8c720144ceb8848423" + integrity sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g== + dependencies: + fetch-blob "^3.1.2" + forwarded@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.2.0.tgz#2269936428aad4c15c7ebe9779a84bf0b2a81811" @@ -13316,6 +13336,11 @@ node-dir@^0.1.10, node-dir@^0.1.17: dependencies: minimatch "^3.0.2" +node-domexception@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/node-domexception/-/node-domexception-1.0.0.tgz#6888db46a1f71c0b76b3f7555016b63fe64766e5" + integrity sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ== + node-fetch@2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" @@ -13328,6 +13353,15 @@ node-fetch@^2.6.1, node-fetch@^2.6.7: dependencies: whatwg-url "^5.0.0" +node-fetch@^3.2.10: + version "3.2.10" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-3.2.10.tgz#e8347f94b54ae18b57c9c049ef641cef398a85c8" + integrity sha512-MhuzNwdURnZ1Cp4XTazr69K0BTizsBroX7Zx3UgDSVcZYKF/6p0CBe4EUb/hLqmzVhl0UpYfgRljQ4yxE+iCxA== + dependencies: + data-uri-to-buffer "^4.0.0" + fetch-blob "^3.1.4" + formdata-polyfill "^4.0.10" + node-int64@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" @@ -17583,7 +17617,7 @@ web-namespaces@^1.0.0: resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.4.tgz#bc98a3de60dadd7faefc403d1076d529f5e030ec" integrity sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw== -web-streams-polyfill@^3.1.1: +web-streams-polyfill@^3.0.3, web-streams-polyfill@^3.1.1: version "3.2.1" resolved "https://registry.yarnpkg.com/web-streams-polyfill/-/web-streams-polyfill-3.2.1.tgz#71c2718c52b45fd49dbeee88634b3a60ceab42a6" integrity sha512-e0MO3wdXWKrLbL0DgGnUV7WHVuw9OUvL4hjgnPkIeEvESk74gAITi5G606JtZPp39cd8HA9VQzCIvA49LpPN5Q== From fdd8b8bd510787fd89c05edc974163d503819d2a Mon Sep 17 00:00:00 2001 From: Andras Bacsai Date: Tue, 13 Sep 2022 09:00:50 +0200 Subject: [PATCH 12/12] fix export --- packages/http-client/src/index.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/http-client/src/index.ts b/packages/http-client/src/index.ts index acebfe2724..80e09ce24f 100644 --- a/packages/http-client/src/index.ts +++ b/packages/http-client/src/index.ts @@ -3,7 +3,7 @@ import type { Includes, Project } from "./index.d"; const protocol = process.env.NODE_ENV === "production" ? "https" : "http"; -const loadProject = async ({ +export const loadProject = async ({ projectId, host = process.env.DESIGNER_HOST || "localhost:3000", include = { tree: true, props: true, breakpoints: true }, @@ -29,4 +29,3 @@ const loadProject = async ({ }; }; -export { loadProject };