Migrate to vite

Signed-off-by: Thomas Citharel <tcit@tcit.fr>
This commit is contained in:
Thomas Citharel 2021-10-22 21:43:01 +02:00
parent 9a079e63a6
commit e41039922c
No known key found for this signature in database
GPG Key ID: A061B9DDE0CA0773
33 changed files with 1065 additions and 7221 deletions

View File

@ -116,6 +116,15 @@ config :mobilizon, Mobilizon.Web.Email.Mailer,
# can be `true`
no_mx_lookups: false
config :esbuild,
version: "0.12.18",
default: [
args:
~w(src/main.js --bundle --target=es2016 --outdir=../priv/static/assets --external:/fonts/* --external:/images/*),
cd: Path.expand("../js", __DIR__),
env: %{"NODE_PATH" => Path.expand("../deps", __DIR__)}
]
# Configures Elixir's Logger
config :logger, :console,
backends: [:console],

View File

@ -15,13 +15,7 @@ config :mobilizon, Mobilizon.Web.Endpoint,
check_origin: false,
watchers: [
node: [
"node_modules/webpack/bin/webpack.js",
"--mode",
"development",
"--watch",
"--watch-options-stdin",
"--config",
"node_modules/@vue/cli-service/webpack.config.js",
"node_modules/.bin/vite",
cd: Path.expand("../js", __DIR__)
]
]

View File

@ -3,13 +3,9 @@
"version": "1.3.2",
"private": true,
"scripts": {
"serve": "vue-cli-service serve",
"build": "yarn run build:assets && yarn run build:pictures",
"test:unit": "LANG=en_US.UTF-8 LANGUAGE=en_US:en LC_ALL=en_US.UTF-8 TZ=UTC vue-cli-service test:unit",
"test:e2e": "vue-cli-service test:e2e",
"lint": "vue-cli-service lint",
"build:assets": "vue-cli-service build",
"build:pictures": "bash ./scripts/build/pictures.sh"
"dev": "tsc --noEmit && vite",
"build": "vite build",
"serve": "vite preview"
},
"dependencies": {
"@absinthe/socket": "^0.2.1",
@ -35,8 +31,8 @@
"apollo-absinthe-upload-link": "^1.5.0",
"blurhash": "^1.1.3",
"buefy": "^0.9.0",
"bulma": "^0.9.3",
"bulma-divider": "^0.2.0",
"core-js": "^3.6.4",
"date-fns": "^2.16.0",
"date-fns-tz": "^1.1.6",
"graphql": "^15.0.0",
@ -53,59 +49,40 @@
"tippy.js": "^6.2.3",
"unfetch": "^4.2.0",
"v-tooltip": "^2.1.3",
"vue": "^2.6.11",
"vue": "^2.6.14",
"vue-class-component": "^7.2.3",
"vue-i18n": "^8.14.0",
"vue-meta": "^2.3.1",
"vue-property-decorator": "^9.0.0",
"vue-router": "^3.1.6",
"vue-router": "^3.5.2",
"vue-scrollto": "^2.17.1",
"vue2-leaflet": "^2.0.3",
"vuedraggable": "^2.24.3"
},
"devDependencies": {
"@rollup/plugin-dynamic-import-vars": "^1.4.1",
"@types/jest": "^27.0.2",
"@types/leaflet": "^1.5.2",
"@types/leaflet.locatecontrol": "^0.60.7",
"@types/lodash": "^4.14.141",
"@types/ngeohash": "^0.6.2",
"@types/node": "^16.11.3",
"@types/phoenix": "^1.5.2",
"@types/prosemirror-inputrules": "^1.0.2",
"@types/prosemirror-model": "^1.7.2",
"@types/prosemirror-state": "^1.2.4",
"@types/prosemirror-view": "^1.11.4",
"@typescript-eslint/eslint-plugin": "^4.18.0",
"@typescript-eslint/parser": "^4.18.0",
"@vue/cli-plugin-babel": "~5.0.0-beta.6",
"@vue/cli-plugin-e2e-cypress": "~5.0.0-beta.6",
"@vue/cli-plugin-eslint": "~5.0.0-beta.6",
"@vue/cli-plugin-pwa": "~5.0.0-beta.6",
"@vue/cli-plugin-router": "~5.0.0-beta.6",
"@vue/cli-plugin-typescript": "~5.0.0-beta.6",
"@vue/cli-plugin-unit-jest": "~5.0.0-beta.6",
"@vue/cli-service": "~5.0.0-beta.6",
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^7.0.0",
"@vue/test-utils": "^1.1.0",
"@vue/test-utils": "^1.2.2",
"@vue/vue2-jest": "^27.0.0-alpha.2",
"cypress": "^8.3.0",
"eslint": "^7.20.0",
"eslint-plugin-cypress": "^2.10.3",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-vue": "^7.6.0",
"flush-promises": "^1.0.2",
"jest": "^27.1.0",
"jest-junit": "^13.0.0",
"mock-apollo-client": "^1.1.0",
"prettier": "^2.2.1",
"prettier-eslint": "^13.0.0",
"sass": "^1.34.1",
"sass-loader": "^12.0.0",
"ts-jest": "27",
"typescript": "~4.4.3",
"vue-i18n-extract": "^2.0.4",
"vue-template-compiler": "^2.6.11",
"webpack-cli": "^4.7.0"
"sass": "^1.43.3",
"typescript": "^4.3.2",
"vite": "^2.6.4",
"vite-plugin-html": "^2.1.1",
"vite-plugin-pwa": "^0.11.3",
"vite-plugin-vue2": "^1.9.0",
"vue-template-compiler": "^2.6.14"
}
}

View File

@ -1,22 +1,25 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="<%= BASE_URL %>favicon.ico" />
<meta name="server-injected-data" />
</head>
<body>
<noscript>
<strong
>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
<head>
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width,initial-scale=1.0" />
<link rel="icon" href="/favicon.ico" />
<meta name="server-injected-data" />
<script type="module" src="http://localhost:3000/@vite/client"></script>
<script type="module" src="http://localhost:3000/src/main.ts"></script>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work
properly without JavaScript enabled. Please enable it to
continue.</strong
>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -244,8 +244,27 @@ export default class App extends Vue {
@import "variables";
/* Icons */
$mdi-font-path: "~@mdi/font/fonts";
@import "~@mdi/font/scss/materialdesignicons";
@import "node_modules/@mdi/font/scss/variables";
@import "node_modules/@mdi/font/scss/functions";
@font-face {
font-family: '#{$mdi-font-name}';
src: url('../node_modules/@mdi/font/materialdesignicons-webfont.eot');
src: url('../node_modules/@mdi/font/materialdesignicons-webfont.eot?#iefix') format('embedded-opentype'),
url('../node_modules/@mdi/font/materialdesignicons-webfont.woff2') format('woff2'),
url('../node_modules/@mdi/font/materialdesignicons-webfont.woff') format('woff'),
url('../node_modules/@mdi/font/materialdesignicons-webfont.ttf') format('truetype');
font-weight: normal;
font-style: normal;
}
@import "node_modules/@mdi/font/scss/core";
@import "node_modules/@mdi/font/scss/icons";
@import "node_modules/@mdi/font/scss/extras";
@import "node_modules/@mdi/font/scss/animated";
@import "common";

View File

@ -1,8 +1,8 @@
@import "variables.scss";
@import "~bulma";
@import "~bulma-divider";
@import "~buefy/src/scss/buefy";
@import "node_modules/bulma/bulma.sass";
@import "node_modules/bulma-divider/dist/css/bulma-divider.sass";
@import "node_modules/buefy/src/scss/buefy";
@import "styles/vue-announcer.scss";
@import "styles/vue-skip-to.scss";

View File

@ -1,16 +1,3 @@
<docs>
### Example
```vue
<DateCalendarIcon date="2019-10-05T18:41:11.720Z" />
```
```vue
<DateCalendarIcon
:date="new Date()"
/>
```
</docs>
<template>
<time
class="datetime-container"

View File

@ -1,22 +1,3 @@
<docs>
#### Give a translated and localized text that give the starting and ending datetime for an event.
##### Start date with no ending
```vue
<EventFullDate beginsOn="2015-10-06T18:41:11.720Z" />
```
##### Start date with an ending the same day
```vue
<EventFullDate beginsOn="2015-10-06T18:41:11.720Z" endsOn="2015-10-06T20:41:11.720Z" />
```
##### Start date with an ending on a different day
```vue
<EventFullDate beginsOn="2015-10-06T18:41:11.720Z" endsOn="2032-10-06T18:41:11.720Z" />
```
</docs>
<template>
<p v-if="!endsOn">
<span>{{

View File

@ -1,28 +1,3 @@
import {EventJoinOptions} from "@/types/event.model";
<docs>
A button to set your participation
##### If the participant has been confirmed
```vue
<ParticipationButton :participation="{ role: 'PARTICIPANT' }" :currentActor="{ preferredUsername: 'test', avatar: { url: 'https://huit.re/EPX7vs1j' } }" />
```
##### If the participant has not being approved yet
```vue
<ParticipationButton :participation="{ role: 'NOT_APPROVED' }" :currentActor="{ preferredUsername: 'test', avatar: { url: 'https://huit.re/EPX7vs1j' } }" />
```
##### If the participant has been rejected
```vue
<ParticipationButton :participation="{ role: 'REJECTED' }" :currentActor="{ preferredUsername: 'test', avatar: { url: 'https://huit.re/EPX7vs1j' } }" />
```
##### If the participant doesn't exist yet
```vue
<ParticipationButton :participation="null" :currentActor="{ preferredUsername: 'test', avatar: { url: 'https://huit.re/EPX7vs1j' } }" />
```
</docs>
<template>
<div class="participation-button">
<b-dropdown

View File

@ -116,7 +116,7 @@ export default class Footer extends Vue {
}
</script>
<style lang="scss" scoped>
@import "~bulma/sass/utilities/mixins.sass";
@import "node_modules/bulma/sass/utilities/mixins.sass";
footer.footer {
color: $secondary;
display: flex;

View File

@ -59,6 +59,6 @@ export default class Vue2LeafletLocateControl extends Vue {
}
</script>
<style>
@import "~leaflet.locatecontrol/dist/L.Control.Locate.css";
<style lang="scss">
@import "node_modules/leaflet.locatecontrol/src/L.Control.Locate.scss";
</style>

View File

@ -1,8 +1,3 @@
<docs>
```vue
<report-card :report="{ reported: { name: 'Some bad guy', preferredUsername: 'kevin' }, reporter: { preferredUsername: 'somePerson34' }, reportContent: 'This is not good'}" />
```
</docs>
<template>
<div class="card" v-if="report">
<div class="card-content">

5
js/src/env.d.ts vendored Normal file
View File

@ -0,0 +1,5 @@
interface ImportMetaEnv extends Readonly<Record<string, string>> {}
interface ImportMeta {
readonly env: ImportMetaEnv;
}

View File

@ -1,3 +1,7 @@
if (import.meta.env.MODE !== "development") {
// @ts-ignore
import("vite/modulepreload-polyfill");
}
import Vue from "vue";
import Buefy from "buefy";
import Component from "vue-class-component";

View File

@ -11,7 +11,9 @@ export function DateFnsPlugin(
vue: typeof VueInstance,
{ locale }: { locale: string }
): void {
import(`date-fns/locale/${locale}/index.js`).then((localeEntity) => {
VueInstance.prototype.$dateFnsLocale = localeEntity;
});
import(`../../node_modules/date-fns/locale/${locale}/index.js`).then(
(localeEntity) => {
VueInstance.prototype.$dateFnsLocale = localeEntity;
}
);
}

View File

@ -3,7 +3,7 @@
import { register } from "register-service-worker";
if ("serviceWorker" in navigator && isProduction()) {
register(`${process.env.BASE_URL}service-worker.js`, {
register(`${import.meta.env.BASE_URL}sw.js`, {
ready() {
console.debug(
"App is being served from cache by a service worker.\n" +
@ -36,5 +36,5 @@ if ("serviceWorker" in navigator && isProduction()) {
}
function isProduction(): boolean {
return process.env.NODE_ENV === "production";
return import.meta.env.MODE === "production";
}

View File

@ -108,10 +108,9 @@ export async function loadLanguageAsync(lang: string): Promise<string> {
}
// If the language hasn't been loaded yet
console.debug("loading language", lang);
const file = vueI18NfileForLanguage(lang);
const newMessages = await import(
/* webpackChunkName: "lang-[request]" */ `@/i18n/${vueI18NfileForLanguage(
lang
)}.json`
/* webpackChunkName: "lang-[request]" */ `../i18n/${file}.json`
);
i18n.setLocaleMessage(lang, newMessages.default);
loadedLanguages.push(lang);

View File

@ -1,6 +1,6 @@
@import "~bulma/sass/utilities/functions.sass";
@import "~bulma/sass/utilities/initial-variables.sass";
@import "~bulma/sass/utilities/derived-variables.sass";
@import "node_modules/bulma/sass/utilities/functions.sass";
@import "node_modules/bulma/sass/utilities/initial-variables.sass";
@import "node_modules/bulma/sass/utilities/derived-variables.sass";
$bleuvert: #1e7d97;
$jaune: #ffd599;

View File

@ -892,7 +892,7 @@ export default class Group extends mixins(GroupMixin) {
}
</script>
<style lang="scss" scoped>
@import "~bulma/sass/utilities/mixins.sass";
@import "node_modules/bulma/sass/utilities/mixins.sass";
div.container {
margin-bottom: 3rem;

View File

@ -633,7 +633,7 @@ export default class Home extends Vue {
</script>
<style lang="scss" scoped>
@import "~bulma/sass/utilities/mixins.sass";
@import "node_modules/bulma/sass/utilities/mixins.sass";
main > div > .container {
background: $white;

View File

@ -60,13 +60,9 @@
</template>
<script lang="ts">
import { Component, Vue } from "vue-property-decorator";
import BField from "buefy/src/components/field/Field.vue";
import RouteName from "../router/name";
@Component({
components: {
BField,
},
metaInfo() {
return {
title: this.$t("Page not found") as string,

View File

@ -37,7 +37,7 @@ let pendingRequests: any[] = [];
// Endpoints
const httpServer = GRAPHQL_API_ENDPOINT || "http://localhost:4000";
const httpEndpoint = GRAPHQL_API_FULL_PATH || `${httpServer}/api`;
const webSocketPrefix = process.env.NODE_ENV === "production" ? "wss" : "ws";
const webSocketPrefix = import.meta.env.MODE === "production" ? "wss" : "ws";
const wsEndpoint = `${webSocketPrefix}${httpServer.substring(
httpServer.indexOf(":")
)}/graphql_socket`;

View File

@ -1,15 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-var-requires
const vueJest = require("vue-jest/lib/template-compiler");
module.exports = {
process(content: any) {
const { render } = vueJest({
content,
attrs: {
functional: false,
},
});
return `module.exports = { render: ${render} }`;
},
};

View File

@ -13,7 +13,7 @@
"resolveJsonModule": true,
"sourceMap": true,
"baseUrl": ".",
"types": ["webpack-env", "jest"],
"types": ["vite/client", "jest"],
"typeRoots": ["./@types", "./node_modules/@types"],
"paths": {
"@/*": ["src/*"]

39
js/vite.config.js Normal file
View File

@ -0,0 +1,39 @@
import { defineConfig } from "vite";
import { createVuePlugin } from "vite-plugin-vue2";
import { VitePWA } from "vite-plugin-pwa";
import dynamicImportVars from "@rollup/plugin-dynamic-import-vars";
const path = require("path");
export default defineConfig({
plugins: [createVuePlugin(/* options */), VitePWA({})],
build: {
// generate manifest.json in outDir
manifest: true,
minify: true,
rollupOptions: {
// overwrite default .html entry
input: "src/main.ts",
plugins: [
dynamicImportVars({
// options
}),
],
},
outDir: path.resolve(__dirname, "../priv/static"),
},
resolve: {
alias: {
"@": path.resolve(__dirname, "/src"),
},
},
css: {
preprocessorOptions: {
scss: {
additionalData: `@import "@/variables.scss";`,
sassOptions: {
quietDeps: true,
},
},
},
},
});

View File

@ -1,31 +0,0 @@
const path = require("path");
module.exports = {
outputDir: path.resolve(__dirname, "../priv/static"),
chainWebpack: (config) => {
// remove the prefetch plugin
config.plugins.delete("prefetch");
},
pwa: {
themeColor: "#ffd599", //not required for service worker, but place theme color here if manifest.json doesn't change the color
workboxPluginMode: "InjectManifest",
workboxOptions: {
// swSrc is required in InjectManifest mode.
swSrc: "./src/service-worker.ts",
// ...other Workbox options...
},
manifestOptions: {
orientation: "portrait-primary",
},
},
css: {
loaderOptions: {
scss: {
additionalData: `@import "@/variables.scss";`,
sassOptions: {
quietDeps: true,
},
},
},
},
};

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,12 @@ defmodule Mobilizon.Service.Metadata.Instance do
<script type="application/ld+json">#{Jason.encode!(json_ld)}</script>
"""
path = Path.join(Application.app_dir(:mobilizon, "priv/static"), "manifest.json")
manifest = path |> File.read!() |> Jason.decode!()
[
Tag.tag(:link, rel: "stylesheet", href: "/" <> hd(manifest["src/main.ts"]["css"])),
Tag.tag(:script, type: "module", src: "/" <> manifest["src/main.ts"]["file"]),
Tag.content_tag(:title, title),
Tag.tag(:meta, name: "description", content: description),
Tag.tag(:meta, property: "og:title", content: title),

View File

@ -49,7 +49,7 @@ defmodule Mobilizon.Web.Endpoint do
at: "/",
from: {:mobilizon, "priv/static"},
gzip: false,
only: ~w(index.html manifest.json service-worker.js css fonts img js favicon.ico robots.txt),
only: ~w(index.html manifest.json sw.js registerSW.js assets favicon.ico robots.txt),
only_matching: ["precache-manifest"]
)

71
lib/web/telemetry.ex Normal file
View File

@ -0,0 +1,71 @@
defmodule Mobilizon.Web.Telemetry do
use Supervisor
import Telemetry.Metrics
def start_link(arg) do
Supervisor.start_link(__MODULE__, arg, name: __MODULE__)
end
@impl true
def init(_arg) do
children = [
# Telemetry poller will execute the given period measurements
# every 10_000ms. Learn more here: https://hexdocs.pm/telemetry_metrics
{:telemetry_poller, measurements: periodic_measurements(), period: 10_000}
# Add reporters as children of your supervision tree.
# {Telemetry.Metrics.ConsoleReporter, metrics: metrics()}
]
Supervisor.init(children, strategy: :one_for_one)
end
def metrics do
[
# Phoenix Metrics
summary("phoenix.endpoint.stop.duration",
unit: {:native, :millisecond}
),
summary("phoenix.router_dispatch.stop.duration",
tags: [:route],
unit: {:native, :millisecond}
),
# Database Metrics
summary("mobilizon.repo.query.total_time",
unit: {:native, :millisecond},
description: "The sum of the other measurements"
),
summary("mobilizon.repo.query.decode_time",
unit: {:native, :millisecond},
description: "The time spent decoding the data received from the database"
),
summary("mobilizon.repo.query.query_time",
unit: {:native, :millisecond},
description: "The time spent executing the query"
),
summary("mobilizon.repo.query.queue_time",
unit: {:native, :millisecond},
description: "The time spent waiting for a database connection"
),
summary("mobilizon.repo.query.idle_time",
unit: {:native, :millisecond},
description:
"The time the connection spent waiting before being checked out for the query"
),
# VM Metrics
summary("vm.memory.total", unit: {:byte, :kilobyte}),
summary("vm.total_run_queue_lengths.total"),
summary("vm.total_run_queue_lengths.cpu"),
summary("vm.total_run_queue_lengths.io")
]
end
defp periodic_measurements do
[
# A module, function and arguments to be invoked periodically.
# This function must call :telemetry.execute/3 and a metric must be added above.
# {Mobilizon.Web, :count_users, []}
]
end
end

View File

@ -208,6 +208,9 @@ defmodule Mobilizon.Mixfile do
{:export, "~> 0.1.0"},
{:tz_world, "~> 1.0"},
{:tzdata, "~> 1.1"},
{:phoenix_live_dashboard, "~> 0.5"},
{:telemetry_metrics, "~> 0.6"},
{:telemetry_poller, "~> 1.0"},
# Dev and test dependencies
{:phoenix_live_reload, "~> 1.2", only: [:dev, :e2e]},
{:ex_machina, "~> 2.3", only: [:dev, :test]},
@ -223,7 +226,8 @@ defmodule Mobilizon.Mixfile do
{:mox, "~> 1.0", only: :test},
{:junit_formatter, "~> 3.1", only: [:test]},
{:sobelow, "~> 0.8", only: [:dev, :test]},
{:doctor, "~> 0.18.0", only: :dev}
{:doctor, "~> 0.18.0", only: :dev},
{:esbuild, "~> 0.2", runtime: Mix.env() == :dev}
] ++ oauth_deps()
end
@ -255,7 +259,8 @@ defmodule Mobilizon.Mixfile do
"ecto.migrate",
"cmd cd js && yarn install && cd ../",
"phx.server"
]
],
"assets.deploy": ["esbuild default --minify", "phx.digest"]
]
end

View File

@ -9,6 +9,7 @@
"bamboo_smtp": {:hex, :bamboo_smtp, "4.1.0", "ba547be4146ae592f63af05c6c7b7b5195b2b6ca57eeea9d80070b38eacd528b", [:mix], [{:bamboo, "~> 2.2.0", [hex: :bamboo, repo: "hexpm", optional: false]}, {:gen_smtp, "~> 1.1.1", [hex: :gen_smtp, repo: "hexpm", optional: false]}], "hexpm", "cb1a2856ab0507d10df609428314aa5e18231e8b1801a5bc6e42f319eeb50ad9"},
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
"cachex": {:hex, :cachex, "3.4.0", "868b2959ea4aeb328c6b60ff66c8d5123c083466ad3c33d3d8b5f142e13101fb", [:mix], [{:eternal, "~> 1.2", [hex: :eternal, repo: "hexpm", optional: false]}, {:jumper, "~> 1.0", [hex: :jumper, repo: "hexpm", optional: false]}, {:sleeplocks, "~> 1.1", [hex: :sleeplocks, repo: "hexpm", optional: false]}, {:unsafe, "~> 1.0", [hex: :unsafe, repo: "hexpm", optional: false]}], "hexpm", "370123b1ab4fba4d2965fb18f87fd758325709787c8c5fce35b3fe80645ccbe5"},
"castore": {:hex, :castore, "0.1.12", "b5755d7668668a74c0e3c4c68df91da927e063a5cade17d693eff04e6ab64805", [:mix], [], "hexpm", "981c79528f88ec4ffd627214ad4cdd25052dc56c002996c603011ae37ec1b4b0"},
"certifi": {:hex, :certifi, "2.8.0", "d4fb0a6bb20b7c9c3643e22507e42f356ac090a1dcea9ab99e27e0376d695eba", [:rebar3], [], "hexpm", "6ac7efc1c6f8600b08d625292d4bbf584e14847ce1b6b5c44d983d273e1097ea"},
"cldr_utils": {:hex, :cldr_utils, "2.16.0", "5abd1835151e264f6f9a285ab8c7419954a45eec5ca5a356dea592faa23e80b9", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:decimal, "~> 1.9 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}], "hexpm", "3ef5dc0fdfe566a5a4b8bda726cf760ebada69c0600affc4cb02b5e8ae7f7b47"},
"combine": {:hex, :combine, "0.10.0", "eff8224eeb56498a2af13011d142c5e7997a80c8f5b97c499f84c841032e429f", [:mix], [], "hexpm", "1b1dbc1790073076580d0d1d64e42eae2366583e7aecd455d1215b0d16f2451b"},
@ -36,6 +37,7 @@
"elixir_make": {:hex, :elixir_make, "0.6.3", "bc07d53221216838d79e03a8019d0839786703129599e9619f4ab74c8c096eac", [:mix], [], "hexpm", "f5cbd651c5678bcaabdbb7857658ee106b12509cd976c2c2fca99688e1daf716"},
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
"erlport": {:hex, :erlport, "0.10.1", "c96ffa51bbcab0298232fcdfe8c3e110f1598011de71ae6b9082b80c9e2e476a", [:rebar3], [], "hexpm", "34931e8cb62a131d1bc8a2bd04d4007c73c03e4f10e22ee4a218e7172227a918"},
"esbuild": {:hex, :esbuild, "0.3.3", "1af589106b33bf125f6380459a55847d2bcc9d60bc4605170de8548fb18060b3", [:mix], [{:castore, ">= 0.0.0", [hex: :castore, repo: "hexpm", optional: false]}], "hexpm", "6f860ca9298373a55c58db24f6d5c62c5f7ca1e9d2b8e1602e5f7abc5d6b07bf"},
"eternal": {:hex, :eternal, "1.2.2", "d1641c86368de99375b98d183042dd6c2b234262b8d08dfd72b9eeaafc2a1abd", [:mix], [], "hexpm", "2c9fe32b9c3726703ba5e1d43a1d255a4f3f2d8f8f9bc19f094c7cb1a7a9e782"},
"ex_cldr": {:hex, :ex_cldr, "2.23.2", "76c51b722cefdcd1a13eb5e7c7f4da5b9acfd64ff054424a977ff6e2d6a78981", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:cldr_utils, "~> 2.15", [hex: :cldr_utils, repo: "hexpm", optional: false]}, {:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:gettext, "~> 0.13", [hex: :gettext, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "d9ce03c8d3fdc7ab751bdb2be742b6972f94adc856d51dfe5bb06a51ac96b8f4"},
"ex_cldr_calendars": {:hex, :ex_cldr_calendars, "1.16.0", "7f076c85b63b03cf2c5719b75a9c1ca1b177d6d164a94a1eaf4bfb1a5dca152a", [:mix], [{:calendar_interval, "~> 0.2", [hex: :calendar_interval, repo: "hexpm", optional: true]}, {:earmark, "~> 1.0", [hex: :earmark, repo: "hexpm", optional: false]}, {:ex_cldr, "~> 2.23", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:ex_cldr_units, "~> 3.7", [hex: :ex_cldr_units, repo: "hexpm", optional: true]}, {:ex_doc, "~> 0.21", [hex: :ex_doc, repo: "hexpm", optional: true]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "483d91a0fb4909efe211ae59a3620a28bf1a72d64dbf922ae940115e64f6138a"},
@ -108,6 +110,7 @@
"phoenix": {:hex, :phoenix, "1.6.2", "6cbd5c8ed7a797f25a919a37fafbc2fb1634c9cdb12a4448d7a5d0b26926f005", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:phoenix_view, "~> 1.0", [hex: :phoenix_view, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7bbee475acae0c3abc229b7f189e210ea788e63bd168e585f60c299a4b2f9133"},
"phoenix_ecto": {:hex, :phoenix_ecto, "4.4.0", "0672ed4e4808b3fbed494dded89958e22fb882de47a97634c0b13e7b0b5f7720", [:mix], [{:ecto, "~> 3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14.2 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.9", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "09864e558ed31ee00bd48fcc1d4fc58ae9678c9e81649075431e69dbabb43cc1"},
"phoenix_html": {:hex, :phoenix_html, "3.0.4", "232d41884fe6a9c42d09f48397c175cd6f0d443aaa34c7424da47604201df2e1", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: true]}], "hexpm", "ce17fd3cf815b2ed874114073e743507704b1f5288bb03c304a77458485efc8b"},
"phoenix_live_dashboard": {:hex, :phoenix_live_dashboard, "0.6.0", "6779c97a1dfe4a1b5bfc48937de094d3c0f0ad71ec9e51934306e3315e9b8f09", [:mix], [{:ecto, "~> 3.6.2 or ~> 3.7", [hex: :ecto, repo: "hexpm", optional: true]}, {:ecto_mysql_extras, "~> 0.3", [hex: :ecto_mysql_extras, repo: "hexpm", optional: true]}, {:ecto_psql_extras, "~> 0.7", [hex: :ecto_psql_extras, repo: "hexpm", optional: true]}, {:phoenix_live_view, "~> 0.17.1", [hex: :phoenix_live_view, repo: "hexpm", optional: false]}, {:telemetry_metrics, "~> 0.6.0", [hex: :telemetry_metrics, repo: "hexpm", optional: false]}], "hexpm", "a80036cc73c77280e9c14e241d4593104b836b12aca621b244faae61be67ad37"},
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.3.3", "3a53772a6118d5679bf50fc1670505a290e32a1d195df9e069d8c53ab040c054", [:mix], [{:file_system, "~> 0.2.1 or ~> 0.3", [hex: :file_system, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}], "hexpm", "766796676e5f558dbae5d1bdb066849673e956005e3730dfd5affd7a6da4abac"},
"phoenix_live_view": {:hex, :phoenix_live_view, "0.17.1", "20b6e32e26d36ca18fadff47aa370d18a6000e2065ceb72908b43f4178f1afad", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.9 or ~> 1.6.0", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "70620625828da47516d772a260cdb71f56e30bdfc20750746139ca6e00847286"},
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
@ -129,6 +132,8 @@
"struct_access": {:hex, :struct_access, "1.1.2", "a42e6ceedd9b9ea090ee94a6da089d56e16f374dbbc010c3eebdf8be17df286f", [:mix], [], "hexpm", "e4c411dcc0226081b95709909551fc92b8feb1a3476108348ea7e3f6c12e586a"},
"sweet_xml": {:hex, :sweet_xml, "0.7.1", "a2cac8e2101237e617dfa9d427d44b8aff38ba6294f313ffb4667524d6b71b98", [:mix], [], "hexpm", "8bc7b7b584a6a87113071d0d2fd39fe2251cf2224ecaeed7093bdac1b9c1555f"},
"telemetry": {:hex, :telemetry, "1.0.0", "0f453a102cdf13d506b7c0ab158324c337c41f1cc7548f0bc0e130bbf0ae9452", [:rebar3], [], "hexpm", "73bc09fa59b4a0284efb4624335583c528e07ec9ae76aca96ea0673850aec57a"},
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.1", "315d9163a1d4660aedc3fee73f33f1d355dcc76c5c3ab3d59e76e3edf80eef1f", [:mix], [{:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7be9e0871c41732c233be71e4be11b96e56177bf15dde64a8ac9ce72ac9834c6"},
"telemetry_poller": {:hex, :telemetry_poller, "1.0.0", "db91bb424e07f2bb6e73926fcafbfcbcb295f0193e0a00e825e589a0a47e8453", [:rebar3], [{:telemetry, "~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "b3a24eafd66c3f42da30fc3ca7dda1e9d546c12250a2d60d7b81d264fbec4f6e"},
"tesla": {:hex, :tesla, "1.4.3", "f5a494e08fb1abe4fd9c28abb17f3d9b62b8f6fc492860baa91efb1aab61c8a0", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:exjsx, ">= 3.0.0", [hex: :exjsx, repo: "hexpm", optional: true]}, {:finch, "~> 0.3", [hex: :finch, repo: "hexpm", optional: true]}, {:fuse, "~> 2.4", [hex: :fuse, repo: "hexpm", optional: true]}, {:gun, "~> 1.3", [hex: :gun, repo: "hexpm", optional: true]}, {:hackney, "~> 1.6", [hex: :hackney, repo: "hexpm", optional: true]}, {:ibrowse, "4.4.0", [hex: :ibrowse, repo: "hexpm", optional: true]}, {:jason, ">= 1.0.0", [hex: :jason, repo: "hexpm", optional: true]}, {:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:mint, "~> 1.0", [hex: :mint, repo: "hexpm", optional: true]}, {:poison, ">= 1.0.0", [hex: :poison, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "e0755bb664bf4d664af72931f320c97adbf89da4586670f4864bf259b5750386"},
"timex": {:hex, :timex, "3.7.6", "502d2347ec550e77fdf419bc12d15bdccd31266bb7d925b30bf478268098282f", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 1.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "a296327f79cb1ec795b896698c56e662ed7210cc9eb31f0ab365eb3a62e2c589"},
"tz_world": {:hex, :tz_world, "1.0.0", "53366d7ec1d3fb11e1a34ce7c74d21c354195521b3309cdb9e6cc84b266cae83", [:mix], [{:castore, "~> 0.1", [hex: :castore, repo: "hexpm", optional: true]}, {:certifi, "~> 2.5", [hex: :certifi, repo: "hexpm", optional: true]}, {:geo, "~> 1.0 or ~> 2.0 or ~> 3.3", [hex: :geo, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "9d7aeaa078913b6d486d2a1bf3c1fd380cb16180b93415c7f3fde7cabff478f8"},