fix: Use Build Time Base Path #2964

Merged
konrad merged 2 commits from eljef/frontend:base_path_fix into main 2023-02-03 08:57:29 +00:00
Contributor
  • If a base path is provided at build time, use it.

    • Base path can be set with VIKUNJA_FRONTEND_SUBPATH at
      build time
      • VIKUNJA_FRONTEND_SUBPATH sets import.meta.env.BASE_URL
      • Usages of import.meta.env.BASE_URL are statically replaced
        at build time.
      • If base path is not provided, import.meta.env.BASE_URL
        defaults to '/'.
      • Documentation:
        https://vitejs.dev/guide/env-and-mode.html
  • This uses loadEnv to load an environment file at configuration
    time.

  • This adds a commented example to .env.local.example

  • Fixes:

    • Manifest not loading because of incorrect path.
    • Service Worker not loading because path is incorrect in
      manifest.
    • Service Worker crashing because import of workbox is from
      wrong path.
    • Service Worker not loading a task because path is incorrect
      in event listener.
    • Incorrect URLs being set on window because base path is
      incorrect.
      • ex: /login vs /base/login
* If a base path is provided at build time, use it. * Base path can be set with `VIKUNJA_FRONTEND_SUBPATH` at build time * `VIKUNJA_FRONTEND_SUBPATH` sets `import.meta.env.BASE_URL` * Usages of `import.meta.env.BASE_URL` are statically replaced at build time. * If base path is not provided, `import.meta.env.BASE_URL` defaults to '/'. * Documentation: https://vitejs.dev/guide/env-and-mode.html * This uses loadEnv to load an environment file at configuration time. * Documentation: * https://vitejs.dev/config/#environment-variables * More on environment files: * https://vitejs.dev/guide/env-and-mode.html * `VIKUNJA_FRONTEND_SUBPATH` is the variable in the environment file that will be used to set the base path. * This adds a commented example to .env.local.example * Fixes: * Manifest not loading because of incorrect path. * Service Worker not loading because path is incorrect in manifest. * Service Worker crashing because import of workbox is from wrong path. * Service Worker not loading a task because path is incorrect in event listener. * Incorrect URLs being set on window because base path is incorrect. * ex: `/login` vs `/base/login`
Author
Contributor

All of the areas that are patched were identified through running the app in a test deployment using a sub-directory for the base.

This fixes issues with the service worker URL not being correctly set in index.html, the service worker crashing because it can't import workbox correctly, and URLs in the interface redirecting to not include the base URL. (ie, main page sets URL to /login instead of /base/login.

When using --base during the build, the sub-directory must contain a trailing slash.
ie: --base=/base/

All of the areas that are patched were identified through running the app in a test deployment using a sub-directory for the base. This fixes issues with the service worker URL not being correctly set in index.html, the service worker crashing because it can't import workbox correctly, and URLs in the interface redirecting to not include the base URL. (ie, main page sets URL to /login instead of /base/login. When using `--base` during the build, the sub-directory must contain a trailing slash. ie: `--base=/base/`
Member

Hi eljef!

Thank you for creating a PR!

I've deployed the changes of this PR on a preview environment under this URL: https://2964-basepathfix--vikunja-frontend-preview.netlify.app

You can use this url to view the changes live and test them out.
You will need to manually connect this to an api running somehwere. The easiest to use is https://try.vikunja.io/.

Have a nice day!

Beep boop, I'm a bot.

Hi eljef! Thank you for creating a PR! I've deployed the changes of this PR on a preview environment under this URL: https://2964-basepathfix--vikunja-frontend-preview.netlify.app You can use this url to view the changes live and test them out. You will need to manually connect this to an api running somehwere. The easiest to use is https://try.vikunja.io/. Have a nice day! > Beep boop, I'm a bot.
Member

Hey, thanks for the pull request.

Documentation:
https://cli.vuejs.org/guide/mode-and-env.html

This link is from vue-cli, probably you wantws to paste the other link here as well.

