Production ready build (#175)
- Rename `public` -> `client` so it doesn't get copied automagically as-is (without hashes which we want for cache busting), https://vitejs.dev/guide/assets.html#the-public-directory - We still build the version files to `public/` so their copied as-is and Vite handles it for us (so we can use `emptyOutDir`) - Use a multiple entrypoint `.js` Vite build so things can be more intelligently bundled and take less time - We aren't using library mode because it doesn't minify or bundle assets - Using hash asset tags for cache busting. Hash of the file included in the file name - We lookup these hashed assets from `manifest.json` that Vite builds (https://vitejs.dev/guide/backend-integration.html) to serve and preload - In terms of optimized bundles, I know the current output isn't great now but will have to opt to fix that up separately in the future. Tracked by https://github.com/matrix-org/matrix-public-archive/issues/176
This commit is contained in:
parent
50a1d658e8
commit
9c0b6fe85e
|
@ -1,7 +1,7 @@
|
|||
node_modules
|
||||
.DS_Store
|
||||
dist
|
||||
dist-ssr
|
||||
public
|
||||
*.local
|
||||
|
||||
config.user-overrides.json
|
||||
|
|
10
Dockerfile
10
Dockerfile
|
@ -4,7 +4,8 @@
|
|||
# - https://github.com/npm/cli/issues/4769
|
||||
FROM node:16.14.2-buster-slim
|
||||
|
||||
# Pass through some GitHub CI variables which we use in the build
|
||||
# Pass through some GitHub CI variables which we use in the build (for version
|
||||
# files/tags)
|
||||
ARG GITHUB_SHA
|
||||
ENV GITHUB_SHA=$GITHUB_SHA
|
||||
ARG GITHUB_REF
|
||||
|
@ -25,14 +26,13 @@ RUN npm install
|
|||
# Copy what we need for the client-side build
|
||||
COPY config /app/config/
|
||||
COPY build-scripts /app/build-scripts/
|
||||
COPY public /app/public/
|
||||
COPY client /app/client/
|
||||
COPY shared /app/shared/
|
||||
# Also copy the server stuff (we reference the config from the `build-client.js`)
|
||||
COPY server /app/server/
|
||||
# Build the client-side bundle
|
||||
RUN npm run build
|
||||
|
||||
# Copy the rest of the app
|
||||
COPY server /app/server/
|
||||
|
||||
HEALTHCHECK CMD node docker-health-check.js
|
||||
|
||||
ENTRYPOINT ["/bin/bash", "-c", "npm start"]
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
'use strict';
|
||||
|
||||
// A way to build multiple Vite entrypoints
|
||||
|
||||
// We can remove this once Vite supports multiple entrypoints and
|
||||
// https://github.com/vitejs/vite/pull/7047 lands. We can migrate back to a
|
||||
// normal `vite.config.js` and what we had before.
|
||||
//
|
||||
// Related issues:
|
||||
// - https://github.com/vitejs/vite/issues/4530
|
||||
// - https://github.com/vitejs/vite/discussions/1736
|
||||
|
||||
const path = require('path');
|
||||
const vite = require('vite');
|
||||
const mergeOptions = require('merge-options');
|
||||
|
||||
const generateViteConfigForEntryPoint = require('./generate-vite-config-for-entry-point');
|
||||
|
||||
const entryPoints = [
|
||||
path.resolve(__dirname, '../public/js/entry-client-hydrogen.js'),
|
||||
path.resolve(__dirname, '../public/js/entry-client-room-directory.js'),
|
||||
path.resolve(__dirname, '../public/js/entry-client-room-alias-hash-redirect.js'),
|
||||
];
|
||||
|
||||
async function buildClientScripts(extraConfig = {}) {
|
||||
for (const entryPoint of entryPoints) {
|
||||
// Build the client-side JavaScript bundle when we see any changes
|
||||
const viteConfig = mergeOptions(
|
||||
generateViteConfigForEntryPoint(entryPoint),
|
||||
// Since we're building multiple entryPoints, we don't want it to clear out for each one
|
||||
{ build: { emptyOutDir: false } },
|
||||
extraConfig
|
||||
);
|
||||
await vite.build(viteConfig);
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = buildClientScripts;
|
|
@ -1,10 +1,19 @@
|
|||
'use strict';
|
||||
|
||||
const buildClientScripts = require('./build-client-scripts');
|
||||
const writeVersionFiles = require('./write-version-files');
|
||||
const vite = require('vite');
|
||||
const mergeOptions = require('merge-options');
|
||||
|
||||
async function build(extraConfig) {
|
||||
await Promise.all([writeVersionFiles(), buildClientScripts(extraConfig)]);
|
||||
// Require the config before the Vite config so `process.env.NODE_ENV` is set
|
||||
require('../server/lib/config');
|
||||
|
||||
const writeVersionFiles = require('./write-version-files');
|
||||
const viteConfig = require('./vite.config');
|
||||
|
||||
async function buildClient(extraConfig = {}) {
|
||||
await writeVersionFiles();
|
||||
|
||||
const resultantViteConfig = mergeOptions(viteConfig, extraConfig);
|
||||
await vite.build(resultantViteConfig);
|
||||
}
|
||||
|
||||
module.exports = build;
|
||||
module.exports = buildClient;
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
// vite.config.js
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const { defineConfig } = require('vite');
|
||||
|
||||
function generateViteConfigForEntryPoint(entryPoint) {
|
||||
const entryPointName = path.basename(entryPoint, '.js');
|
||||
|
||||
return defineConfig({
|
||||
// We have to specify this otherwise Vite will override NODE_ENV as
|
||||
// `production` when we start the server and watch build in our `start-dev.js`.
|
||||
mode: process.env.NODE_ENV || 'dev',
|
||||
|
||||
//root: './',
|
||||
//base: './',
|
||||
outDir: './dist',
|
||||
// optimizeDeps: {
|
||||
// include: ['matrix-public-archive-shared'],
|
||||
// },
|
||||
resolve: {
|
||||
alias: {
|
||||
// The `file:` packages don't seem resolve correctly so let's add an alias as well
|
||||
// See https://css-tricks.com/adding-vite-to-your-existing-web-app/#aa-aliases
|
||||
'matrix-public-archive-shared': path.resolve(__dirname, '../shared'),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
// Fix `Error: 'default' is not exported by ...` when importin CommonJS files,
|
||||
// see https://github.com/vitejs/vite/issues/2679
|
||||
commonjsOptions: { include: [] },
|
||||
|
||||
lib: {
|
||||
entry: entryPoint,
|
||||
//formats: ['cjs'],
|
||||
name: entryPointName,
|
||||
fileName: (format) => `${entryPointName}.${format}.js`,
|
||||
},
|
||||
rollupOptions: {},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
module.exports = generateViteConfigForEntryPoint;
|
|
@ -0,0 +1,80 @@
|
|||
// vite.config.js
|
||||
'use strict';
|
||||
|
||||
const path = require('path');
|
||||
const {
|
||||
defineConfig, //splitVendorChunkPlugin
|
||||
} = require('vite');
|
||||
|
||||
module.exports = defineConfig({
|
||||
// We have to specify this otherwise Vite will override NODE_ENV as
|
||||
// `production` when we start the server and watch build in our `start-dev.js`.
|
||||
mode: process.env.NODE_ENV || 'dev',
|
||||
|
||||
plugins: [
|
||||
// Alternatively, we can manually configure chunks via
|
||||
// `build.rollupOptions.output.manualChunks`.
|
||||
// Docs: https://vitejs.dev/guide/build.html#chunking-strategy
|
||||
//
|
||||
// This didn't seem to work for me though, so I've done the manual config way.
|
||||
// splitVendorChunkPlugin(),
|
||||
],
|
||||
|
||||
//root: './',
|
||||
//base: './',
|
||||
// optimizeDeps: {
|
||||
// include: ['matrix-public-archive-shared'],
|
||||
// },
|
||||
resolve: {
|
||||
alias: {
|
||||
// The `file:` packages don't seem resolve correctly so let's add an alias as well
|
||||
// See https://css-tricks.com/adding-vite-to-your-existing-web-app/#aa-aliases
|
||||
'matrix-public-archive-shared': path.resolve(__dirname, '../shared'),
|
||||
},
|
||||
},
|
||||
build: {
|
||||
outDir: './dist',
|
||||
rollupOptions: {
|
||||
// Overwrite default `index.html` entry
|
||||
// (https://vitejs.dev/guide/backend-integration.html#backend-integration)
|
||||
input: [
|
||||
path.resolve(__dirname, '../client/js/entry-client-hydrogen.js'),
|
||||
path.resolve(__dirname, '../client/js/entry-client-room-directory.js'),
|
||||
path.resolve(__dirname, '../client/js/entry-client-room-alias-hash-redirect.js'),
|
||||
],
|
||||
output: {
|
||||
assetFileNames: (chunkInfo) => {
|
||||
const { name } = path.parse(chunkInfo.name);
|
||||
// Some of the Hydrogen assets already have hashes in the name so let's remove
|
||||
// that in favor of our new hash.
|
||||
const nameWithoutHash = name.replace(/-[a-z0-9]+$/, '');
|
||||
|
||||
return `assets/${nameWithoutHash}-[hash][extname]`;
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// We want to know how the transformed source relates back to the original source
|
||||
// for easier debugging
|
||||
sourcemap: true,
|
||||
|
||||
// Generate `dist/manifest.json` that we can use to map a given file to it's built
|
||||
// hashed file name and any dependencies it has.
|
||||
manifest: true,
|
||||
// We don't want to use the `ssrManifest` option. It's supposedly "for determining
|
||||
// style links and asset preload directives in production"
|
||||
// (https://vitejs.dev/config/build-options.html#build-ssrmanifest) (also see
|
||||
// https://vitejs.dev/guide/ssr.html#generating-preload-directives) but doesn't seem
|
||||
// very useful or what we want.
|
||||
//
|
||||
// ssrManifest: true,
|
||||
|
||||
// Copy things like the version files from `public/` to `dist/`
|
||||
copyPublicDir: true,
|
||||
|
||||
// Fix `Error: 'default' is not exported by ...` when importing CommonJS files, see
|
||||
// https://github.com/vitejs/vite/issues/2679 and docs:
|
||||
// https://vitejs.dev/guide/dep-pre-bundling.html#monorepos-and-linked-dependencies
|
||||
commonjsOptions: { include: [/shared/] },
|
||||
},
|
||||
});
|
|
@ -38,10 +38,10 @@ async function writeVersionFiles() {
|
|||
);
|
||||
}
|
||||
|
||||
await mkdirp(path.join(__dirname, '../dist/'));
|
||||
await writeFile(path.join(__dirname, '../dist/GIT_COMMIT'), commit);
|
||||
await writeFile(path.join(__dirname, '../dist/VERSION'), branch);
|
||||
await writeFile(path.join(__dirname, '../dist/VERSION_DATE'), new Date().toISOString());
|
||||
await mkdirp(path.join(__dirname, '../public/'));
|
||||
await writeFile(path.join(__dirname, '../public/GIT_COMMIT'), commit);
|
||||
await writeFile(path.join(__dirname, '../public/VERSION'), branch);
|
||||
await writeFile(path.join(__dirname, '../public/VERSION_DATE'), new Date().toISOString());
|
||||
}
|
||||
|
||||
module.exports = writeVersionFiles;
|
||||
|
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
|
@ -0,0 +1,9 @@
|
|||
import 'matrix-public-archive-shared/hydrogen-vm-render-script';
|
||||
|
||||
// Assets
|
||||
// We have to disable no-missing-require lint because it doesn't take into
|
||||
// account `package.json`. `exports`, see
|
||||
// https://github.com/mysticatea/eslint-plugin-node/issues/255
|
||||
// eslint-disable-next-line node/no-missing-import
|
||||
import 'hydrogen-view-sdk/assets/theme-element-light.css';
|
||||
import '../css/styles.css';
|
|
@ -2,6 +2,14 @@ import assert from 'matrix-public-archive-shared/lib/assert';
|
|||
import MatrixPublicArchiveURLCreator from 'matrix-public-archive-shared/lib/url-creator';
|
||||
import redirectIfRoomAliasInHash from 'matrix-public-archive-shared/lib/redirect-if-room-alias-in-hash';
|
||||
|
||||
// Assets
|
||||
// We have to disable no-missing-require lint because it doesn't take into
|
||||
// account `package.json`. `exports`, see
|
||||
// https://github.com/mysticatea/eslint-plugin-node/issues/255
|
||||
// eslint-disable-next-line node/no-missing-import
|
||||
import 'hydrogen-view-sdk/assets/theme-element-light.css';
|
||||
import '../css/styles.css';
|
||||
|
||||
const config = window.matrixPublicArchiveContext.config;
|
||||
assert(config);
|
||||
assert(config.basePath);
|
|
@ -0,0 +1,14 @@
|
|||
import 'matrix-public-archive-shared/room-directory-vm-render-script';
|
||||
|
||||
// Assets
|
||||
// We have to disable no-missing-require lint because it doesn't take into
|
||||
// account `package.json`. `exports`, see
|
||||
// https://github.com/mysticatea/eslint-plugin-node/issues/255
|
||||
// eslint-disable-next-line node/no-missing-import
|
||||
import 'hydrogen-view-sdk/assets/theme-element-light.css';
|
||||
import '../css/styles.css';
|
||||
import '../css/room-directory.css';
|
||||
// Just need to reference the favicon in one of the entry points for it to be copied
|
||||
// over for all
|
||||
import '../img/favicon.ico';
|
||||
import '../img/favicon.svg';
|
|
@ -41,12 +41,364 @@
|
|||
"mocha": "^9.2.1",
|
||||
"nodemon": "^2.0.15",
|
||||
"prettier": "^2.8.7",
|
||||
"vite": "^2.9.6"
|
||||
"vite": "^4.3.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=16.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz",
|
||||
"integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/android-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"android"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/darwin-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/freebsd-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"freebsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz",
|
||||
"integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==",
|
||||
"cpu": [
|
||||
"arm"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ia32": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz",
|
||||
"integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-loong64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz",
|
||||
"integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==",
|
||||
"cpu": [
|
||||
"loong64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-mips64el": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz",
|
||||
"integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==",
|
||||
"cpu": [
|
||||
"mips64el"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-ppc64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz",
|
||||
"integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==",
|
||||
"cpu": [
|
||||
"ppc64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-riscv64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz",
|
||||
"integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==",
|
||||
"cpu": [
|
||||
"riscv64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-s390x": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz",
|
||||
"integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==",
|
||||
"cpu": [
|
||||
"s390x"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/linux-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"linux"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/netbsd-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"netbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/openbsd-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"openbsd"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/sunos-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"sunos"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==",
|
||||
"cpu": [
|
||||
"arm64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-ia32": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz",
|
||||
"integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==",
|
||||
"cpu": [
|
||||
"ia32"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@esbuild/win32-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
|
@ -2889,10 +3241,11 @@
|
|||
}
|
||||
},
|
||||
"node_modules/esbuild": {
|
||||
"version": "0.14.31",
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz",
|
||||
"integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"esbuild": "bin/esbuild"
|
||||
},
|
||||
|
@ -2900,41 +3253,28 @@
|
|||
"node": ">=12"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"esbuild-android-64": "0.14.31",
|
||||
"esbuild-android-arm64": "0.14.31",
|
||||
"esbuild-darwin-64": "0.14.31",
|
||||
"esbuild-darwin-arm64": "0.14.31",
|
||||
"esbuild-freebsd-64": "0.14.31",
|
||||
"esbuild-freebsd-arm64": "0.14.31",
|
||||
"esbuild-linux-32": "0.14.31",
|
||||
"esbuild-linux-64": "0.14.31",
|
||||
"esbuild-linux-arm": "0.14.31",
|
||||
"esbuild-linux-arm64": "0.14.31",
|
||||
"esbuild-linux-mips64le": "0.14.31",
|
||||
"esbuild-linux-ppc64le": "0.14.31",
|
||||
"esbuild-linux-riscv64": "0.14.31",
|
||||
"esbuild-linux-s390x": "0.14.31",
|
||||
"esbuild-netbsd-64": "0.14.31",
|
||||
"esbuild-openbsd-64": "0.14.31",
|
||||
"esbuild-sunos-64": "0.14.31",
|
||||
"esbuild-windows-32": "0.14.31",
|
||||
"esbuild-windows-64": "0.14.31",
|
||||
"esbuild-windows-arm64": "0.14.31"
|
||||
}
|
||||
},
|
||||
"node_modules/esbuild-windows-64": {
|
||||
"version": "0.14.31",
|
||||
"cpu": [
|
||||
"x64"
|
||||
],
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"win32"
|
||||
],
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"@esbuild/android-arm": "0.17.17",
|
||||
"@esbuild/android-arm64": "0.17.17",
|
||||
"@esbuild/android-x64": "0.17.17",
|
||||
"@esbuild/darwin-arm64": "0.17.17",
|
||||
"@esbuild/darwin-x64": "0.17.17",
|
||||
"@esbuild/freebsd-arm64": "0.17.17",
|
||||
"@esbuild/freebsd-x64": "0.17.17",
|
||||
"@esbuild/linux-arm": "0.17.17",
|
||||
"@esbuild/linux-arm64": "0.17.17",
|
||||
"@esbuild/linux-ia32": "0.17.17",
|
||||
"@esbuild/linux-loong64": "0.17.17",
|
||||
"@esbuild/linux-mips64el": "0.17.17",
|
||||
"@esbuild/linux-ppc64": "0.17.17",
|
||||
"@esbuild/linux-riscv64": "0.17.17",
|
||||
"@esbuild/linux-s390x": "0.17.17",
|
||||
"@esbuild/linux-x64": "0.17.17",
|
||||
"@esbuild/netbsd-x64": "0.17.17",
|
||||
"@esbuild/openbsd-x64": "0.17.17",
|
||||
"@esbuild/sunos-x64": "0.17.17",
|
||||
"@esbuild/win32-arm64": "0.17.17",
|
||||
"@esbuild/win32-ia32": "0.17.17",
|
||||
"@esbuild/win32-x64": "0.17.17"
|
||||
}
|
||||
},
|
||||
"node_modules/escalade": {
|
||||
|
@ -3519,9 +3859,24 @@
|
|||
"dev": true,
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"license": "MIT"
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
|
@ -3649,7 +4004,8 @@
|
|||
},
|
||||
"node_modules/has": {
|
||||
"version": "1.0.3",
|
||||
"license": "MIT",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1"
|
||||
},
|
||||
|
@ -3873,8 +4229,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/is-core-module": {
|
||||
"version": "2.8.1",
|
||||
"license": "MIT",
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
|
||||
"integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
|
||||
"dependencies": {
|
||||
"has": "^1.0.3"
|
||||
},
|
||||
|
@ -4411,9 +4768,16 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/nanoid": {
|
||||
"version": "3.3.4",
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"bin": {
|
||||
"nanoid": "bin/nanoid.cjs"
|
||||
},
|
||||
|
@ -4761,8 +5125,9 @@
|
|||
},
|
||||
"node_modules/picocolors": {
|
||||
"version": "1.0.0",
|
||||
"dev": true,
|
||||
"license": "ISC"
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
|
@ -4808,7 +5173,9 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/postcss": {
|
||||
"version": "8.4.14",
|
||||
"version": "8.4.23",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
|
||||
"integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
|
@ -4818,11 +5185,14 @@
|
|||
{
|
||||
"type": "tidelift",
|
||||
"url": "https://tidelift.com/funding/github/npm/postcss"
|
||||
},
|
||||
{
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ai"
|
||||
}
|
||||
],
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"nanoid": "^3.3.4",
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
},
|
||||
|
@ -5149,10 +5519,11 @@
|
|||
"license": "MIT"
|
||||
},
|
||||
"node_modules/resolve": {
|
||||
"version": "1.22.0",
|
||||
"license": "MIT",
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
|
||||
"dependencies": {
|
||||
"is-core-module": "^2.8.1",
|
||||
"is-core-module": "^2.11.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
},
|
||||
|
@ -5214,14 +5585,16 @@
|
|||
}
|
||||
},
|
||||
"node_modules/rollup": {
|
||||
"version": "2.67.2",
|
||||
"version": "3.20.6",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz",
|
||||
"integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"bin": {
|
||||
"rollup": "dist/bin/rollup"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10.0.0"
|
||||
"node": ">=14.18.0",
|
||||
"npm": ">=8.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
|
@ -5409,8 +5782,9 @@
|
|||
},
|
||||
"node_modules/source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
|
@ -5733,30 +6107,36 @@
|
|||
}
|
||||
},
|
||||
"node_modules/vite": {
|
||||
"version": "2.9.6",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.1.tgz",
|
||||
"integrity": "sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"esbuild": "^0.14.27",
|
||||
"postcss": "^8.4.12",
|
||||
"resolve": "^1.22.0",
|
||||
"rollup": "^2.59.0"
|
||||
"esbuild": "^0.17.5",
|
||||
"postcss": "^8.4.21",
|
||||
"rollup": "^3.20.2"
|
||||
},
|
||||
"bin": {
|
||||
"vite": "bin/vite.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.2.0"
|
||||
"node": "^14.18.0 || >=16.0.0"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "~2.3.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/node": ">= 14",
|
||||
"less": "*",
|
||||
"sass": "*",
|
||||
"stylus": "*"
|
||||
"stylus": "*",
|
||||
"sugarss": "*",
|
||||
"terser": "^5.4.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/node": {
|
||||
"optional": true
|
||||
},
|
||||
"less": {
|
||||
"optional": true
|
||||
},
|
||||
|
@ -5765,6 +6145,12 @@
|
|||
},
|
||||
"stylus": {
|
||||
"optional": true
|
||||
},
|
||||
"sugarss": {
|
||||
"optional": true
|
||||
},
|
||||
"terser": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
|
@ -5929,6 +6315,160 @@
|
|||
"shared": {}
|
||||
},
|
||||
"dependencies": {
|
||||
"@esbuild/android-arm": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.17.17.tgz",
|
||||
"integrity": "sha512-E6VAZwN7diCa3labs0GYvhEPL2M94WLF8A+czO8hfjREXxba8Ng7nM5VxV+9ihNXIY1iQO1XxUU4P7hbqbICxg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/android-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-jaJ5IlmaDLFPNttv0ofcwy/cfeY4bh/n705Tgh+eLObbGtQBK3EPAu+CzL95JVE4nFAliyrnEu0d32Q5foavqg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/android-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-446zpfJ3nioMC7ASvJB1pszHVskkw4u/9Eu8s5yvvsSDTzYh4p4ZIRj0DznSl3FBF0Z/mZfrKXTtt0QCoFmoHA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/darwin-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-m/gwyiBwH3jqfUabtq3GH31otL/0sE0l34XKpSIqR7NjQ/XHQ3lpmQHLHbG8AHTGCw8Ao059GvV08MS0bhFIJQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/darwin-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-4utIrsX9IykrqYaXR8ob9Ha2hAY2qLc6ohJ8c0CN1DR8yWeMrTgYFjgdeQ9LIoTOfLetXjuCu5TRPHT9yKYJVg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/freebsd-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-4PxjQII/9ppOrpEwzQ1b0pXCsFLqy77i0GaHodrmzH9zq2/NEhHMAMJkJ635Ns4fyJPFOlHMz4AsklIyRqFZWA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/freebsd-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-lQRS+4sW5S3P1sv0z2Ym807qMDfkmdhUYX30GRBURtLTrJOPDpoU0kI6pVz1hz3U0+YQ0tXGS9YWveQjUewAJw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-arm": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.17.17.tgz",
|
||||
"integrity": "sha512-biDs7bjGdOdcmIk6xU426VgdRUpGg39Yz6sT9Xp23aq+IEHDb/u5cbmu/pAANpDB4rZpY/2USPhCA+w9t3roQg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-2+pwLx0whKY1/Vqt8lyzStyda1v0qjJ5INWIe+d8+1onqQxHLLi3yr5bAa4gvbzhZqBztifYEu8hh1La5+7sUw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-ia32": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.17.17.tgz",
|
||||
"integrity": "sha512-IBTTv8X60dYo6P2t23sSUYym8fGfMAiuv7PzJ+0LcdAndZRzvke+wTVxJeCq4WgjppkOpndL04gMZIFvwoU34Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-loong64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.17.17.tgz",
|
||||
"integrity": "sha512-WVMBtcDpATjaGfWfp6u9dANIqmU9r37SY8wgAivuKmgKHE+bWSuv0qXEFt/p3qXQYxJIGXQQv6hHcm7iWhWjiw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-mips64el": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.17.17.tgz",
|
||||
"integrity": "sha512-2kYCGh8589ZYnY031FgMLy0kmE4VoGdvfJkxLdxP4HJvWNXpyLhjOvxVsYjYZ6awqY4bgLR9tpdYyStgZZhi2A==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-ppc64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.17.17.tgz",
|
||||
"integrity": "sha512-KIdG5jdAEeAKogfyMTcszRxy3OPbZhq0PPsW4iKKcdlbk3YE4miKznxV2YOSmiK/hfOZ+lqHri3v8eecT2ATwQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-riscv64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.17.17.tgz",
|
||||
"integrity": "sha512-Cj6uWLBR5LWhcD/2Lkfg2NrkVsNb2sFM5aVEfumKB2vYetkA/9Uyc1jVoxLZ0a38sUhFk4JOVKH0aVdPbjZQeA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-s390x": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.17.17.tgz",
|
||||
"integrity": "sha512-lK+SffWIr0XsFf7E0srBjhpkdFVJf3HEgXCwzkm69kNbRar8MhezFpkIwpk0qo2IOQL4JE4mJPJI8AbRPLbuOQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/linux-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-XcSGTQcWFQS2jx3lZtQi7cQmDYLrpLRyz1Ns1DzZCtn898cWfm5Icx/DEWNcTU+T+tyPV89RQtDnI7qL2PObPg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/netbsd-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-RNLCDmLP5kCWAJR+ItLM3cHxzXRTe4N00TQyQiimq+lyqVqZWGPAvcyfUBM0isE79eEZhIuGN09rAz8EL5KdLA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/openbsd-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-PAXswI5+cQq3Pann7FNdcpSUrhrql3wKjj3gVkmuz6OHhqqYxKvi6GgRBoaHjaG22HV/ZZEgF9TlS+9ftHVigA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/sunos-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-V63egsWKnx/4V0FMYkr9NXWrKTB5qFftKGKuZKFIrAkO/7EWLFnbBZNM1CvJ6Sis+XBdPws2YQSHF1Gqf1oj/Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/win32-arm64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.17.17.tgz",
|
||||
"integrity": "sha512-YtUXLdVnd6YBSYlZODjWzH+KzbaubV0YVd6UxSfoFfa5PtNJNaW+1i+Hcmjpg2nEe0YXUCNF5bkKy1NnBv1y7Q==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/win32-ia32": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.17.17.tgz",
|
||||
"integrity": "sha512-yczSLRbDdReCO74Yfc5tKG0izzm+lPMYyO1fFTcn0QNwnKmc3K+HdxZWLGKg4pZVte7XVgcFku7TIZNbWEJdeQ==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@esbuild/win32-x64": {
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.17.17.tgz",
|
||||
"integrity": "sha512-FNZw7H3aqhF9OyRQbDDnzUApDXfC1N6fgBhkqEO2jvYCJ+DxMTfZVqg3AX0R1khg1wHTBRD5SdcibSJ+XF6bFg==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"@eslint-community/eslint-utils": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
|
||||
|
@ -7769,36 +8309,35 @@
|
|||
}
|
||||
},
|
||||
"esbuild": {
|
||||
"version": "0.14.31",
|
||||
"version": "0.17.17",
|
||||
"resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.17.17.tgz",
|
||||
"integrity": "sha512-/jUywtAymR8jR4qsa2RujlAF7Krpt5VWi72Q2yuLD4e/hvtNcFQ0I1j8m/bxq238pf3/0KO5yuXNpuLx8BE1KA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild-android-64": "0.14.31",
|
||||
"esbuild-android-arm64": "0.14.31",
|
||||
"esbuild-darwin-64": "0.14.31",
|
||||
"esbuild-darwin-arm64": "0.14.31",
|
||||
"esbuild-freebsd-64": "0.14.31",
|
||||
"esbuild-freebsd-arm64": "0.14.31",
|
||||
"esbuild-linux-32": "0.14.31",
|
||||
"esbuild-linux-64": "0.14.31",
|
||||
"esbuild-linux-arm": "0.14.31",
|
||||
"esbuild-linux-arm64": "0.14.31",
|
||||
"esbuild-linux-mips64le": "0.14.31",
|
||||
"esbuild-linux-ppc64le": "0.14.31",
|
||||
"esbuild-linux-riscv64": "0.14.31",
|
||||
"esbuild-linux-s390x": "0.14.31",
|
||||
"esbuild-netbsd-64": "0.14.31",
|
||||
"esbuild-openbsd-64": "0.14.31",
|
||||
"esbuild-sunos-64": "0.14.31",
|
||||
"esbuild-windows-32": "0.14.31",
|
||||
"esbuild-windows-64": "0.14.31",
|
||||
"esbuild-windows-arm64": "0.14.31"
|
||||
"@esbuild/android-arm": "0.17.17",
|
||||
"@esbuild/android-arm64": "0.17.17",
|
||||
"@esbuild/android-x64": "0.17.17",
|
||||
"@esbuild/darwin-arm64": "0.17.17",
|
||||
"@esbuild/darwin-x64": "0.17.17",
|
||||
"@esbuild/freebsd-arm64": "0.17.17",
|
||||
"@esbuild/freebsd-x64": "0.17.17",
|
||||
"@esbuild/linux-arm": "0.17.17",
|
||||
"@esbuild/linux-arm64": "0.17.17",
|
||||
"@esbuild/linux-ia32": "0.17.17",
|
||||
"@esbuild/linux-loong64": "0.17.17",
|
||||
"@esbuild/linux-mips64el": "0.17.17",
|
||||
"@esbuild/linux-ppc64": "0.17.17",
|
||||
"@esbuild/linux-riscv64": "0.17.17",
|
||||
"@esbuild/linux-s390x": "0.17.17",
|
||||
"@esbuild/linux-x64": "0.17.17",
|
||||
"@esbuild/netbsd-x64": "0.17.17",
|
||||
"@esbuild/openbsd-x64": "0.17.17",
|
||||
"@esbuild/sunos-x64": "0.17.17",
|
||||
"@esbuild/win32-arm64": "0.17.17",
|
||||
"@esbuild/win32-ia32": "0.17.17",
|
||||
"@esbuild/win32-x64": "0.17.17"
|
||||
}
|
||||
},
|
||||
"esbuild-windows-64": {
|
||||
"version": "0.14.31",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"escalade": {
|
||||
"version": "3.1.1"
|
||||
},
|
||||
|
@ -8193,8 +8732,17 @@
|
|||
"version": "1.0.0",
|
||||
"dev": true
|
||||
},
|
||||
"fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1"
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5"
|
||||
|
@ -8277,6 +8825,8 @@
|
|||
},
|
||||
"has": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
|
||||
"integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1"
|
||||
}
|
||||
|
@ -8409,7 +8959,9 @@
|
|||
}
|
||||
},
|
||||
"is-core-module": {
|
||||
"version": "2.8.1",
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.0.tgz",
|
||||
"integrity": "sha512-RECHCBCd/viahWmwj6enj19sKbHfJrddi/6cBDsNTKbNq0f7VeaUkBo60BqzvPqo/W54ChS62Z5qyun7cfOMqQ==",
|
||||
"requires": {
|
||||
"has": "^1.0.3"
|
||||
}
|
||||
|
@ -8741,7 +9293,9 @@
|
|||
"version": "2.0.0"
|
||||
},
|
||||
"nanoid": {
|
||||
"version": "3.3.4",
|
||||
"version": "3.3.6",
|
||||
"resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz",
|
||||
"integrity": "sha512-BGcqMMJuToF7i1rt+2PWSNVnWIkGCU78jBG3RxO/bZlnZPK2Cmi2QaffxGO/2RvWi9sL+FAiRiXMgsyxQ1DIDA==",
|
||||
"dev": true
|
||||
},
|
||||
"natural-compare": {
|
||||
|
@ -8953,6 +9507,8 @@
|
|||
},
|
||||
"picocolors": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
|
||||
"integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
|
||||
"dev": true
|
||||
},
|
||||
"picomatch": {
|
||||
|
@ -8986,10 +9542,12 @@
|
|||
"version": "4.0.0"
|
||||
},
|
||||
"postcss": {
|
||||
"version": "8.4.14",
|
||||
"version": "8.4.23",
|
||||
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.23.tgz",
|
||||
"integrity": "sha512-bQ3qMcpF6A/YjR55xtoTr0jGOlnPOKAIMdOWiv0EIT6HVPEaJiJB4NLljSbiHoC2RX7DN5Uvjtpbg1NPdwv1oA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"nanoid": "^3.3.4",
|
||||
"nanoid": "^3.3.6",
|
||||
"picocolors": "^1.0.0",
|
||||
"source-map-js": "^1.0.2"
|
||||
}
|
||||
|
@ -9175,9 +9733,11 @@
|
|||
}
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.22.0",
|
||||
"version": "1.22.2",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.2.tgz",
|
||||
"integrity": "sha512-Sb+mjNHOULsBv818T40qSPeRiuWLyaGMa5ewydRLFimneixmVy2zdivRl+AF6jaYPC8ERxGDmFSiqui6SfPd+g==",
|
||||
"requires": {
|
||||
"is-core-module": "^2.8.1",
|
||||
"is-core-module": "^2.11.0",
|
||||
"path-parse": "^1.0.7",
|
||||
"supports-preserve-symlinks-flag": "^1.0.0"
|
||||
}
|
||||
|
@ -9212,7 +9772,9 @@
|
|||
}
|
||||
},
|
||||
"rollup": {
|
||||
"version": "2.67.2",
|
||||
"version": "3.20.6",
|
||||
"resolved": "https://registry.npmjs.org/rollup/-/rollup-3.20.6.tgz",
|
||||
"integrity": "sha512-2yEB3nQXp/tBQDN0hJScJQheXdvU2wFhh6ld7K/aiZ1vYcak6N/BKjY1QrU6BvO2JWYS8bEs14FRaxXosxy2zw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fsevents": "~2.3.2"
|
||||
|
@ -9333,6 +9895,8 @@
|
|||
},
|
||||
"source-map-js": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz",
|
||||
"integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==",
|
||||
"dev": true
|
||||
},
|
||||
"split2": {
|
||||
|
@ -9531,14 +10095,15 @@
|
|||
"version": "1.1.2"
|
||||
},
|
||||
"vite": {
|
||||
"version": "2.9.6",
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/vite/-/vite-4.3.1.tgz",
|
||||
"integrity": "sha512-EPmfPLAI79Z/RofuMvkIS0Yr091T2ReUoXQqc5ppBX/sjFRhHKiPPF/R46cTdoci/XgeQpB23diiJxq5w30vdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"esbuild": "^0.14.27",
|
||||
"esbuild": "^0.17.5",
|
||||
"fsevents": "~2.3.2",
|
||||
"postcss": "^8.4.12",
|
||||
"resolve": "^1.22.0",
|
||||
"rollup": "^2.59.0"
|
||||
"postcss": "^8.4.21",
|
||||
"rollup": "^3.20.2"
|
||||
}
|
||||
},
|
||||
"webidl-conversions": {
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
"test": "npm run mocha -- test/**/*-tests.js --timeout 15000",
|
||||
"test-e2e-interactive": "npm run mocha -- test/e2e-tests.js --timeout 15000 --bail --interactive",
|
||||
"nodemon": "nodemon",
|
||||
"gulp": "gulp",
|
||||
"vite": "vite",
|
||||
"mocha": "mocha",
|
||||
"eslint": "eslint",
|
||||
|
@ -33,7 +34,7 @@
|
|||
"mocha": "^9.2.1",
|
||||
"nodemon": "^2.0.15",
|
||||
"prettier": "^2.8.7",
|
||||
"vite": "^2.9.6"
|
||||
"vite": "^4.3.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@opentelemetry/api": "^1.1.0",
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
import 'matrix-public-archive-shared/hydrogen-vm-render-script';
|
|
@ -1 +0,0 @@
|
|||
import 'matrix-public-archive-shared/room-directory-vm-render-script';
|
|
@ -2,10 +2,8 @@
|
|||
|
||||
const assert = require('assert');
|
||||
|
||||
const { getSerializableSpans } = require('../tracing/tracing-middleware');
|
||||
const renderHydrogenToString = require('../hydrogen-render/render-hydrogen-to-string');
|
||||
const sanitizeHtml = require('../lib/sanitize-html');
|
||||
const safeJson = require('../lib/safe-json');
|
||||
const renderPageHtml = require('../hydrogen-render/render-page-html');
|
||||
|
||||
async function renderHydrogenVmRenderScriptToPageHtml({
|
||||
pageOptions,
|
||||
|
@ -15,10 +13,6 @@ async function renderHydrogenVmRenderScriptToPageHtml({
|
|||
assert(vmRenderScriptFilePath);
|
||||
assert(vmRenderContext);
|
||||
assert(pageOptions);
|
||||
assert(pageOptions.title);
|
||||
assert(pageOptions.styles);
|
||||
assert(pageOptions.scripts);
|
||||
assert(pageOptions.cspNonce);
|
||||
|
||||
const hydrogenHtmlOutput = await renderHydrogenToString({
|
||||
vmRenderScriptFilePath,
|
||||
|
@ -26,80 +20,12 @@ async function renderHydrogenVmRenderScriptToPageHtml({
|
|||
pageOptions,
|
||||
});
|
||||
|
||||
// Serialize the state for when we run the Hydrogen render again client-side to
|
||||
// re-hydrate the DOM
|
||||
const serializedMatrixPublicArchiveContext = JSON.stringify({
|
||||
...vmRenderContext,
|
||||
const pageHtml = renderPageHtml({
|
||||
pageOptions,
|
||||
bodyHtml: hydrogenHtmlOutput,
|
||||
vmRenderContext,
|
||||
});
|
||||
|
||||
const serializableSpans = getSerializableSpans();
|
||||
const serializedSpans = JSON.stringify(serializableSpans);
|
||||
|
||||
// We shouldn't let some pages be indexed by search engines
|
||||
let maybeNoIndexHtml = '';
|
||||
if (!pageOptions.shouldIndex) {
|
||||
maybeNoIndexHtml = `<meta name="robots" content="noindex, nofollow" />`;
|
||||
}
|
||||
|
||||
const pageHtml = `
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
${maybeNoIndexHtml}
|
||||
${sanitizeHtml(`<title>${pageOptions.title}</title>`)}
|
||||
<link rel="icon" href="/img/favicon.ico" sizes="any">
|
||||
<link rel="icon" href="/img/favicon.svg" type="image/svg+xml">
|
||||
${pageOptions.styles
|
||||
.map(
|
||||
(styleUrl) =>
|
||||
`<link href="${styleUrl}" rel="stylesheet" nonce="${pageOptions.cspNonce}">`
|
||||
)
|
||||
.join('\n')}
|
||||
</head>
|
||||
<body>
|
||||
${hydrogenHtmlOutput}
|
||||
|
||||
${
|
||||
/**
|
||||
* This inline snippet is used in to scroll the Hydrogen timeline to the
|
||||
* right place immediately when the page loads instead of waiting for
|
||||
* Hydrogen to load, hydrate and finally scroll.
|
||||
*/ ''
|
||||
}
|
||||
<script type="text/javascript" nonce="${pageOptions.cspNonce}">
|
||||
const qs = new URLSearchParams(window?.location?.search);
|
||||
const atEventId = qs.get('at');
|
||||
if (atEventId) {
|
||||
const el = document.querySelector(\`[data-event-id="\${atEventId}"]\`);
|
||||
requestAnimationFrame(() => {
|
||||
el && el.scrollIntoView({ block: 'center' });
|
||||
});
|
||||
} else {
|
||||
const el = document.querySelector('.js-bottom-scroll-anchor');
|
||||
requestAnimationFrame(() => {
|
||||
el && el.scrollIntoView({ block: 'end' });
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" nonce="${pageOptions.cspNonce}">
|
||||
window.matrixPublicArchiveContext = ${safeJson(serializedMatrixPublicArchiveContext)}
|
||||
</script>
|
||||
|
||||
${pageOptions.scripts
|
||||
.map(
|
||||
(scriptUrl) =>
|
||||
`<script type="text/javascript" src="${scriptUrl}" nonce="${pageOptions.cspNonce}"></script>`
|
||||
)
|
||||
.join('\n')}
|
||||
<script type="text/javascript" nonce="${pageOptions.cspNonce}">
|
||||
window.tracingSpansForRequest = ${safeJson(serializedSpans)};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
return pageHtml;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,106 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
|
||||
const { getSerializableSpans } = require('../tracing/tracing-middleware');
|
||||
const sanitizeHtml = require('../lib/sanitize-html');
|
||||
const safeJson = require('../lib/safe-json');
|
||||
const getDependenciesForEntryPointName = require('../lib/get-dependencies-for-entry-point-name');
|
||||
const getFaviconAssetUrls = require('../lib/get-favicon-asset-urls');
|
||||
|
||||
const faviconMap = getFaviconAssetUrls();
|
||||
|
||||
async function renderPageHtml({
|
||||
pageOptions,
|
||||
// Make sure you sanitize this before passing it to us
|
||||
bodyHtml,
|
||||
vmRenderContext,
|
||||
}) {
|
||||
assert(vmRenderContext);
|
||||
assert(pageOptions);
|
||||
assert(pageOptions.title);
|
||||
assert(pageOptions.entryPoint);
|
||||
assert(pageOptions.cspNonce);
|
||||
|
||||
const { styles, scripts } = getDependenciesForEntryPointName(pageOptions.entryPoint);
|
||||
console.log('styles', styles);
|
||||
console.log('scripts', scripts);
|
||||
|
||||
// Serialize the state for when we run the Hydrogen render again client-side to
|
||||
// re-hydrate the DOM
|
||||
const serializedMatrixPublicArchiveContext = JSON.stringify({
|
||||
...vmRenderContext,
|
||||
});
|
||||
|
||||
const serializableSpans = getSerializableSpans();
|
||||
const serializedSpans = JSON.stringify(serializableSpans);
|
||||
|
||||
// We shouldn't let some pages be indexed by search engines
|
||||
let maybeNoIndexHtml = '';
|
||||
if (!pageOptions.shouldIndex) {
|
||||
maybeNoIndexHtml = `<meta name="robots" content="noindex, nofollow" />`;
|
||||
}
|
||||
|
||||
const pageHtml = `
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
${maybeNoIndexHtml}
|
||||
${sanitizeHtml(`<title>${pageOptions.title}</title>`)}
|
||||
<link rel="icon" href="${faviconMap.ico}" sizes="any">
|
||||
<link rel="icon" href="${faviconMap.svg}" type="image/svg+xml">
|
||||
${styles
|
||||
.map(
|
||||
(styleUrl) =>
|
||||
`<link href="${styleUrl}" rel="stylesheet" nonce="${pageOptions.cspNonce}">`
|
||||
)
|
||||
.join('\n')}
|
||||
</head>
|
||||
<body>
|
||||
${bodyHtml}
|
||||
|
||||
${
|
||||
/**
|
||||
* This inline snippet is used in to scroll the Hydrogen timeline to the
|
||||
* right place immediately when the page loads instead of waiting for
|
||||
* Hydrogen to load, hydrate and finally scroll.
|
||||
*/ ''
|
||||
}
|
||||
<script type="text/javascript" nonce="${pageOptions.cspNonce}">
|
||||
const qs = new URLSearchParams(window?.location?.search);
|
||||
const atEventId = qs.get('at');
|
||||
if (atEventId) {
|
||||
const el = document.querySelector(\`[data-event-id="\${atEventId}"]\`);
|
||||
requestAnimationFrame(() => {
|
||||
el && el.scrollIntoView({ block: 'center' });
|
||||
});
|
||||
} else {
|
||||
const el = document.querySelector('.js-bottom-scroll-anchor');
|
||||
requestAnimationFrame(() => {
|
||||
el && el.scrollIntoView({ block: 'end' });
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="text/javascript" nonce="${pageOptions.cspNonce}">
|
||||
window.matrixPublicArchiveContext = ${safeJson(serializedMatrixPublicArchiveContext)}
|
||||
</script>
|
||||
|
||||
${scripts
|
||||
.map(
|
||||
(scriptUrl) =>
|
||||
`<script type="text/javascript" src="${scriptUrl}" nonce="${pageOptions.cspNonce}"></script>`
|
||||
)
|
||||
.join('\n')}
|
||||
<script type="text/javascript" nonce="${pageOptions.cspNonce}">
|
||||
window.tracingSpansForRequest = ${safeJson(serializedSpans)};
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
return pageHtml;
|
||||
}
|
||||
|
||||
module.exports = renderPageHtml;
|
|
@ -0,0 +1,111 @@
|
|||
'use strict';
|
||||
|
||||
const assert = require('assert');
|
||||
const path = require('path').posix;
|
||||
|
||||
// Lazy-load the manifest so we only require it on first call hopefully after the Vite
|
||||
// client build completes.
|
||||
let _manifest;
|
||||
function getManifest() {
|
||||
if (_manifest) {
|
||||
return _manifest;
|
||||
}
|
||||
// We have to disable this because it's built via the Vite client build.
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
_manifest = require('../../dist/manifest.json');
|
||||
return _manifest;
|
||||
}
|
||||
|
||||
let _entryPoints;
|
||||
function getEntryPoints() {
|
||||
if (_entryPoints) {
|
||||
return _entryPoints;
|
||||
}
|
||||
|
||||
const manifest = getManifest();
|
||||
_entryPoints = Object.keys(manifest).filter((name) => {
|
||||
return manifest[name].isEntry;
|
||||
});
|
||||
return _entryPoints;
|
||||
}
|
||||
|
||||
function recurseManifestEntryName(entryName) {
|
||||
const manifest = getManifest();
|
||||
const entry = manifest[entryName];
|
||||
|
||||
// css
|
||||
const styles = [];
|
||||
// imports
|
||||
const scripts = [];
|
||||
// imports, dynamicImports
|
||||
const preloadScripts = [];
|
||||
|
||||
for (const importName of entry.imports || []) {
|
||||
scripts.push(path.join('/', importName));
|
||||
preloadScripts.push(path.join('/', importName));
|
||||
|
||||
const {
|
||||
styles: moreStyles,
|
||||
scripts: moreScripts,
|
||||
preloadScripts: morePreloadScripts,
|
||||
} = recurseManifestEntryName(importName);
|
||||
|
||||
styles.push(...moreStyles);
|
||||
scripts.push(...moreScripts);
|
||||
preloadScripts.push(...morePreloadScripts);
|
||||
}
|
||||
|
||||
for (const dynamicImportName of entry.dynamicImports || []) {
|
||||
preloadScripts.push(path.join('/', dynamicImportName));
|
||||
|
||||
const {
|
||||
styles: moreStyles,
|
||||
scripts: moreScripts,
|
||||
preloadScripts: morePreloadScripts,
|
||||
} = recurseManifestEntryName(dynamicImportName);
|
||||
|
||||
styles.push(...moreStyles);
|
||||
scripts.push(...moreScripts);
|
||||
preloadScripts.push(...morePreloadScripts);
|
||||
}
|
||||
|
||||
for (const cssName of entry.css || []) {
|
||||
styles.push(path.join('/', cssName));
|
||||
}
|
||||
|
||||
return {
|
||||
// css
|
||||
styles,
|
||||
// imports
|
||||
scripts,
|
||||
// dynamicImports
|
||||
preloadScripts,
|
||||
};
|
||||
}
|
||||
|
||||
// Look through the Vite manifest.json and return the dependencies for a given entry
|
||||
function getDependenciesForEntryPointName(entryPointName) {
|
||||
assert(entryPointName);
|
||||
const manifest = getManifest();
|
||||
|
||||
const entry = manifest[entryPointName];
|
||||
assert(
|
||||
entry.isEntry,
|
||||
`You must start with a valid entry point from the Vite manifest.json. Saw ${entryPointName} but the only entry points available are ${JSON.stringify(
|
||||
getEntryPoints(),
|
||||
null,
|
||||
2
|
||||
)}`
|
||||
);
|
||||
|
||||
const { styles, scripts, preloadScripts } = recurseManifestEntryName(entryPointName);
|
||||
|
||||
return {
|
||||
// De-duplicate assets
|
||||
styles: Array.from(new Set(styles)),
|
||||
scripts: Array.from(new Set(scripts)),
|
||||
preloadScripts: Array.from(new Set(preloadScripts)),
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = getDependenciesForEntryPointName;
|
|
@ -0,0 +1,29 @@
|
|||
'use strict';
|
||||
|
||||
const path = require('path').posix;
|
||||
|
||||
// Lazy-load the manifest so we only require it on first call hopefully after the Vite
|
||||
// client build completes.
|
||||
let _manifest;
|
||||
function getManifest() {
|
||||
if (_manifest) {
|
||||
return _manifest;
|
||||
}
|
||||
// We have to disable this because it's built via the Vite client build.
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
_manifest = require('../../dist/manifest.json');
|
||||
return _manifest;
|
||||
}
|
||||
|
||||
function getFaviconAssetUrls() {
|
||||
const manifest = getManifest();
|
||||
const icoAssetPath = path.join('/', manifest['client/img/favicon.ico'].file);
|
||||
const svgAssetFile = path.join('/', manifest['client/img/favicon.svg'].file);
|
||||
|
||||
return {
|
||||
ico: icoAssetPath,
|
||||
svg: svgAssetFile,
|
||||
};
|
||||
}
|
||||
|
||||
module.exports = getFaviconAssetUrls;
|
|
@ -9,18 +9,18 @@ assert(packageInfo.version);
|
|||
|
||||
const packageVersion = packageInfo.version;
|
||||
|
||||
function readFileSync(path) {
|
||||
function readVersionFileSync(path) {
|
||||
try {
|
||||
return fs.readFileSync(path, 'utf8');
|
||||
return fs.readFileSync(path, 'utf8').trim();
|
||||
} catch (err) {
|
||||
console.warn(`Unable to read version tags path=${path}`, err);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
const commit = readFileSync(path.join(__dirname, '../../dist/GIT_COMMIT'), 'utf8').trim();
|
||||
const version = readFileSync(path.join(__dirname, '../../dist/VERSION'), 'utf8').trim();
|
||||
const versionDate = readFileSync(path.join(__dirname, '../../dist/VERSION_DATE'), 'utf8').trim();
|
||||
const commit = readVersionFileSync(path.join(__dirname, '../../dist/GIT_COMMIT'), 'utf8');
|
||||
const version = readVersionFileSync(path.join(__dirname, '../../dist/VERSION'), 'utf8');
|
||||
const versionDate = readVersionFileSync(path.join(__dirname, '../../dist/VERSION_DATE'), 'utf8');
|
||||
|
||||
function getVersionTags() {
|
||||
return {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
const assert = require('assert');
|
||||
|
||||
const getDependenciesForEntryPointName = require('../lib/get-dependencies-for-entry-point-name');
|
||||
|
||||
// Set some preload link headers which we can use with Cloudflare to turn into 103 early
|
||||
// hints, https://developers.cloudflare.com/cache/about/early-hints/
|
||||
//
|
||||
|
@ -12,14 +14,15 @@ const assert = require('assert');
|
|||
function setHeadersToPreloadAssets(res, pageOptions) {
|
||||
assert(res);
|
||||
assert(pageOptions);
|
||||
assert(pageOptions.entryPoint);
|
||||
|
||||
const { styles, scripts } = pageOptions;
|
||||
const { styles, preloadScripts } = getDependenciesForEntryPointName(pageOptions.entryPoint);
|
||||
|
||||
const styleLinks = styles.map((styleUrl) => {
|
||||
return `<${styleUrl}>; rel=preload; as=style`;
|
||||
});
|
||||
|
||||
const scriptLinks = scripts.map((scriptUrl) => {
|
||||
const scriptLinks = preloadScripts.map((scriptUrl) => {
|
||||
return `<${scriptUrl}>; rel=preload; as=script`;
|
||||
});
|
||||
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
const assert = require('assert');
|
||||
const urlJoin = require('url-join');
|
||||
const safeJson = require('../lib/safe-json');
|
||||
const sanitizeHtml = require('../lib/sanitize-html');
|
||||
const renderPageHtml = require('../hydrogen-render/render-page-html');
|
||||
|
||||
const config = require('../lib/config');
|
||||
const basePath = config.get('basePath');
|
||||
|
@ -13,47 +13,38 @@ assert(basePath);
|
|||
// page that will potentially redirect them to the correct place if they tried
|
||||
// `/r/#room-alias:server/date/2022/10/27` -> `/r/room-alias:server/date/2022/10/27`
|
||||
function clientSideRoomAliasHashRedirectRoute(req, res) {
|
||||
const cspNonce = res.locals.cspNonce;
|
||||
const hydrogenStylesUrl = urlJoin(basePath, '/hydrogen-assets/hydrogen-styles.css');
|
||||
const stylesUrl = urlJoin(basePath, '/css/styles.css');
|
||||
const jsBundleUrl = urlJoin(basePath, '/js/entry-client-room-alias-hash-redirect.es.js');
|
||||
|
||||
const context = {
|
||||
config: {
|
||||
basePath,
|
||||
},
|
||||
const pageOptions = {
|
||||
title: `Page not found - Matrix Public Archive`,
|
||||
entryPoint: 'client/js/entry-client-room-alias-hash-redirect.js',
|
||||
locationHref: urlJoin(basePath, req.originalUrl),
|
||||
// We don't have a Matrix room so we don't know whether or not to index. Just choose
|
||||
// a safe-default of false.
|
||||
shouldIndex: false,
|
||||
cspNonce: res.locals.cspNonce,
|
||||
};
|
||||
const serializedContext = JSON.stringify(context);
|
||||
|
||||
const pageHtml = `
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Page not found - Matrix Public Archive</title>
|
||||
<link href="${hydrogenStylesUrl}" rel="stylesheet" nonce="${cspNonce}">
|
||||
<link href="${stylesUrl}" rel="stylesheet" nonce="${cspNonce}">
|
||||
</head>
|
||||
${/* We add the .hydrogen class here just to get normal body styles */ ''}
|
||||
<body class="hydrogen">
|
||||
<h1>
|
||||
404: Page not found.
|
||||
<span class="js-try-redirect-message" style="display: none">One sec while we try to redirect you to the right place.</span>
|
||||
</h1>
|
||||
<p>If there was a #room_alias:server hash in the URL, we tried redirecting you to the right place.</p>
|
||||
<p>
|
||||
Otherwise, you're simply in a place that does not exist.
|
||||
You can ${sanitizeHtml(`<a href="${basePath}">go back to the homepage</a>.`)}
|
||||
</p>
|
||||
|
||||
<script type="text/javascript" nonce="${cspNonce}">
|
||||
window.matrixPublicArchiveContext = ${safeJson(serializedContext)}
|
||||
</script>
|
||||
<script type="text/javascript" src="${jsBundleUrl}" nonce="${cspNonce}"></script>
|
||||
</body>
|
||||
</html>
|
||||
const bodyHtml = `
|
||||
<h1>
|
||||
404: Page not found.
|
||||
<span class="js-try-redirect-message" style="display: none">One sec while we try to redirect you to the right place.</span>
|
||||
</h1>
|
||||
<p>If there was a #room_alias:server hash in the URL, we tried redirecting you to the right place.</p>
|
||||
<p>
|
||||
Otherwise, you're simply in a place that does not exist.
|
||||
You can ${sanitizeHtml(`<a href="${basePath}">go back to the homepage</a>.`)}
|
||||
</p>
|
||||
`;
|
||||
|
||||
const pageHtml = renderPageHtml({
|
||||
pageOptions,
|
||||
bodyHtml,
|
||||
vmRenderContext: {
|
||||
config: {
|
||||
basePath,
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
res.status(404);
|
||||
res.set('Content-Type', 'text/html');
|
||||
res.send(pageHtml);
|
||||
|
|
|
@ -38,32 +38,8 @@ function installRoutes(app) {
|
|||
})
|
||||
);
|
||||
|
||||
// We have to disable no-missing-require lint because it doesn't take into
|
||||
// account `package.json`. `exports`, see
|
||||
// https://github.com/mysticatea/eslint-plugin-node/issues/255
|
||||
app.use(
|
||||
'/hydrogen-assets',
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
express.static(path.dirname(require.resolve('hydrogen-view-sdk/assets/main.js')))
|
||||
);
|
||||
|
||||
app.get(
|
||||
// This has to be at the root so that the font URL references resolve correctly
|
||||
'/hydrogen-assets/hydrogen-styles.css',
|
||||
asyncHandler(async function (req, res) {
|
||||
res.set('Content-Type', 'text/css');
|
||||
// We have to disable no-missing-require lint because it doesn't take into
|
||||
// account `package.json`. `exports`, see
|
||||
// https://github.com/mysticatea/eslint-plugin-node/issues/255
|
||||
// eslint-disable-next-line node/no-missing-require
|
||||
res.sendFile(require.resolve('hydrogen-view-sdk/assets/theme-element-light.css'));
|
||||
})
|
||||
);
|
||||
|
||||
// Our own archive app styles and scripts
|
||||
app.use('/css', express.static(path.join(__dirname, '../../public/css')));
|
||||
app.use('/img', express.static(path.join(__dirname, '../../public/img')));
|
||||
app.use('/js', express.static(path.join(__dirname, '../../dist/')));
|
||||
app.use('/assets', express.static(path.join(__dirname, '../../dist/assets')));
|
||||
|
||||
app.use('/', require('./room-directory-routes'));
|
||||
|
||||
|
|
|
@ -63,15 +63,9 @@ router.get(
|
|||
// We index the room directory unless the config says we shouldn't index anything
|
||||
const shouldIndex = !stopSearchEngineIndexing;
|
||||
|
||||
const hydrogenStylesUrl = urlJoin(basePath, '/hydrogen-assets/hydrogen-styles.css');
|
||||
const stylesUrl = urlJoin(basePath, '/css/styles.css');
|
||||
const roomDirectoryStylesUrl = urlJoin(basePath, '/css/room-directory.css');
|
||||
const jsBundleUrl = urlJoin(basePath, '/js/entry-client-room-directory.es.js');
|
||||
|
||||
const pageOptions = {
|
||||
title: `Matrix Public Archive`,
|
||||
styles: [hydrogenStylesUrl, stylesUrl, roomDirectoryStylesUrl],
|
||||
scripts: [jsBundleUrl],
|
||||
entryPoint: 'client/js/entry-client-room-directory.js',
|
||||
locationHref: urlJoin(basePath, req.originalUrl),
|
||||
shouldIndex,
|
||||
cspNonce: res.locals.cspNonce,
|
||||
|
|
|
@ -870,14 +870,9 @@ router.get(
|
|||
shouldIndex = roomData?.historyVisibility === `world_readable`;
|
||||
}
|
||||
|
||||
const hydrogenStylesUrl = urlJoin(basePath, '/hydrogen-assets/hydrogen-styles.css');
|
||||
const stylesUrl = urlJoin(basePath, '/css/styles.css');
|
||||
const jsBundleUrl = urlJoin(basePath, '/js/entry-client-hydrogen.es.js');
|
||||
|
||||
const pageOptions = {
|
||||
title: `${roomData.name} - Matrix Public Archive`,
|
||||
styles: [hydrogenStylesUrl, stylesUrl],
|
||||
scripts: [jsBundleUrl],
|
||||
entryPoint: 'client/js/entry-client-hydrogen.js',
|
||||
locationHref: urlJoin(basePath, req.originalUrl),
|
||||
shouldIndex,
|
||||
cspNonce: res.locals.cspNonce,
|
||||
|
|
|
@ -16,12 +16,24 @@ buildClient({
|
|||
},
|
||||
});
|
||||
|
||||
const nodeArgs = [];
|
||||
if (process.argv.inspectNode) {
|
||||
nodeArgs.push('--inspect');
|
||||
}
|
||||
if (process.argv.traceWarningsNode) {
|
||||
nodeArgs.push('--trace-warnings');
|
||||
}
|
||||
|
||||
// Pass through some args
|
||||
const args = [];
|
||||
if (process.argv.includes('--tracing')) {
|
||||
if (process.argv.tracing) {
|
||||
args.push('--tracing');
|
||||
}
|
||||
|
||||
if (process.argv.logOutputFromChildProcesses) {
|
||||
args.push('--logOutputFromChildProcesses');
|
||||
}
|
||||
|
||||
// Listen for any changes to files and restart the Node.js server process
|
||||
//
|
||||
// For API docs, see
|
||||
|
@ -32,6 +44,7 @@ nodemon({
|
|||
ignoreRoot: ['.git'],
|
||||
ignore: [path.join(__dirname, '../dist/*')],
|
||||
args,
|
||||
nodeArgs,
|
||||
});
|
||||
|
||||
nodemon
|
||||
|
|
Loading…
Reference in New Issue