diff --git a/.gitignore b/.gitignore index f1d58e68..913d67a4 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ node_modules .DS_Store dist +dist_injected dist-ssr *.local *.log diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..dcc3fec4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,20 @@ +FROM node:15-buster AS builder + +WORKDIR /usr/src/app +COPY package*.json ./ + +RUN yarn --no-cache + +COPY . . +COPY .env.build .env +RUN yarn typecheck +RUN yarn build +RUN npm prune --production + +FROM node:15-buster +WORKDIR /usr/src/app +COPY --from=builder /usr/src/app . +RUN rm ./.env + +EXPOSE 5000 +CMD [ "yarn", "start:inject" ] \ No newline at end of file diff --git a/README.md b/README.md index 64f4a46b..756236f4 100644 --- a/README.md +++ b/README.md @@ -29,14 +29,16 @@ It is also recommended to run `git submodule update` after you pull from upstrea ## CLI Commands -| Command | Description | -| ---------------- | -------------------------------------------- | -| `yarn dev` | Start the Revolt client in development mode. | -| `yarn build` | Build the Revolt client. | -| `yarn preview` | Start a local server with the built client. | -| `yarn lint` | Run ESLint on the client. | -| `yarn fmt` | Run Prettier on the client. | -| `yarn typecheck` | Run TypeScript type checking on the client. | +| Command | Description | +| ------------------- | -------------------------------------------- | +| `yarn dev` | Start the Revolt client in development mode. | +| `yarn build` | Build the Revolt client. | +| `yarn preview` | Start a local server with the built client. | +| `yarn lint` | Run ESLint on the client. | +| `yarn fmt` | Run Prettier on the client. | +| `yarn typecheck` | Run TypeScript type checking on the client. | +| `yarn start` | Start a local sirv server with built client. | +| `yarn start:inject` | Inject a given API URL and start server. | ## License diff --git a/package.json b/package.json index f7a1b84f..5912596d 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,9 @@ "preview": "vite preview", "lint": "eslint 'src/**/*.{js,jsx,ts,tsx}'", "fmt": "prettier --write 'src/**/*.{js,jsx,ts,tsx}'", - "typecheck": "tsc --noEmit" + "typecheck": "tsc --noEmit", + "start": "sirv dist --cors --single --host", + "start:inject": "node scripts/inject.js && sirv dist_injected --cors --single --host" }, "eslintConfig": { "parser": "@typescript-eslint/parser", @@ -90,6 +92,7 @@ "eslint-config-preact": "^1.1.4", "eventemitter3": "^4.0.7", "highlight.js": "^11.0.1", + "klaw": "^3.0.0", "localforage": "^1.9.0", "lodash.defaultsdeep": "^4.6.1", "lodash.isequal": "^4.5.0", @@ -120,6 +123,7 @@ "rimraf": "^3.0.2", "sass": "^1.35.1", "shade-blend-color": "^1.0.0", + "sirv-cli": "^1.0.14", "styled-components": "^5.3.0", "typescript": "^4.3.2", "ulid": "^2.3.0", diff --git a/scripts/inject.js b/scripts/inject.js new file mode 100644 index 00000000..5a4b45a5 --- /dev/null +++ b/scripts/inject.js @@ -0,0 +1,49 @@ +/* eslint-disable */ +const { copy, remove, access, readFile, writeFile } = require("fs-extra"); +const klaw = require("klaw"); + +let target = /__API_URL__/g; +let replacement = process.env.REVOLT_PUBLIC_URL; +let BUILD_DIRECTORY = "dist"; +let OUT_DIRECTORY = "dist_injected"; + +if (typeof replacement === "undefined") { + console.error("No REVOLT_PUBLIC_URL specified in environment variables."); + process.exit(1); +} + +(async () => { + console.log("Ensuring project has been built at least once."); + try { + await access(BUILD_DIRECTORY); + } catch (err) { + console.error("Build project at least once!"); + return process.exit(1); + } + + console.log("Determining if injected build already exists..."); + try { + await access(OUT_DIRECTORY); + + console.log("Deleting existing build..."); + await remove(OUT_DIRECTORY); + } catch (err) {} + + await copy(BUILD_DIRECTORY, OUT_DIRECTORY); + + console.log("Processing bundles..."); + for await (const file of klaw(OUT_DIRECTORY)) { + let path = file.path; + if (path.endsWith(".js")) { + let data = await readFile(path); + if (target.test(data)) { + console.log("Matched file", path); + + let processed = data.toString().replace(target, replacement); + await writeFile(path, processed); + } + } + } + + console.log("Complete."); +})(); diff --git a/publish.sh b/scripts/publish.sh old mode 100644 new mode 100755 similarity index 100% rename from publish.sh rename to scripts/publish.sh diff --git a/yarn.lock b/yarn.lock index 27dd3cfc..64d96793 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1111,6 +1111,11 @@ "@nodelib/fs.scandir" "2.1.5" fastq "^1.6.0" +"@polka/url@^1.0.0-next.20": + version "1.0.0-next.20" + resolved "https://registry.yarnpkg.com/@polka/url/-/url-1.0.0-next.20.tgz#111b5db0f501aa89b05076fa31f0ea0e0c292cd3" + integrity sha512-88p7+M0QGxKpmnkfXjS4V26AnoC/eiqZutE8GLdaI5X12NY75bXSdTY9NkmYb2Xyk1O+MmkuO6Frmsj84V6I8Q== + "@popperjs/core@^2.8.3": version "2.9.3" resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.3.tgz#8b68da1ebd7fc603999cf6ebee34a4899a14b88e" @@ -1932,6 +1937,11 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s= +console-clear@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/console-clear/-/console-clear-1.1.1.tgz#995e20cbfbf14dd792b672cde387bd128d674bf7" + integrity sha512-pMD+MVR538ipqkG5JXeOEbKWS5um1H4LUUccUQG68qpeqBYbzYy79Gh55jkd2TtPdRfUaLWdv6LPP//5Zt0aPQ== + convert-source-map@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.8.0.tgz#f3373c32d21b4d780dd8004514684fb791ca4369" @@ -2492,6 +2502,11 @@ get-own-enumerable-property-symbols@^3.0.0: resolved "https://registry.yarnpkg.com/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.2.tgz#b5fde77f22cbe35f390b4e089922c50bce6ef664" integrity sha512-I0UBV/XOz1XkIJHEUDMZAbzCThU/H8DxmSfmdGcKPnVhu2VfFqr34jr9777IyaTYvxjedWhqVIilEDsCdP5G6g== +get-port@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-3.2.0.tgz#dd7ce7de187c06c8bf353796ac71e099f0980ebc" + integrity sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw= + glob-parent@^5.1.2, glob-parent@~5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" @@ -2535,7 +2550,7 @@ globby@^11.0.3: merge2 "^1.3.0" slash "^3.0.0" -graceful-fs@^4.1.6, graceful-fs@^4.2.0: +graceful-fs@^4.1.6, graceful-fs@^4.1.9, graceful-fs@^4.2.0: version "4.2.8" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== @@ -2890,6 +2905,18 @@ katex@^0.13.9: dependencies: commander "^6.0.0" +klaw@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/klaw/-/klaw-3.0.0.tgz#b11bec9cf2492f06756d6e809ab73a2910259146" + integrity sha512-0Fo5oir+O9jnXu5EefYbVK+mHMBeEVEy2cmctR1O1NECcCkPRreJKrS6Qt/j3KC2C148Dfo9i3pCmCMsdqGr0g== + dependencies: + graceful-fs "^4.1.9" + +kleur@^3.0.0: + version "3.0.3" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-3.0.3.tgz#a79c9ecc86ee1ce3fa6206d1216c501f147fc07e" + integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== + kolorist@^1.2.10: version "1.5.0" resolved "https://registry.yarnpkg.com/kolorist/-/kolorist-1.5.0.tgz#a06f7dd11d1b5fdb743d79c8acd4e1ecbcbd89b3" @@ -2922,6 +2949,11 @@ linkify-it@^3.0.1: dependencies: uc.micro "^1.0.1" +local-access@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/local-access/-/local-access-1.1.0.tgz#e007c76ba2ca83d5877ba1a125fc8dfe23ba4798" + integrity sha512-XfegD5pyTAfb+GY6chk283Ox5z8WexG56OvM06RWLpAc/UHozO8X6xAxEkIitZOtsSMM1Yr3DkHgW5W+onLhCw== + localforage@^1.9.0: version "1.9.0" resolved "https://registry.yarnpkg.com/localforage/-/localforage-1.9.0.tgz#f3e4d32a8300b362b4634cc4e066d9d00d2f09d1" @@ -3077,6 +3109,11 @@ micromatch@^4.0.4: braces "^3.0.1" picomatch "^2.2.3" +mime@^2.3.1: + version "2.5.2" + resolved "https://registry.yarnpkg.com/mime/-/mime-2.5.2.tgz#6e3dc6cc2b9510643830e5f19d5cb753da5eeabe" + integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== + mini-create-react-context@^0.4.0: version "0.4.1" resolved "https://registry.yarnpkg.com/mini-create-react-context/-/mini-create-react-context-0.4.1.tgz#072171561bfdc922da08a60c2197a497cc2d1d5e" @@ -3107,6 +3144,11 @@ mobx@^6.3.2: resolved "https://registry.yarnpkg.com/mobx/-/mobx-6.3.2.tgz#125590961f702a572c139ab69392bea416d2e51b" integrity sha512-xGPM9dIE1qkK9Nrhevp0gzpsmELKU4MFUJRORW/jqxVFIHHWIoQrjDjL8vkwoJYY3C2CeVJqgvl38hgKTalTWg== +mri@^1.1.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/mri/-/mri-1.1.6.tgz#49952e1044db21dbf90f6cd92bc9c9a777d415a6" + integrity sha512-oi1b3MfbyGa7FJMP9GmLTttni5JoICpYBRlq+x5V16fZbLsnL9N3wFqqIm/nIG43FjUFkFh9Epzp/kzUGUnJxQ== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -3649,6 +3691,13 @@ run-parallel@^1.1.9: dependencies: queue-microtask "^1.2.2" +sade@^1.6.0: + version "1.7.4" + resolved "https://registry.yarnpkg.com/sade/-/sade-1.7.4.tgz#ea681e0c65d248d2095c90578c03ca0bb1b54691" + integrity sha512-y5yauMD93rX840MwUJr7C1ysLFBgMspsdTo4UVrDg3fXDvtwOyIqykhVAAm6fk/3au77773itJStObgK+LKaiA== + dependencies: + mri "^1.1.0" + safe-buffer@^5.1.0: version "5.2.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" @@ -3671,6 +3720,11 @@ sdp-transform@^2.14.1: resolved "https://registry.yarnpkg.com/sdp-transform/-/sdp-transform-2.14.1.tgz#2bb443583d478dee217df4caa284c46b870d5827" integrity sha512-RjZyX3nVwJyCuTo5tGPx+PZWkDMCg7oOLpSlhjDdZfwUoNqG1mM8nyj31IGHyaPWXhjbP7cdK3qZ2bmkJ1GzRw== +semiver@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/semiver/-/semiver-1.1.0.tgz#9c97fb02c21c7ce4fcf1b73e2c7a24324bdddd5f" + integrity sha512-QNI2ChmuioGC1/xjyYwyZYADILWyW6AmS1UH6gDj/SFUUUS4MBAWs/7mxnkRPc/F4iHezDP+O8t0dO8WHiEOdg== + semver@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" @@ -3726,6 +3780,29 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" +sirv-cli@^1.0.14: + version "1.0.14" + resolved "https://registry.yarnpkg.com/sirv-cli/-/sirv-cli-1.0.14.tgz#4bc60421b3de9caea80ccd292b5004aca4ce3c81" + integrity sha512-yyUTNr984ANKDloqepkYbBSqvx3buwYg2sQKPWjSU+IBia5loaoka2If8N9CMwt8AfP179cdEl7kYJ//iWJHjQ== + dependencies: + console-clear "^1.1.0" + get-port "^3.2.0" + kleur "^3.0.0" + local-access "^1.0.1" + sade "^1.6.0" + semiver "^1.0.0" + sirv "^1.0.13" + tinydate "^1.0.0" + +sirv@^1.0.13: + version "1.0.17" + resolved "https://registry.yarnpkg.com/sirv/-/sirv-1.0.17.tgz#86e2c63c612da5a1dace1c16c46f524aaa26ac45" + integrity sha512-qx9go5yraB7ekT7bCMqUHJ5jEaOC/GXBxUWv+jeWnb7WzHUFdcQPGWk7YmAwFBaQBrogpuSqd/azbC2lZRqqmw== + dependencies: + "@polka/url" "^1.0.0-next.20" + mime "^2.3.1" + totalist "^1.0.0" + slash@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-3.0.0.tgz#6539be870c165adbd5240220dbe361f1bc4d4634" @@ -3967,6 +4044,11 @@ tiny-warning@^1.0.0, tiny-warning@^1.0.3: resolved "https://registry.yarnpkg.com/tiny-warning/-/tiny-warning-1.0.3.tgz#94a30db453df4c643d0fd566060d60a875d84754" integrity sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA== +tinydate@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/tinydate/-/tinydate-1.3.0.tgz#e6ca8e5a22b51bb4ea1c3a2a4fd1352dbd4c57fb" + integrity sha512-7cR8rLy2QhYHpsBDBVYnnWXm8uRTr38RoZakFSW7Bs7PzfMPNZthuMLkwqZv7MTu8lhQ91cOFYS5a7iFj2oR3w== + tippy.js@^6.3.1: version "6.3.1" resolved "https://registry.yarnpkg.com/tippy.js/-/tippy.js-6.3.1.tgz#3788a007be7015eee0fd589a66b98fb3f8f10181" @@ -3986,6 +4068,11 @@ to-regex-range@^5.0.1: dependencies: is-number "^7.0.0" +totalist@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/totalist/-/totalist-1.1.0.tgz#a4d65a3e546517701e3e5c37a47a70ac97fe56df" + integrity sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g== + tr46@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"