Hey, thanks for the pull request. > Documentation: https://cli.vuejs.org/guide/mode-and-env.html This link is from vue-cli, probably you wantws to paste the other link here as well.
dpschen requested changes 2023-01-17 09:06:54 +00:00
@ -99,3 +99,3 @@
routes: [
{
path: '/',
path: import.meta.env.BASE_URL + '',

I think vue router has a basepath option (cant't search the docs right now on mobile).

I think vue router has a basepath option (cant't search the docs right now on mobile).
It's part of `createWebHistory`: https://router.vuejs.org/api/index.html#createwebhistory
Author
Contributor

I could not get the basepath options to work, and did not know about the createWebHistory. I can rework this part to use it.

I could not get the basepath options to work, and did not know about the createWebHistory. I can rework this part to use it.
Author
Contributor

I've changed to use this.

I've changed to use this.
konrad marked this conversation as resolved
vite.config.ts Outdated
@ -85,3 +85,3 @@
srcDir: 'src',
filename: 'sw.ts',
base: '/',
base: process.env.BASE_URL,

I'm a bit confused: you mention vites base option but don't use it. This is the base option of VitePWA.

I'm a bit confused: you mention vites `base` option but don't use it. This is the base option of VitePWA.
Author
Contributor

Even setting the base option in vite, the PWA setup does not pull that base path. I had to explicitly set it so that the PWA would be pulled from the correct path.

Even setting the base option in vite, the PWA setup does not pull that base path. I had to explicitly set it so that the PWA would be pulled from the correct path.

Maybe using import.meta.env.BASE_URL is the better choice as that will more likely work with the --base CLI option

Maybe using `import.meta.env.BASE_URL` is the better choice as that will more likely work with the `--base` CLI option
Author
Contributor

process.env.BASE_URL is set by --base along with import.meta.env.BASE_URL.

WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta]

vite.config.ts:87:9:
87 │ base: import.meta.env.BASE_URL,
╵ ~~~~~~~~~~~

You need to set the output format to "esm" for "import.meta" to work correctly.

This is why I am using process.env.BASE_URL.

`process.env.BASE_URL` is set by --base along with `import.meta.env.BASE_URL`. >WARNING] "import.meta" is not available with the "cjs" output format and will be empty [empty-import-meta] > > vite.config.ts:87:9: > 87 │ base: import.meta.env.BASE_URL, > ╵ ~~~~~~~~~~~ > > You need to set the output format to "esm" for "import.meta" to work correctly. This is why I am using `process.env.BASE_URL`.

Okay that makes sense.

Okay that makes sense.
eljef marked this conversation as resolved
Member

Usages of process.env.BASE_URL are statically replaced at
build time.

I am not sure about this. Where in the docs did you get this from? it was the case in vue-cli. In vite you would usually use the declare option for statically replacements.

> Usages of process.env.BASE_URL are statically replaced at build time. I am not sure about this. Where in the docs did you get this from? it was the case in vue-cli. In vite you would usually use the `declare` option for statically replacements.
dpschen changed title from fix(base): Use Build Time Base to fix(base): Use Build Time Base path 2023-01-17 13:27:21 +00:00
Author
Contributor

Hey, thanks for the pull request.

Documentation:
https://cli.vuejs.org/guide/mode-and-env.html

This link is from vue-cli, probably you wantws to paste the other link here as well.

This URL is intended. It actually has the documentation for process.env.BASE_URL. This page also includes the information for static replacement of variables.

> Hey, thanks for the pull request. > > > Documentation: > https://cli.vuejs.org/guide/mode-and-env.html > > This link is from vue-cli, probably you wantws to paste the other link here as well. This URL is intended. It actually has the documentation for `process.env.BASE_URL`. This page also includes the information for static replacement of variables.
Author
Contributor

Usages of process.env.BASE_URL are statically replaced at
build time.

I am not sure about this. Where in the docs did you get this from? it was the case in vue-cli. In vite you would usually use the declare option for statically replacements.

This is stated in the documentation here: https://cli.vuejs.org/guide/mode-and-env.html

Note that only NODE_ENV, BASE_URL, and variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. It is to avoid accidentally exposing a private key on the machine that could have the same name.

> > Usages of process.env.BASE_URL are statically replaced at > build time. > > I am not sure about this. Where in the docs did you get this from? it was the case in vue-cli. In vite you would usually use the `declare` option for statically replacements. This is stated in the documentation here: https://cli.vuejs.org/guide/mode-and-env.html > > Note that only NODE_ENV, BASE_URL, and variables that start with VUE_APP_ will be statically embedded into the client bundle with webpack.DefinePlugin. It is to avoid accidentally exposing a private key on the machine that could have the same name.
eljef force-pushed base_path_fix from 9a0da60536 to bb5f00775f 2023-01-17 15:54:55 +00:00 Compare
Author
Contributor

I've pushed an update using createWebHistory with a base set as an argument. This does work for me with the subfolder. Thank you @konrad for pointing that out.

I've pushed an update using `createWebHistory` with a base set as an argument. This does work for me with the subfolder. Thank you @konrad for pointing that out.
Owner

It's just that we don't use vue cli, only vite. You probably mean https://vitejs.dev/guide/build.html#public-base-path for docs.

Does the process described about this in our docs still work with this change? https://vikunja.io/docs/running-vikunja-in-a-subdirectory/

It's just that we don't use vue cli, only vite. You probably mean https://vitejs.dev/guide/build.html#public-base-path for docs. Does the process described about this in our docs still work with this change? https://vikunja.io/docs/running-vikunja-in-a-subdirectory/
Author
Contributor

It's just that we don't use vue cli, only vite. You probably mean https://vitejs.dev/guide/build.html#public-base-path for docs.

While vue cli is not used, the variable is still set and used by the underlying vue components.

Does the process described about this in our docs still work with this change? https://vikunja.io/docs/running-vikunja-in-a-subdirectory/

I followed this process, and ran into the issues that led to me submitting this PR. If you follow the documented process, several areas do not pick up the base path settings. The PWA tries to load from / instead of /base. As does the manifest, etc. Editing paths in index.html and the manifest leads to the PWA crashing because it is trying to load /workbox-version instead of /base/workbox-version.

When initiating the first page, the app redirects to /login instead of /base/login.

> It's just that we don't use vue cli, only vite. You probably mean https://vitejs.dev/guide/build.html#public-base-path for docs. While vue cli is not used, the variable is still set and used by the underlying vue components. > Does the process described about this in our docs still work with this change? https://vikunja.io/docs/running-vikunja-in-a-subdirectory/ I followed this process, and ran into the issues that led to me submitting this PR. If you follow the documented process, several areas do not pick up the base path settings. The PWA tries to load from `/` instead of `/base`. As does the manifest, etc. Editing paths in index.html and the manifest leads to the PWA crashing because it is trying to load `/workbox-version` instead of `/base/workbox-version`. When initiating the first page, the app redirects to `/login` instead of `/base/login`.
Owner

I followed this process, and ran into the issues that led to me submitting this PR.

Okay, but do we need to update the docs?

> I followed this process, and ran into the issues that led to me submitting this PR. Okay, but do we need to update the docs?
Author
Contributor

I followed this process, and ran into the issues that led to me submitting this PR.

Okay, but do we need to update the docs?

If this PR is approved after any requested changes, the only change will be is that --base=/path requires a trailing slash: --base=/path/

> > I followed this process, and ran into the issues that led to me submitting this PR. > > Okay, but do we need to update the docs? If this PR is approved after any requested changes, the only change will be is that `--base=/path` requires a trailing slash: `--base=/path/`
Owner

If this PR is approved after any requested changes, the only change will be is that --base=/path requires a trailing slash: --base=/path/

Can you open a follow up to the docs once this is merged?

> If this PR is approved after any requested changes, the only change will be is that --base=/path requires a trailing slash: --base=/path/ Can you open a follow up to the docs once this is merged?
Author
Contributor

If this PR is approved after any requested changes, the only change will be is that --base=/path requires a trailing slash: --base=/path/

Can you open a follow up to the docs once this is merged?

I'm 100% willing to do this. What repo are the docs located in?

> > If this PR is approved after any requested changes, the only change will be is that --base=/path requires a trailing slash: --base=/path/ > > Can you open a follow up to the docs once this is merged? I'm 100% willing to do this. What repo are the docs located in?
Owner

I'm 100% willing to do this. What repo are the docs located in?

Awesome! They are here: https://kolaente.dev/vikunja/api/src/branch/main/docs/content/doc/setup/subdirectory.md

> I'm 100% willing to do this. What repo are the docs located in? Awesome! They are here: https://kolaente.dev/vikunja/api/src/branch/main/docs/content/doc/setup/subdirectory.md
Author
Contributor

I'm 100% willing to do this. What repo are the docs located in?

Awesome! They are here: https://kolaente.dev/vikunja/api/src/branch/main/docs/content/doc/setup/subdirectory.md

PR submitted as WIP until this one is approved.
vikunja/api#1363

> > I'm 100% willing to do this. What repo are the docs located in? > > Awesome! They are here: https://kolaente.dev/vikunja/api/src/branch/main/docs/content/doc/setup/subdirectory.md PR submitted as WIP until this one is approved. https://kolaente.dev/vikunja/api/pulls/1363
eljef requested review from dpschen 2023-01-17 22:41:27 +00:00
eljef force-pushed base_path_fix from bb5f00775f to b98bb50596 2023-01-17 22:43:59 +00:00 Compare
dpschen reviewed 2023-01-17 23:54:24 +00:00
vite.config.ts Outdated
@ -85,3 +85,3 @@
srcDir: 'src',
filename: 'sw.ts',
base: '/',
base: process.env.BASE_URL,

Just checking:
If process.env.BASE_URL is empty aka undefined wouldn't this set the base property to undefined as well? Does VitePWA handle this case, so that it falls back to /?

Just checking: If `process.env.BASE_URL` is empty aka `undefined` wouldn't this set the `base` property to `undefined` as well? Does VitePWA handle this case, so that it falls back to `/`?
Author
Contributor

This is the only usage of process.env.BASE_URL in the patch. When base: is undefined, it falls back to '/'. I've built and tested this a few times now.

However, to handle this case as a just in case, I could add a ternary?
process.env.BASE_URL ? process.env.BASE_URL : '/'

That will at least set it to '/' in the case of it being falsey (empty / undefined).

This is the only usage of `process.env.BASE_URL` in the patch. When `base:` is undefined, it falls back to '/'. I've built and tested this a few times now. However, to handle this case as a just in case, I could add a ternary? `process.env.BASE_URL ? process.env.BASE_URL : '/'` That will at least set it to '/' in the case of it being falsey (empty / undefined).
Author
Contributor

./ fixes the issue with loading of the PWA from a sub-directory. Using that here.

`./` fixes the issue with loading of the PWA from a sub-directory. Using that here.
eljef marked this conversation as resolved
Member

I found this comment from the vue router author. Considering this we really should use vites base option in the configuration and not the cli flag. because else the PWA base might be different.

I found [this comment](https://github.com/vuejs/router/issues/1550#issuecomment-1244454581) from the vue router author. Considering this we really should use vites base option in the configuration and not the cli flag. because else the PWA base might be different.
Author
Contributor

I found this comment from the vue router author. Considering this we really should use vites base option in the configuration and not the cli flag. because else the PWA base might be different.

This turned out to be a lot simpler than I initially thought. Since I can't access import.meta.env.BASE_URL in vite.config.js, I initially used process.env.BASE_URL. After reading the comment about what the writer said, I did some testing. In just vite.config.js, setting base to './', with the preceding dot, fixes the issue of the service worker not loading correctly. I'll have the updated patch up soon.

> I found [this comment](https://github.com/vuejs/router/issues/1550#issuecomment-1244454581) from the vue router author. Considering this we really should use vites base option in the configuration and not the cli flag. because else the PWA base might be different. This turned out to be a lot simpler than I initially thought. Since I can't access `import.meta.env.BASE_URL` in vite.config.js, I initially used `process.env.BASE_URL`. After reading the comment about what the writer said, I did some testing. In just vite.config.js, setting base to './', with the preceding dot, fixes the issue of the service worker not loading correctly. I'll have the updated patch up soon.
eljef force-pushed base_path_fix from b98bb50596 to 783ceb26c4 2023-01-18 01:17:05 +00:00 Compare
Author
Contributor

Updated commit in place and it is quite minimal now.

I will explore making this more dynamic in the future. I'd like to not build each release if I can help it :)

Updated commit in place and it is quite minimal now. I will explore making this more dynamic in the future. I'd like to not build each release if I can help it :)
konrad approved these changes 2023-01-18 08:26:13 +00:00
Owner

I will explore making this more dynamic in the future. I'd like to not build each release if I can help it :)

I think there's no good way to do this other than building it once with a base url like BASE_URL_TO_REPLACE and then using sed to replace all instances of that

> I will explore making this more dynamic in the future. I'd like to not build each release if I can help it :) I think there's no good way to do this other than building it once with a base url like `BASE_URL_TO_REPLACE` and then using sed to replace all instances of that
dpschen requested changes 2023-01-18 12:14:22 +00:00
vite.config.ts Outdated
@ -85,3 +85,3 @@
srcDir: 'src',
filename: 'sw.ts',
base: '/',
base: './',

Sorry to bother, but I'm still not happy with this, because this option of VitePWA needs to be identical to the Vite base option. I am not sure about using ./ because this might create problems when the first page the user visits is a vikunja subpage (like https://example.com/myvikunjasubpath/labels). The VitePWA base option falls back by default to the Vite base option. So we only need to the Vite base option corectly:

a scope: omitted here for simplicity, the vite-plugin-pwa plugin will use the Vite base option to configure it (default is /)

(see: https://vite-pwa-org.netlify.app/guide/pwa-minimal-requirements.html#web-app-manifest)

Considering that have you tried removing the base option from VitePWA completely?

So I would do the following:

A ) Set the base option of Vite to process.env.VIKUNJA_FRONTEND_SUBPATH. I came up with that name by checking our other build options (@konrad what do you think?). A fallback is not necessary (I checked the source). You couldn't use import.meta.env.BASE_URL because that is something that Vite provides to the application after it initialized. Vite itself doesn't have access to it, because it first has to read out the config file :) .

B) We than add an example configuration to the .env.local.example file.
This way the user can use the normal build instructions using pnpm run build and doesn't have to fiddle with vite or workbox. The latter might change either way soonish since we don't really use the up-to-date way to integrate VitePWA.

C) This should be documented in vikunja/api#1363
The user can either set the env via the .env file or via setting the env dynamically, like:

VIKUNJA_FRONTEND_SUBPATH=myvikunjasubpath && pnpm run build

I'm not sure if it would make sense to use something like cross-env there.


Just that I don't loose this link:
I found this as an example in the vite-plugin-pwa repo where they set the env path similar to how I would let the user do it. Not how I would write our commands in the package.json.

Sorry to bother, but I'm still not happy with this, because this option of *VitePWA* _needs_ to be identical to the Vite base option. I am not sure about using ./ because this might create problems when the first page the user visits is a vikunja subpage (like `https://example.com/myvikunjasubpath/labels`). The VitePWA base option falls back by default to the Vite base option. So we only need to the Vite base option corectly: > a scope: omitted here for simplicity, the vite-plugin-pwa plugin will use the Vite base option to configure it (default is /) *(see: https://vite-pwa-org.netlify.app/guide/pwa-minimal-requirements.html#web-app-manifest)* Considering that have you tried removing the base option from VitePWA completely? So I would do the following: A ) Set the base option of Vite to `process.env.VIKUNJA_FRONTEND_SUBPATH`. I came up with that name by checking [our other build options](https://vikunja.io/docs/config-options/) (@konrad what do you think?). A fallback is not necessary (I checked the source). You couldn't use `import.meta.env.BASE_URL` because that is something that Vite provides to the application after it initialized. Vite itself doesn't have access to it, because it first has to read out the config file :) . B) We than add an example configuration to the [`.env.local.example` file](https://kolaente.dev/vikunja/frontend/src/branch/main/.env.local.example). This way the user can use the normal build instructions using `pnpm run build` and doesn't have to fiddle with vite or workbox. The latter might change either way soonish since we don't really use the up-to-date way to integrate VitePWA. C) This should be documented in https://kolaente.dev/vikunja/api/pulls/1363 The user can either set the env via the `.env` file or via setting the env dynamically, like: ```sh VIKUNJA_FRONTEND_SUBPATH=myvikunjasubpath && pnpm run build ``` I'm not sure if it would make sense to use something like [cross-env](https://github.com/kentcdodds/cross-env) there. ------ Just that I don't loose this link: I found [this](https://github.com/vite-pwa/vite-plugin-pwa/blob/3d6f489b360c971b3a376a1284c34aa260fb03aa/examples/vue-router/package.json#L19-L26) as an example in the vite-plugin-pwa repo where they set the env path similar to how I would let the user do it. _Not_ how I would write our commands in the package.json.

I came up with that name by checking our other build options (@konrad what do you think?)

I don't think that's necessary since the option is not replaced at runtime, build only. It's probably easier to use the base path option provided by vite?

> I came up with that name by checking our other build options (@konrad what do you think?) I don't think that's necessary since the option is not replaced at runtime, build only. It's probably easier to use the base path option provided by vite?

I don't think that's necessary since the option is not replaced at runtime, build only.

What impcat does that have to the naming convention?

It's probably easier to use the base path option provided by vite?

But the env would be used by vite to set the base path option of vite. If we don't provide the option to set the base path via a env variable we don't conform the 12 factor methodology. It's a common pattern.

Since the base path falls back to the cli flag, it wouldn't prevent the user from using the cli flag. I still wouldn't do it since it makes it more complex since the user needs to use more tools (vite instead of only pnpm and copying the workbox as well).

> I don't think that's necessary since the option is not replaced at runtime, build only. What impcat does that have to the naming convention? > It's probably easier to use the base path option provided by vite? But the env would **be used by vite** to set the base path option of vite. If we don't provide the option to set the base path via a env variable we don't conform the 12 factor methodology. It's [a common pattern](https://sourcegraph.com/search?q=context%3Aglobal+file%3Avite%5C.config+base%3A+process.env.BASE_URL&patternType=standard&sm=1&groupBy=repo). Since the base path falls back to the cli flag, it wouldn't prevent the user from using the cli flag. I still wouldn't do it since it makes it more complex since the user needs to use more tools (vite instead of only pnpm and copying the workbox as well).

What impcat does that have to the naming convention?

Not much, I just thought since the other variables using that pattern are used for build-time only this would be confusing. The bigger argument here would be the --base cli flag which I think will only populate the BASE_URL env variable.

Anyway, that's probably nitpicking now.

I'd argue this does not fall under the 12 factor principle because this is not about configuration at runtime.

> What impcat does that have to the naming convention? Not much, I just thought since the other variables using that pattern are used for build-time only this would be confusing. The bigger argument here would be the `--base` cli flag which I think will only populate the `BASE_URL` env variable. Anyway, that's probably nitpicking now. I'd argue this does not fall under the 12 factor principle because this is not about configuration at *runtime*.

Anyway, that's probably nitpicking now.

It really feels like it, I know! Sorry also @eljef.

I just want to solve this kind configuration also for the future.

As far as I understood storing the config in the environment can also apply to the environment of the build pipeline. This is also exactly what they talk about in that segment.

since the other variables using that pattern are used for build-time only

VIKUNJA_FRONTEND_SUBPATH would then be build time configuration.

I know that we try to make most of the stuff configurable via edits in the index.html which is kind of runtime, but I wanted change this in a way so that we still support this and we can configure the same stuff via environment variables during build time.

This way a user can configure everything in one place if he wants to do his custom build. There wouldn't be the need to change the index.html and use custom vite config options during the build.

> Anyway, that's probably nitpicking now. It really feels like it, I know! Sorry also @eljef. I just want to solve this kind configuration also for the future. As far as I understood [storing the config in the environment](https://12factor.net/config) can also apply to the environment of the build pipeline. This is also exactly what they talk about in that segment. > since the other variables using that pattern are used for build-time only `VIKUNJA_FRONTEND_SUBPATH` would then be build time configuration. I know that we try to make most of the stuff configurable via edits in the index.html which is kind of runtime, but I wanted change this in a way so that we still support this _and_ we can configure the same stuff via environment variables during build time. This way a user can configure everything in one place if he wants to do his custom build. There wouldn't be the need to change the index.html _and_ use custom vite config options during the build.
Author
Contributor

Anyway, that's probably nitpicking now.

It really feels like it, I know! Sorry also @eljef.

I'm used to arguing over patches via mailing lists. The level of nitpicking comes down to quote placement, type of quotes, etc... My feelings are hurt in now way :)

I'd much rather work through all concerns and get it done right the first time.

I'll have the patch edited in a bit. I'll use the environment variable VIKUNJA_FRONTEND_SUBPATH and will do a bit of correctness checking on it, such as trailing slash check, etc. It's user input, so it's best to sanity check it. I can push that as a config option and use it in the places that import.meta.env.BASE_URL is used.

This will allow for build pipelines to store the variable for testing as well as keeping the path the same everywhere.

> Anyway, that's probably nitpicking now. > > It really feels like it, I know! Sorry also @eljef. I'm used to arguing over patches via mailing lists. The level of nitpicking comes down to quote placement, type of quotes, etc... My feelings are hurt in now way :) I'd much rather work through all concerns and get it done right the first time. I'll have the patch edited in a bit. I'll use the environment variable `VIKUNJA_FRONTEND_SUBPATH` and will do a bit of correctness checking on it, such as trailing slash check, etc. It's user input, so it's best to sanity check it. I can push that as a config option and use it in the places that `import.meta.env.BASE_URL` is used. This will allow for build pipelines to store the variable for testing as well as keeping the path the same everywhere.

will do a bit of correctness checking on it, such as trailing slash check, etc.

Oh that's nice. I read about using zod for env var checking recently.

I can push that as a config option and use it in the places that import.meta.env.BASE_URL is used.

I think we only need to set Vites base option with VIKUNJA_FRONTEND_SUBPATH. On all the other places it makes sense to keep using import.meta.env.BASE_URL, like you already do, since that's a common pattern.

> will do a bit of correctness checking on it, such as trailing slash check, etc. Oh that's nice. I read about [using zod for env var checking](https://twitter.com/mattpocockuk/status/1615110808219918352) recently. > I can push that as a config option and use it in the places that import.meta.env.BASE_URL is used. I think we only need to set Vites `base` option with `VIKUNJA_FRONTEND_SUBPATH`. On all the other places it makes sense to keep using `import.meta.env.BASE_URL`, like you already do, since that's a common pattern.
Author
Contributor

I think we only need to set Vites base option with VIKUNJA_FRONTEND_SUBPATH.

Does this cover the case where the user uses --base AND
VIKUNJA_FRONTEND_SUBPATH? I don't want to have the --base option override VIKUNJA_FRONTEND_SUBPATH.

If using VIKUNJA_FRONTEND_SUBPATH overrides the --base option, then I agree.

I know that having both shouldn't be something that happens, but I am not above making sure someone is building correctly.

> I think we only need to set Vites base option with VIKUNJA_FRONTEND_SUBPATH. Does this cover the case where the user uses `--base` AND `VIKUNJA_FRONTEND_SUBPATH`? I don't want to have the `--base` option override `VIKUNJA_FRONTEND_SUBPATH`. If using `VIKUNJA_FRONTEND_SUBPATH` overrides the `--base` option, then I agree. I know that having both shouldn't be something that happens, but I am not above making sure someone is building correctly.

If the user sets the --base flag it will override the config that was set in the config file (see here and then used here). But that is fine since we would internally only use import.meta.env.BASE_URL which is based on the resolved config.

If there is no env or flag set it will fall back to /.

The resolveBaseUrl also does some testing so you don't have to go too far with the tests. I'm actually unsure if you should add any tests, since there might be other cases where a missing / in the end might be wanted/needed by the user.

If the user sets the `--base` flag it **will** override the config that was set in the config file (see [here](https://github.com/vitejs/vite/blob/a6df6b4a21897e15c4ec0ae1ca4070eaa5d16946/packages/vite/src/node/config.ts#LL1109C23-L1109C23) and then used [here](https://github.com/vitejs/vite/blob/a6df6b4a21897e15c4ec0ae1ca4070eaa5d16946/packages/vite/src/node/config.ts#L442)). But that is fine since we would internally only use `import.meta.env.BASE_URL` which is based on the resolved config. If there is no env or flag set [it will fall back to `/`](https://github.com/vitejs/vite/blob/a6df6b4a21897e15c4ec0ae1ca4070eaa5d16946/packages/vite/src/node/config.ts#L522). The `resolveBaseUrl` also does some testing so you don't have to go too far with the tests. I'm actually unsure if you should add any tests, since there might be other cases where a missing `/` in the end might be wanted/needed by the user.
eljef marked this conversation as resolved
dpschen requested review from konrad 2023-01-18 12:14:37 +00:00
eljef force-pushed base_path_fix from 783ceb26c4 to 020d3e6ec1 2023-01-18 16:47:03 +00:00 Compare
eljef force-pushed base_path_fix from 020d3e6ec1 to 385e2b389b 2023-01-18 16:55:17 +00:00 Compare
Author
Contributor

Patch updated and pushed. The PR's message has been updated.

The base path is now set from VIKUNJA_FRONTEND_SUBPATH. This correctly sets all paths. This is also future facing as when you implement loading from .env files, The resolved environment can set this.

I updated the documentation PR to match. I tested builds with and without the variable set. The build correctly sets the paths in both cases.

You can also change the variable name later after a nitpicking match. 😆

Patch updated and pushed. The PR's message has been updated. The base path is now set from `VIKUNJA_FRONTEND_SUBPATH`. This correctly sets all paths. This is also future facing as when you implement loading from `.env` files, The resolved environment can set this. I updated the documentation PR to match. I tested builds with and without the variable set. The build correctly sets the paths in both cases. You can also change the variable name later after a nitpicking match. 😆
eljef requested review from dpschen 2023-01-18 17:09:23 +00:00
Member

Thanks a lot! :)

The only thing I'm missing now is a line in that newly merged .env.local.example filling out our new variable. Can you rebase on top of main?

Thanks a lot! :) The only thing I'm missing now is a line in that [newly merged .env.local.example](https://kolaente.dev/vikunja/frontend/src/branch/main/.env.local.example) filling out our new variable. Can you rebase on top of main?
eljef force-pushed base_path_fix from 385e2b389b to 1a8fc57ec2 2023-01-18 21:27:44 +00:00 Compare
Author
Contributor

Thanks a lot! :)

The only thing I'm missing now is a line in that newly merged .env.local.example filling out our new variable. Can you rebase on top of main?

Rebased.

Also, to access .env files at configuration time, you need to do a little extra work, per the documentation.

https://vitejs.dev/config/#environment-variables

> Thanks a lot! :) > > The only thing I'm missing now is a line in that [newly merged .env.local.example](https://kolaente.dev/vikunja/frontend/src/branch/main/.env.local.example) filling out our new variable. Can you rebase on top of main? Rebased. Also, to access `.env` files at configuration time, you need to do a little extra work, per the documentation. https://vitejs.dev/config/#environment-variables
Member

Also, to access .env files at configuration time, you need to do a little extra work, per the documentation.

https://vitejs.dev/config/#environment-variables

Wow, you are right. I guess the base doesn't work right now if, if it is defined via the env file. Only via a var already set via the environment.

Can you make it work?

> Also, to access `.env` files at configuration time, you need to do a little extra work, per the documentation. > > https://vitejs.dev/config/#environment-variables Wow, you are right. I guess the `base` doesn't work right now if, if it is defined via the env file. Only via a var already set via the environment. Can you make it work?
Author
Contributor

Can you make it work?

I think I can. Now the question is, should that be included in the scope of this PR?

> Can you make it work? I think I can. Now the question is, should that be included in the scope of this PR?
Author
Contributor

Can you make it work?

I think I can. Now the question is, should that be included in the scope of this PR?

I think, if it is possible, that I'd like to put the env expansion work in a new PR.

> > Can you make it work? > > I think I can. Now the question is, should that be included in the scope of this PR? I think, if it is possible, that I'd like to put the env expansion work in a new PR.
eljef closed this pull request 2023-01-19 21:58:38 +00:00
Author
Contributor

OK, I did not want to close this. Tabbing does not take focus to the UI elements one would think it does :(

OK, I did not want to close this. Tabbing does not take focus to the UI elements one would think it does :(
eljef reopened this pull request 2023-01-19 22:00:41 +00:00
Owner

I think, if it is possible, that I'd like to put the env expansion work in a new PR.

Fine by me to do this in another PR 👍

> I think, if it is possible, that I'd like to put the env expansion work in a new PR. Fine by me to do this in another PR 👍
Author
Contributor

I've updated the documentation PR to not be WIP. I'm working on the loading of the environment file and setting the base via that method.

I've updated the documentation PR to not be WIP. I'm working on the loading of the environment file and setting the base via that method.
Member

should that be included in the scope of this PR?

Let's just change those two lines and then this PR should be ready to go.

> should that be included in the scope of this PR? Let's just change those two lines and then this PR should be ready to go.
Member

Fine by me to do this in another PR 👍

Also fine be me!

> Fine by me to do this in another PR 👍 Also fine be me!
eljef force-pushed base_path_fix from 1a8fc57ec2 to 3bbbcf3353 2023-01-20 00:24:43 +00:00 Compare
eljef changed title from fix(base): Use Build Time Base path to Use Build Time Base path 2023-01-20 00:26:10 +00:00
Author
Contributor

OK. I think I landed on a full, final approach to supporting VIKUNJA_FRONTEND_SUBPATH and having it properly set throughout the code base.

There are two ways of setting the base path supported.

  • Via environment variable at build time.
    • VIKUNJA_FRONTEND_SUBPATH=/subpath/ pnpm vite build
  • Via .env files.
    • Set VIKUNJA_FRONTEND_SUBPATH in the env file.

I even added a quick check function to vite.config.ts to resolve which build path variable has been specified. It resolves in order of CLI provided environment variable, then .env file, and finally falling back to '/'. The function also verifies the provided path ends with a trailing slash.

I tested with the following conditions:

  • pnp run build with no vars set. (base condition)
  • VIKUNJA_FRONTEND_SUBPATH=/subpath pnpm run build
  • VIKUNJA_FRONTEND_SUBPATH=/subpath/ pnpm run build
  • pnpm run build with VIKUNJA_FRONTEND_SUBPATH=/subpath set in .env.local
  • pnpm run build with VIKUNJA_FRONTEND_SUBPATH=/subpath/ set in .env.local
  • pnpm run build with VIKUNJA_FRONTEND_SUBPATH=/subpath set in .env.production.local
  • pnpm run build with VIKUNJA_FRONTEND_SUBPATH=/subpath/ set in .env.production.local

All builds resulted in a properly set base path set in index.html, manifest.webmanifest, and sw.js. I'll update the documenation PR to reflect.

OK. I think I landed on a full, final approach to supporting `VIKUNJA_FRONTEND_SUBPATH` and having it properly set throughout the code base. There are two ways of setting the base path supported. * Via environment variable at build time. * `VIKUNJA_FRONTEND_SUBPATH=/subpath/ pnpm vite build` * Via .env files. * Set `VIKUNJA_FRONTEND_SUBPATH` in the env file. I even added a quick check function to vite.config.ts to resolve which build path variable has been specified. It resolves in order of CLI provided environment variable, then .env file, and finally falling back to '/'. The function also verifies the provided path ends with a trailing slash. I tested with the following conditions: * `pnp run build` with no vars set. (base condition) * `VIKUNJA_FRONTEND_SUBPATH=/subpath pnpm run build` * `VIKUNJA_FRONTEND_SUBPATH=/subpath/ pnpm run build` * `pnpm run build` with `VIKUNJA_FRONTEND_SUBPATH=/subpath` set in `.env.local` * `pnpm run build` with `VIKUNJA_FRONTEND_SUBPATH=/subpath/` set in `.env.local` * `pnpm run build` with `VIKUNJA_FRONTEND_SUBPATH=/subpath` set in `.env.production.local` * `pnpm run build` with `VIKUNJA_FRONTEND_SUBPATH=/subpath/` set in `.env.production.local` All builds resulted in a properly set base path set in `index.html`, `manifest.webmanifest`, and `sw.js`. I'll update the documenation PR to reflect.
Author
Contributor

In the future, if you want to set variables to be pulled through the code base during configuration, you can add the define key in configuration and reference env. So, this is future looking by accident ;p

In the future, if you want to set variables to be pulled through the code base during configuration, you can add the define key in configuration and reference env. So, this is future looking by accident ;p
eljef force-pushed base_path_fix from 3bbbcf3353 to c4f8fd962a 2023-01-20 06:16:48 +00:00 Compare
konrad approved these changes 2023-01-20 12:56:44 +00:00
konrad left a comment
Owner

Looks good!

@dpschen can you take another look?

Looks good! @dpschen can you take another look?
dpschen was assigned by konrad 2023-01-20 12:56:51 +00:00
Member

I'm really unsure about the requirement of the trailing /.
I vaguely remember having built something on a server where there was never one.

Would this also work for this case?

I do know that vue-router doesn't care if there is a trailing / or not (see strict option).

After checking out the source and history of Vite's config parser I'm also sure that this is not an easy topic, considering the changes that happened there regarding the base option.

I found this line in the Vite's source where it gets clear that the base in the resolved config gets added a trailing slash automatically

Might also be that I am now simply confused 😆 after going through all that stuff.

The loadEnv function includes already all process.env when called with an empty string. So if not a problem otherwise (see paragraph above) we only need to add the trailing slash if the returned config from loadEnv does contain something.

I'm really unsure about the requirement of the trailing `/`. I vaguely remember having built something on a server where there was never one. Would this also work for this case? I do know that vue-router doesn't care if there is a trailing `/` or not (see [strict option](https://router.vuejs.org/guide/essentials/route-matching-syntax.html#sensitive-and-strict-route-options)). After checking out the source and history of Vite's config parser I'm also sure that [this](https://github.com/vitejs/vite/issues/9236) [is](https://github.com/vitejs/vite/pull/10590) [__not__](https://github.com/vitejs/vite/issues/8770) [an easy](https://github.com/vitejs/vite/issues/6596) [topic](https://github.com/vitejs/vite/pull/8772), considering the changes that happened there regarding the `base` option. I found this line in the Vite's source where it gets clear that [the base in the resolved config gets added a trailing slash automatically]( https://github.com/vitejs/vite/blob/b35fe883fdc699ac1450882562872095abe9959b/packages/vite/src/node/config.ts#L643) Might also be that I am now simply confused 😆 after going through all that stuff. The `loadEnv` function [includes already all `process.env` when called with an empty string](https://github.com/vitejs/vite/blob/main/packages/vite/src/node/env.ts#L73-L77). So if not a problem otherwise (see paragraph above) we only need to add the trailing slash if the returned config from `loadEnv` does contain something.
Author
Contributor

If it were only the router, the trailing slash would not be needed. The router does indeed handle the case just fine.

The cases that aren't handled are in the appending of the base path in the service worker. If there is not a trailing slash, your could combine /basepath and /sw.js just fine. But, in the case where base is /, you would end up with //sw.js. I ran into that in testing. And if you register just sw.js with no path, and then append a base with no trailing slash, you end up with /basesw.js. So, to fix it for this, and for any future URL writes needed outside of the router, I made the function that adds the trailing slash.

And in the sw.ts itself, the imports of workbox are similarly affected.

If it were only the router, the trailing slash would not be needed. The router does indeed handle the case just fine. The cases that aren't handled are in the appending of the base path in the service worker. If there is not a trailing slash, your could combine `/basepath` and `/sw.js` just fine. But, in the case where base is `/`, you would end up with `//sw.js`. I ran into that in testing. And if you register just `sw.js` with no path, and then append a base with no trailing slash, you end up with `/basesw.js`. So, to fix it for this, and for any future URL writes needed outside of the router, I made the function that adds the trailing slash. And in the sw.ts itself, the imports of workbox are similarly affected.
eljef closed this pull request 2023-01-20 17:42:52 +00:00
eljef reopened this pull request 2023-01-20 17:42:57 +00:00
Author
Contributor

Ugh Gitea.... The tab order for UI elements REALLY needs to be reordered. And why is the close button located so precariously close to the comment button anyway?

Ugh Gitea.... The tab order for UI elements REALLY needs to be reordered. And why is the close button located so precariously close to the comment button anyway?
eljef force-pushed base_path_fix from c4f8fd962a to e5a4548071 2023-01-20 18:37:59 +00:00 Compare
eljef force-pushed base_path_fix from e5a4548071 to 854b883c7c 2023-01-20 23:36:42 +00:00 Compare
Author
Contributor

After running all sorts of tests, this is the iteration I came up with. The function is removed and instead a basic if check is used to ensure the base has a trailing slash.

The router itself does not need the trailing slash because it has logic to correctly handle the slashes on the base when joining a child path to it.

It is outside the router where things gets hairy. An example is registerServiceWorker.ts
In order to register the service worker, the base path must be appended in the register() call. So the path is concatenated. But there are conditions in which the concatenation could go wrong.

  • register(base + '/sw.js')
    • In default with not base provided, base falls back to /
    • This results in register(//sw.js)
  • register(base + 'sw.js')
    • If base does not have a trailing /
    • This results in register(/basesw.js)

The user doesn't have to provide a trailing slash. I can knock that out of the documentation. The code will handle that for them. But, outside of the router where path resolution and normalization is not happening, the trailing slash is needed to make sure paths are proper.

After running all sorts of tests, this is the iteration I came up with. The function is removed and instead a basic `if` check is used to ensure the base has a trailing slash. The router itself does not need the trailing slash because it has logic to correctly handle the slashes on the base when joining a child path to it. It is outside the router where things gets hairy. An example is `registerServiceWorker.ts` In order to register the service worker, the base path must be appended in the `register()` call. So the path is concatenated. But there are conditions in which the concatenation could go wrong. * `register(base + '/sw.js')` * In default with not base provided, base falls back to `/` * This results in `register(//sw.js)` * `register(base + 'sw.js')` * If base does not have a trailing `/` * This results in `register(/basesw.js)` The user doesn't have to provide a trailing slash. I can knock that out of the documentation. The code will handle that for them. But, outside of the router where path resolution and normalization is not happening, the trailing slash is needed to make sure paths are proper.
Author
Contributor

@dpschen Any news on this after the last push and my last comment?

@dpschen Any news on this after the last push and my last comment?
eljef force-pushed base_path_fix from 854b883c7c to da7fd100e9 2023-01-23 17:09:12 +00:00 Compare
eljef force-pushed base_path_fix from da7fd100e9 to 182b5741af 2023-01-24 23:41:20 +00:00 Compare
Author
Contributor

Patches for the PR updated to not require any kind of trailing slash.

Places in the code, outside of the router, that use URLs use the urlJoin function to make sure a proper path is built from import.meta.env.BASE_URL and whatever path is being appended. This will make sure a path doesn't end up being formatted as //path or /pathsubpath or path//subpath. There will always be a proper path/subpath or /path/subpath.

So far, the only places outside of the router that require this are in src/registerServiceWorker.ts and src/sw.ts.

This 100% eliminates any need for a trailing slash and even allows for correction of some user error. ie: If a user were to add slashes after or something.

This does add a dependency on the url-join package, found at https://github.com/jfromaniello/url-join.

I tried the URL function that is supported in browsers, but URL does not maintain the /subpath of a URL. It replaces the path. More on URL can be found here. https://developer.mozilla.org/en-US/docs/Web/API/URL/URL

Patches for the PR updated to not require any kind of trailing slash. Places in the code, outside of the router, that use URLs use the urlJoin function to make sure a proper path is built from `import.meta.env.BASE_URL` and whatever path is being appended. This will make sure a path doesn't end up being formatted as `//path` or `/pathsubpath` or `path//subpath`. There will always be a proper `path/subpath` or `/path/subpath`. So far, the only places outside of the router that require this are in `src/registerServiceWorker.ts` and `src/sw.ts`. This 100% eliminates any need for a trailing slash and even allows for correction of some user error. ie: If a user were to add slashes after or something. This does add a dependency on the `url-join` package, found at https://github.com/jfromaniello/url-join. I tried the `URL` function that is supported in browsers, but `URL` does not maintain the `/subpath` of a URL. It replaces the path. More on `URL` can be found here. https://developer.mozilla.org/en-US/docs/Web/API/URL/URL
Member

Sorry for the delay. I like the last aproach!

Are you sure a client side library like join-url is even needed? Maybe a simple conditional for the leading backslash like you had in the version before would suffice for sw.js and registerserviceworker. Vite has e.g. an internal joinUrlSegments.

I'm taking the blame here because of my bad variable name VIKUNJA_FRONTEND_SUBPATH I proposed. My idea was to explain better what the variable is. Seems like Vites base did already a good job there. What I mean is: there should never be a path before the base aka subpath, because Vite needs the full path (in the sense of URL.pathname).

If we still nee a lib: We have a url library called ufo already included in Vikunja (see e.g. the use of parseUrl here). Maybe we can use the joinUrl from there.

The user error correction is something that in this case I think we don't need on client side. If we would check it would probably be better to let the build fail instead of correcting on runtime. But I don't think we should intervene there (not sure right now is there could be a weird valid reason to use //, e.g. someone assigned your project to that path but you don't have influence on it).

Sorry for the delay. I like the last aproach! Are you sure a client side library like join-url is even needed? Maybe a simple conditional for the leading backslash like you had in the version before would suffice for sw.js and registerserviceworker. Vite has e.g. an internal [`joinUrlSegments`](https://github.com/vitejs/vite/blob/8a40ea41ac435c587014bd28d1955d139ef9266d/packages/vite/src/node/utils.ts#L1229-L1240). I'm taking the blame here because of my bad variable name `VIKUNJA_FRONTEND_SUBPATH` I proposed. My idea was to explain better what the variable is. Seems like Vites `base` did already a good job there. What I mean is: there should never be a path before the base aka subpath, because Vite needs the full path (in the sense of `URL.pathname`). If we still nee a lib: We have a url library called ufo already included in Vikunja (see e.g. [the use of `parseUrl` here](https://kolaente.dev/vikunja/frontend/src/commit/8f25f5d353064f383e97bbc524ce6e00ba559d0f/src/components/misc/api-config.vue#L62-L64)). Maybe we can use the [`joinUrl` from there](https://github.com/unjs/ufo#joinurl). The user error correction is something that in this case I think we don't need on client side. If we would check it would probably be better to let the build fail instead of correcting on runtime. But I don't think we should intervene there (not sure right now is there could be a weird valid reason to use `//`, e.g. someone assigned your project to that path but you don't have influence on it).
Author
Contributor

The client side library is not needed if we can do the simple check at build time. The simple check makes it so there is no trailing slash needed to be added by the user. It'll be verified at build time and the trailing slash will be added just for the external libraries. I'll gladly revert it back to the simple conditional. The client library was only added because it seemed that you were hoping to eliminate the conditional and backslash all together.

I'll add the conditional and remove the dependency and get this in order.

The client side library is not needed if we can do the simple check at build time. The simple check makes it so there is no trailing slash needed to be added by the user. It'll be verified at build time and the trailing slash will be added just for the external libraries. I'll gladly revert it back to the simple conditional. The client library was only added because it seemed that you were hoping to eliminate the conditional and backslash all together. I'll add the conditional and remove the dependency and get this in order.
Member

Awesome! :)

I'll add the conditional and remove the dependency and get this in order.

Just to make sure we're on the same page:

I would add the conditional only where it's needed aka where you used urlJoin in the sw.ts and in the registerServiceWorker.ts.

Awesome! :) > I'll add the conditional and remove the dependency and get this in order. Just to make sure we're on the same page: I would add the conditional only where it's needed aka where you used `urlJoin` in the `sw.ts` and in the `registerServiceWorker.ts`.
eljef force-pushed base_path_fix from 182b5741af to 274a0465e0 2023-01-25 18:13:54 +00:00 Compare
Author
Contributor

OK. Updated as requested. Conditionals in registerServiceWorker.ts and sw.ts. No extra deps. Still honors environment files, etc.

OK. Updated as requested. Conditionals in `registerServiceWorker.ts` and `sw.ts`. No extra deps. Still honors environment files, etc.
eljef changed title from Use Build Time Base path to fix: Use Build Time Base Path 2023-01-25 18:17:04 +00:00
eljef force-pushed base_path_fix from 274a0465e0 to 8b212a3543 2023-01-27 05:56:50 +00:00 Compare
eljef force-pushed base_path_fix from 8b212a3543 to 93ed6b9bd3 2023-01-28 23:40:37 +00:00 Compare
eljef force-pushed base_path_fix from 93ed6b9bd3 to b8859d1559 2023-01-29 23:22:46 +00:00 Compare
eljef force-pushed base_path_fix from b8859d1559 to 44c3a0fb4c 2023-02-02 06:33:43 +00:00 Compare
Author
Contributor

@dpschen Anything else needed here?

@dpschen Anything else needed here?
Author
Contributor

Associated docs updated in vikunja/api#1363

Associated docs updated in https://kolaente.dev/vikunja/api/pulls/1363
konrad force-pushed base_path_fix from 44c3a0fb4c to f6bd88b0de 2023-02-03 08:19:46 +00:00 Compare
konrad force-pushed base_path_fix from f6bd88b0de to af55992057 2023-02-03 08:23:08 +00:00 Compare
Owner

Incorporated a few changes from @dpschen and rebased, should be good to go now.

Incorporated a few changes from @dpschen and rebased, should be good to go now.
konrad approved these changes 2023-02-03 08:24:21 +00:00
konrad left a comment
Owner

Thanks!

Thanks!
konrad scheduled this pull request to auto merge when all checks succeed 2023-02-03 08:24:38 +00:00
konrad merged commit 6572f75e5d into main 2023-02-03 08:57:29 +00:00
Member

Thanks @eljef, sorry again that it took so long!

Thanks @eljef, sorry again that it took so long!
This repo is archived. You cannot comment on pull requests.
No description provided.