chore: Update ex_cldr
This commit is contained in:
commit
1333be352f
61 changed files with 13556 additions and 14815 deletions
3
.dialyzer_ignore.exs
Normal file
3
.dialyzer_ignore.exs
Normal file
|
@ -0,0 +1,3 @@
|
|||
[
|
||||
{"lib/i18n.ex:1:pattern_match_cov The pattern pattern <_@1, _@2, _@3> can never match the type, because it is covered by previous clauses."}
|
||||
]
|
|
@ -2,3 +2,4 @@ cover
|
|||
.elixir_ls
|
||||
*.dump
|
||||
.journal-*
|
||||
.git
|
||||
|
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -44,3 +44,6 @@ config/*.secret.exs
|
|||
|
||||
# Temporary CI build file
|
||||
build.env
|
||||
|
||||
# CI metrics file
|
||||
metrics.txt
|
||||
|
|
|
@ -26,7 +26,7 @@ variables:
|
|||
- name: postgres:12
|
||||
script: script/cibuild
|
||||
|
||||
test:
|
||||
test_1.10.4:
|
||||
<<: *test_template
|
||||
image: "elixir:1.10.4-alpine"
|
||||
|
||||
|
@ -34,15 +34,55 @@ test_1.11.4:
|
|||
<<: *test_template
|
||||
image: "elixir:1.11.4-alpine"
|
||||
|
||||
test_1.12.1:
|
||||
test:
|
||||
<<: *test_template
|
||||
image: "elixir:1.12.1-alpine"
|
||||
script:
|
||||
- script/cibuild covered
|
||||
artifacts:
|
||||
paths:
|
||||
- cover/excoveralls.json
|
||||
|
||||
credo:
|
||||
stage: test
|
||||
image: "elixir:1.12.1-alpine"
|
||||
cache:
|
||||
key: "test_1.12.1"
|
||||
paths:
|
||||
- _build/
|
||||
- deps/
|
||||
script:
|
||||
- mix local.hex --force
|
||||
- mix local.rebar --force
|
||||
- mix deps.get
|
||||
- mix credo --all
|
||||
|
||||
stylelint:
|
||||
stage: test
|
||||
image: "node:16"
|
||||
script:
|
||||
- cd apps/app/assets/
|
||||
- npm install
|
||||
- npx stylelint **/*.css
|
||||
|
||||
prettier:
|
||||
stage: test
|
||||
image: "node:16"
|
||||
script:
|
||||
- cd apps/app/assets/
|
||||
- npm install
|
||||
- npx prettier --check **/*.js
|
||||
|
||||
build_image_for_commit:
|
||||
stage: test
|
||||
image: "docker:20.10"
|
||||
only:
|
||||
- master
|
||||
rules:
|
||||
- if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
|
||||
when: on_success
|
||||
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
|
||||
changes:
|
||||
- Dockerfile
|
||||
when: on_success
|
||||
services:
|
||||
- name: docker:20.10-dind
|
||||
before_script:
|
||||
|
@ -51,6 +91,19 @@ build_image_for_commit:
|
|||
script:
|
||||
- script/ci-docker-build
|
||||
|
||||
report_coverage:
|
||||
stage: deploy_tags
|
||||
needs: ['test']
|
||||
image: "elixir:1.12.1-alpine"
|
||||
script:
|
||||
- mix local.hex --force
|
||||
- script/coverage-json-to-metrics
|
||||
- script/coverage-json-to-cobertura
|
||||
artifacts:
|
||||
reports:
|
||||
metrics: metrics.txt
|
||||
cobertura: cover/cobertura.xml
|
||||
|
||||
# If tests pass, tag the commit and update package versions
|
||||
deploy_to_tags:
|
||||
stage: deploy_tags
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
erlang 23.0.2
|
||||
elixir 1.10.3-otp-23
|
||||
elixir 1.12.1
|
||||
nodejs 14.5.0
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM elixir:1.10.4-alpine AS elixir-builder
|
||||
FROM elixir:1.12.2-alpine AS elixir-builder
|
||||
|
||||
RUN apk add git
|
||||
|
||||
|
@ -29,7 +29,7 @@ RUN mix deps.get
|
|||
|
||||
# Leave off here so that we can built assets and compile the elixir app in parallel
|
||||
|
||||
FROM node:16.3.0 AS asset-builder
|
||||
FROM node:16.6.0 AS asset-builder
|
||||
|
||||
# Build assets in a node container
|
||||
ADD ./apps/app/assets/ /root/app/apps/app/assets/
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
defmodule Legendary.Admin.Routes do
|
||||
@moduledoc """
|
||||
Routes from the admin app. Use like:
|
||||
|
||||
use Legendary.Admin.Routes
|
||||
"""
|
||||
defmacro __using__(_opts \\ []) do
|
||||
quote do
|
||||
use Kaffy.Routes, scope: "/admin", pipe_through: [:require_admin]
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Legendary.Admin.Telemetry do
|
||||
@moduledoc """
|
||||
Collect metrics from the admin app.
|
||||
"""
|
||||
|
||||
use Supervisor
|
||||
import Telemetry.Metrics
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Legendary.Admin.Kaffy.Config do
|
||||
@moduledoc """
|
||||
Pull in the resource list for the admin from the application config.
|
||||
"""
|
||||
|
||||
def create_resources(_conn) do
|
||||
config = Application.get_env(:admin, Legendary.Admin)
|
||||
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
defmodule Legendary.Admin.Kaffy.EditorExtension do
|
||||
@moduledoc """
|
||||
Bring in additional CSS and JS for the admin interface e.g. the
|
||||
markdown editor library.
|
||||
"""
|
||||
|
||||
def stylesheets(_conn) do
|
||||
[
|
||||
{:safe, ~s(<link rel="stylesheet" href="/css/content-editor.css" />)},
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Legendary.Admin.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
@version "2.10.0"
|
||||
@version "3.1.2"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
{
|
||||
"presets": [
|
||||
"@babel/preset-env"
|
||||
]
|
||||
"presets": ["@babel/preset-env"]
|
||||
}
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
node_modules
|
||||
css/phoenix.css
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
@import "tailwindcss/base";
|
||||
|
||||
@import "tailwindcss/components";
|
||||
|
||||
@import "tailwindcss/utilities";
|
||||
|
||||
@import "@fortawesome/fontawesome-free/css/all.css";
|
||||
|
||||
@import "blog";
|
||||
@import "code";
|
||||
|
||||
|
@ -14,27 +10,28 @@ body {
|
|||
}
|
||||
|
||||
input[type="checkbox"]::after {
|
||||
content: "";
|
||||
color: currentColor;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
display: inline-flex;
|
||||
color: currentColor;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
content: "";
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked::after {
|
||||
content: "✓";
|
||||
}
|
||||
|
||||
.hidden-options-toggle:checked+.hidden {
|
||||
.hidden-options-toggle:checked + .hidden {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.password-revealer {
|
||||
@apply absolute;
|
||||
height: 45px;
|
||||
width: 45px;
|
||||
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
width: 45px;
|
||||
height: 45px;
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@
|
|||
|
||||
.hljs {
|
||||
@apply mt-6 mb-12 border-l-4 border-indigo-900 font-mono;
|
||||
--background-color: theme("colors.indigo.100");
|
||||
--background-color: theme("colors.indigo.100"); /* stylelint-disable-line custom-property-empty-line-before */
|
||||
--attribute-color: theme("colors.orange.700");
|
||||
--section-color: theme("colors.teal.700");
|
||||
--string-color: theme("colors.green.700");
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
// We need to import the CSS so that webpack will load it.
|
||||
// The MiniCssExtractPlugin is used to separate it out into
|
||||
// its own CSS file.
|
||||
import "../css/app.css"
|
||||
import "../css/app.css";
|
||||
|
||||
// webpack automatically bundles all modules in your
|
||||
// entry points. Those entry points can be configured
|
||||
|
@ -12,48 +12,46 @@ import "../css/app.css"
|
|||
// import {Socket} from "phoenix"
|
||||
// import socket from "./socket"
|
||||
//
|
||||
import "phoenix_html"
|
||||
import "alpinejs"
|
||||
import "./live"
|
||||
import { ready } from "./utils"
|
||||
import "phoenix_html";
|
||||
import "alpinejs";
|
||||
import "./live";
|
||||
import { ready } from "./utils";
|
||||
|
||||
function togglePasswordFieldVisibility()
|
||||
{
|
||||
const passwordFields = document.querySelectorAll('[name="user[password]"]')
|
||||
var bloop;
|
||||
|
||||
function togglePasswordFieldVisibility() {
|
||||
const passwordFields = document.querySelectorAll('[name="user[password]"]');
|
||||
passwordFields.forEach((el) => {
|
||||
if (el.type == 'password')
|
||||
{
|
||||
el.type = 'text'
|
||||
if (el.type == "password") {
|
||||
el.type = "text";
|
||||
} else {
|
||||
el.type = "password";
|
||||
}
|
||||
else
|
||||
{
|
||||
el.type = 'password'
|
||||
}
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
const toggleSidebar = (event) => {
|
||||
document.querySelectorAll('.sidebar').forEach((el) => {
|
||||
el.classList.toggle('visible')
|
||||
})
|
||||
}
|
||||
document.querySelectorAll(".sidebar").forEach((el) => {
|
||||
el.classList.toggle("visible");
|
||||
});
|
||||
};
|
||||
|
||||
ready(() => {
|
||||
(document.getElementById('nav-toggle') ||{}).onclick = function(){
|
||||
(document.getElementById("nav-toggle") || {}).onclick = function () {
|
||||
document.getElementById("nav-content").classList.toggle("hidden");
|
||||
}
|
||||
};
|
||||
|
||||
document.querySelectorAll('.js-passwordRevealer').forEach((el) => {
|
||||
el.addEventListener('click', togglePasswordFieldVisibility)
|
||||
})
|
||||
document.querySelectorAll(".js-passwordRevealer").forEach((el) => {
|
||||
el.addEventListener("click", togglePasswordFieldVisibility);
|
||||
});
|
||||
|
||||
document.querySelectorAll('.js-SidebarOpener').forEach((el) => {
|
||||
el.addEventListener('click', toggleSidebar)
|
||||
})
|
||||
document.querySelectorAll(".js-SidebarOpener").forEach((el) => {
|
||||
el.addEventListener("click", toggleSidebar);
|
||||
});
|
||||
|
||||
document.querySelectorAll('.js-flash-closer').forEach((el) => {
|
||||
el.addEventListener('click', () => {
|
||||
el.closest('.js-flash').remove()
|
||||
})
|
||||
})
|
||||
})
|
||||
document.querySelectorAll(".js-flash-closer").forEach((el) => {
|
||||
el.addEventListener("click", () => {
|
||||
el.closest(".js-flash").remove();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,34 +1,33 @@
|
|||
import { ready } from "./utils"
|
||||
import SimpleMDE from "simplemde"
|
||||
import "simplemde/dist/simplemde.min.css"
|
||||
import "../css/content-editor-overrides.css"
|
||||
|
||||
import { ready } from "./utils";
|
||||
import SimpleMDE from "simplemde";
|
||||
import "simplemde/dist/simplemde.min.css";
|
||||
import "../css/content-editor-overrides.css";
|
||||
|
||||
const requestPreview = (plainText, previewContainer) => {
|
||||
let request = new XMLHttpRequest()
|
||||
const postForm = previewContainer.closest('form')
|
||||
let formData = new FormData(postForm)
|
||||
let request = new XMLHttpRequest();
|
||||
const postForm = previewContainer.closest("form");
|
||||
let formData = new FormData(postForm);
|
||||
|
||||
formData.set('post[content]', plainText)
|
||||
formData.set("post[content]", plainText);
|
||||
|
||||
request.addEventListener('load', function(event) {
|
||||
previewContainer.innerHTML = event.target.responseText
|
||||
})
|
||||
request.addEventListener("load", function (event) {
|
||||
previewContainer.innerHTML = event.target.responseText;
|
||||
});
|
||||
|
||||
request.open('POST', '/pages/posts/preview', true)
|
||||
request.open("POST", "/posts/preview", true);
|
||||
|
||||
request.send(formData)
|
||||
}
|
||||
request.send(formData);
|
||||
};
|
||||
|
||||
ready(() => {
|
||||
document.querySelectorAll('[data-simplemde]').forEach(el => {
|
||||
document.querySelectorAll("[data-simplemde]").forEach((el) => {
|
||||
new SimpleMDE({
|
||||
element: el,
|
||||
previewRender: (plainText, previewContainer) => {
|
||||
requestPreview(plainText, previewContainer)
|
||||
requestPreview(plainText, previewContainer);
|
||||
|
||||
return previewContainer.innerHTML
|
||||
return previewContainer.innerHTML;
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,18 +1,25 @@
|
|||
import {Socket} from "phoenix"
|
||||
import LiveSocket from "phoenix_live_view"
|
||||
import topbar from "topbar"
|
||||
import { Socket } from "phoenix";
|
||||
import LiveSocket from "phoenix_live_view";
|
||||
import topbar from "topbar";
|
||||
|
||||
let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
|
||||
let csrfToken = document
|
||||
.querySelector("meta[name='csrf-token']")
|
||||
.getAttribute("content");
|
||||
|
||||
let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}})
|
||||
let liveSocket = new LiveSocket("/live", Socket, {
|
||||
params: { _csrf_token: csrfToken },
|
||||
});
|
||||
|
||||
// Show progress bar on live navigation and form submits
|
||||
topbar.config({barColors: {0: "#3B82F6"}, shadowColor: "rgba(0, 0, 0, .3)"})
|
||||
window.addEventListener("phx:page-loading-start", info => topbar.show())
|
||||
window.addEventListener("phx:page-loading-stop", info => topbar.hide())
|
||||
topbar.config({
|
||||
barColors: { 0: "#3B82F6" },
|
||||
shadowColor: "rgba(0, 0, 0, .3)",
|
||||
});
|
||||
window.addEventListener("phx:page-loading-start", (info) => topbar.show());
|
||||
window.addEventListener("phx:page-loading-stop", (info) => topbar.hide());
|
||||
|
||||
// Connect if there are any LiveViews on the page
|
||||
liveSocket.connect()
|
||||
liveSocket.connect();
|
||||
|
||||
// Expose liveSocket on window for web console debug logs and latency simulation:
|
||||
// >> liveSocket.enableDebug()
|
||||
|
@ -20,4 +27,4 @@ liveSocket.connect()
|
|||
// The latency simulator is enabled for the duration of the browser session.
|
||||
// Call disableLatencySim() to disable:
|
||||
// >> liveSocket.disableLatencySim()
|
||||
window.liveSocket = liveSocket
|
||||
window.liveSocket = liveSocket;
|
||||
|
|
|
@ -6,9 +6,9 @@
|
|||
//
|
||||
// Pass the token on params as below. Or remove it
|
||||
// from the params if you are not using authentication.
|
||||
import {Socket} from "phoenix"
|
||||
import { Socket } from "phoenix";
|
||||
|
||||
let socket = new Socket("/socket", {params: {token: window.userToken}})
|
||||
let socket = new Socket("/socket", { params: { token: window.userToken } });
|
||||
|
||||
// When you connect, you'll often need to authenticate the client.
|
||||
// For example, imagine you have an authentication plug, `MyAuth`,
|
||||
|
@ -52,12 +52,17 @@ let socket = new Socket("/socket", {params: {token: window.userToken}})
|
|||
// end
|
||||
//
|
||||
// Finally, connect to the socket:
|
||||
socket.connect()
|
||||
socket.connect();
|
||||
|
||||
// Now that you are connected, you can join channels with a topic:
|
||||
let channel = socket.channel("topic:subtopic", {})
|
||||
channel.join()
|
||||
.receive("ok", resp => { console.log("Joined successfully", resp) })
|
||||
.receive("error", resp => { console.log("Unable to join", resp) })
|
||||
let channel = socket.channel("topic:subtopic", {});
|
||||
channel
|
||||
.join()
|
||||
.receive("ok", (resp) => {
|
||||
console.log("Joined successfully", resp);
|
||||
})
|
||||
.receive("error", (resp) => {
|
||||
console.log("Unable to join", resp);
|
||||
});
|
||||
|
||||
export default socket
|
||||
export default socket;
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
|
||||
const ready = (fn) => {
|
||||
if (document.readyState != 'loading') {
|
||||
fn()
|
||||
if (document.readyState != "loading") {
|
||||
fn();
|
||||
} else {
|
||||
document.addEventListener('DOMContentLoaded', fn)
|
||||
document.addEventListener("DOMContentLoaded", fn);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export { ready }
|
||||
export { ready };
|
||||
|
|
27342
apps/app/assets/package-lock.json
generated
27342
apps/app/assets/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -5,20 +5,23 @@
|
|||
"scripts": {
|
||||
"deploy": "webpack --mode production",
|
||||
"watch": "webpack --mode development --watch",
|
||||
"profile": "webpack --mode development --plugin webpack/lib/debug/ProfilingPlugin"
|
||||
"profile": "webpack --mode development --plugin webpack/lib/debug/ProfilingPlugin",
|
||||
"preinstall": "npx npm-force-resolutions"
|
||||
},
|
||||
"dependencies": {
|
||||
"@fortawesome/fontawesome-free": "^5.14.0",
|
||||
"alpinejs": "^2.8.1",
|
||||
"autoprefixer": "^9.8.6",
|
||||
"csswring": "^7.0.0",
|
||||
"glob": "^7.1.6",
|
||||
"npm-force-resolutions": "^0.0.10",
|
||||
"phoenix": "file:/../../../deps/phoenix",
|
||||
"phoenix_html": "file:/../../../deps/phoenix_html",
|
||||
"phoenix_live_view": "file:../../../deps/phoenix_live_view",
|
||||
"postcss-clean": "^1.2.2",
|
||||
"postcss-color-function": "^4.1.0",
|
||||
"simplemde": "^1.11.2",
|
||||
"tailwindcss": "^1.7.3",
|
||||
"squeak": "^1.3.0",
|
||||
"tailwindcss": "^2.2.6",
|
||||
"topbar": "^1.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -29,24 +32,28 @@
|
|||
"css-loader": "^3.4.2",
|
||||
"css-minimizer-webpack-plugin": "^3.0.2",
|
||||
"file-loader": "^6.0.0",
|
||||
"image-webpack-loader": "^6.0.0",
|
||||
"image-webpack-loader": "^7.0.1",
|
||||
"less": "^3.11.3",
|
||||
"less-loader": "^6.2.0",
|
||||
"mini-css-extract-plugin": "^1.6.2",
|
||||
"postcss-css-variables": "^0.17.0",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-loader": "^6.1.0",
|
||||
"prettier": "2.3.2",
|
||||
"sass": "^1.35.1",
|
||||
"sass-loader": "^8.0.2",
|
||||
"style-loader": "^1.2.1",
|
||||
"stylelint": "^13.13.1",
|
||||
"stylelint-config-standard": "^22.0.0",
|
||||
"stylelint": "^13.8.0",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"stylelint-order": "^4.1.0",
|
||||
"terser-webpack-plugin": "^2.3.2",
|
||||
"terser-webpack-plugin": "^5.1.4",
|
||||
"webpack": "^5.1.0",
|
||||
"webpack-cli": "^4.7.2"
|
||||
"webpack-cli": "^4.7.2",
|
||||
"yargs-parser": "^20.2.9"
|
||||
},
|
||||
"resolutions": {
|
||||
"graceful-fs": "4.2.3"
|
||||
"graceful-fs": "4.2.3",
|
||||
"meow": "9.0.0",
|
||||
"tempfile": "4.0.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,11 @@
|
|||
module.exports = {
|
||||
plugins: [
|
||||
require('postcss-import')({
|
||||
plugins: [
|
||||
require('stylelint')(),
|
||||
]
|
||||
require("postcss-import")({
|
||||
plugins: [require("stylelint")()],
|
||||
}),
|
||||
require('tailwindcss'),
|
||||
require('autoprefixer'),
|
||||
require('csswring')(),
|
||||
require('postcss-color-function')()
|
||||
require("tailwindcss"),
|
||||
require("autoprefixer"),
|
||||
require("postcss-clean")(),
|
||||
require("postcss-color-function")(),
|
||||
],
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,23 +1,163 @@
|
|||
const yargsParser = require("yargs-parser");
|
||||
const cliArgs = yargsParser(process.argv);
|
||||
|
||||
const mode = process.env.NODE_ENV || cliArgs.mode || "development";
|
||||
|
||||
module.exports = {
|
||||
future: {
|
||||
removeDeprecatedGapUtilities: true,
|
||||
},
|
||||
purge: {
|
||||
enabled: true,
|
||||
layers: ['base', 'components', 'utilities'],
|
||||
enabled: mode == "production",
|
||||
layers: ["base", "components", "utilities"],
|
||||
content: [
|
||||
'../../../**/views/*.ex',
|
||||
'../../../**/*.html.eex',
|
||||
'../../../**/*.html.leex',
|
||||
'../../../**/*.html.heex',
|
||||
'./js/**/*.js'
|
||||
]
|
||||
"../../../**/views/*.ex",
|
||||
"../../../**/*.html.eex",
|
||||
"../../../**/*.html.leex",
|
||||
"../../../**/*.html.heex",
|
||||
"./js/**/*.js",
|
||||
],
|
||||
},
|
||||
theme: {
|
||||
extend: {},
|
||||
colors: {
|
||||
transparent: "transparent",
|
||||
current: "currentColor",
|
||||
|
||||
black: "#000",
|
||||
white: "#fff",
|
||||
|
||||
gray: {
|
||||
100: "#f7fafc",
|
||||
200: "#edf2f7",
|
||||
300: "#e2e8f0",
|
||||
400: "#cbd5e0",
|
||||
500: "#a0aec0",
|
||||
600: "#718096",
|
||||
700: "#4a5568",
|
||||
800: "#2d3748",
|
||||
900: "#1a202c",
|
||||
},
|
||||
red: {
|
||||
100: "#fff5f5",
|
||||
200: "#fed7d7",
|
||||
300: "#feb2b2",
|
||||
400: "#fc8181",
|
||||
500: "#f56565",
|
||||
600: "#e53e3e",
|
||||
700: "#c53030",
|
||||
800: "#9b2c2c",
|
||||
900: "#742a2a",
|
||||
},
|
||||
orange: {
|
||||
100: "#fffaf0",
|
||||
200: "#feebc8",
|
||||
300: "#fbd38d",
|
||||
400: "#f6ad55",
|
||||
500: "#ed8936",
|
||||
600: "#dd6b20",
|
||||
700: "#c05621",
|
||||
800: "#9c4221",
|
||||
900: "#7b341e",
|
||||
},
|
||||
yellow: {
|
||||
100: "#fffff0",
|
||||
200: "#fefcbf",
|
||||
300: "#faf089",
|
||||
400: "#f6e05e",
|
||||
500: "#ecc94b",
|
||||
600: "#d69e2e",
|
||||
700: "#b7791f",
|
||||
800: "#975a16",
|
||||
900: "#744210",
|
||||
},
|
||||
green: {
|
||||
100: "#f0fff4",
|
||||
200: "#c6f6d5",
|
||||
300: "#9ae6b4",
|
||||
400: "#68d391",
|
||||
500: "#48bb78",
|
||||
600: "#38a169",
|
||||
700: "#2f855a",
|
||||
800: "#276749",
|
||||
900: "#22543d",
|
||||
},
|
||||
teal: {
|
||||
100: "#e6fffa",
|
||||
200: "#b2f5ea",
|
||||
300: "#81e6d9",
|
||||
400: "#4fd1c5",
|
||||
500: "#38b2ac",
|
||||
600: "#319795",
|
||||
700: "#2c7a7b",
|
||||
800: "#285e61",
|
||||
900: "#234e52",
|
||||
},
|
||||
blue: {
|
||||
100: "#ebf8ff",
|
||||
200: "#bee3f8",
|
||||
300: "#90cdf4",
|
||||
400: "#63b3ed",
|
||||
500: "#4299e1",
|
||||
600: "#3182ce",
|
||||
700: "#2b6cb0",
|
||||
800: "#2c5282",
|
||||
900: "#2a4365",
|
||||
},
|
||||
indigo: {
|
||||
100: "#ebf4ff",
|
||||
200: "#c3dafe",
|
||||
300: "#a3bffa",
|
||||
400: "#7f9cf5",
|
||||
500: "#667eea",
|
||||
600: "#5a67d8",
|
||||
700: "#4c51bf",
|
||||
800: "#434190",
|
||||
900: "#3c366b",
|
||||
},
|
||||
purple: {
|
||||
100: "#faf5ff",
|
||||
200: "#e9d8fd",
|
||||
300: "#d6bcfa",
|
||||
400: "#b794f4",
|
||||
500: "#9f7aea",
|
||||
600: "#805ad5",
|
||||
700: "#6b46c1",
|
||||
800: "#553c9a",
|
||||
900: "#44337a",
|
||||
},
|
||||
pink: {
|
||||
100: "#fff5f7",
|
||||
200: "#fed7e2",
|
||||
300: "#fbb6ce",
|
||||
400: "#f687b3",
|
||||
500: "#ed64a6",
|
||||
600: "#d53f8c",
|
||||
700: "#b83280",
|
||||
800: "#97266d",
|
||||
900: "#702459",
|
||||
},
|
||||
},
|
||||
fontSize: {
|
||||
xs: "0.75rem",
|
||||
sm: "0.875rem",
|
||||
base: "1rem",
|
||||
lg: "1.125rem",
|
||||
xl: "1.25rem",
|
||||
"2xl": "1.5rem",
|
||||
"3xl": "1.875rem",
|
||||
"4xl": "2.25rem",
|
||||
"5xl": "3rem",
|
||||
"6xl": "4rem",
|
||||
},
|
||||
extend: {
|
||||
boxShadow: {
|
||||
xs: "0 0 0 1px rgba(0, 0, 0, 0.05)",
|
||||
outline: "0 0 0 3px rgba(66, 153, 225, 0.5)",
|
||||
},
|
||||
},
|
||||
},
|
||||
variants: {
|
||||
backgroundColor: ['responsive', 'hover', 'focus', 'checked'],
|
||||
backgroundColor: ["responsive", "hover", "focus", "checked"],
|
||||
extend: {
|
||||
fontWeight: ["hover", "focus"],
|
||||
},
|
||||
},
|
||||
plugins: [],
|
||||
}
|
||||
};
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
const path = require('path');
|
||||
const glob = require('glob');
|
||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||
const TerserPlugin = require('terser-webpack-plugin');
|
||||
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');
|
||||
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
||||
const path = require("path");
|
||||
const glob = require("glob");
|
||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
|
||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
||||
|
||||
const nodeModulesPath = path.resolve(__dirname, 'node_modules')
|
||||
const nodeModulesPath = path.resolve(__dirname, "node_modules");
|
||||
|
||||
module.exports = (env, options) => {
|
||||
const devMode = options.mode !== 'production';
|
||||
const devMode = options.mode !== "production";
|
||||
|
||||
return {
|
||||
optimization: {
|
||||
minimizer: [
|
||||
new TerserPlugin({ cache: true, parallel: true, sourceMap: devMode }),
|
||||
new TerserPlugin({ parallel: true }),
|
||||
new CssMinimizerPlugin(),
|
||||
]
|
||||
],
|
||||
},
|
||||
mode: options.mode,
|
||||
devtool: devMode ? 'source-map' : undefined,
|
||||
devtool: devMode ? "source-map" : undefined,
|
||||
entry: {
|
||||
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
|
||||
'content-editor': ['./js/content-editor.js'],
|
||||
'tailwind': ['./tailwind.config.js'],
|
||||
app: glob.sync("./vendor/**/*.js").concat(["./js/app.js"]),
|
||||
"content-editor": ["./js/content-editor.js"],
|
||||
},
|
||||
output: {
|
||||
filename: 'js/[name].js',
|
||||
path: path.resolve(__dirname, '../priv/static/')
|
||||
filename: "js/[name].js",
|
||||
path: path.resolve(__dirname, "../priv/static/"),
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
|
@ -34,9 +33,9 @@ module.exports = (env, options) => {
|
|||
{
|
||||
test: /\.(jpg|jpeg|gif|png)$/,
|
||||
use: [
|
||||
'file-loader',
|
||||
"file-loader",
|
||||
{
|
||||
loader: 'image-webpack-loader',
|
||||
loader: "image-webpack-loader",
|
||||
options: {
|
||||
disable: devMode,
|
||||
},
|
||||
|
@ -45,61 +44,108 @@ module.exports = (env, options) => {
|
|||
},
|
||||
{
|
||||
test: /\.(woff2?|ttf|eot|svg)(\?[a-z0-9\=\.]+)?$/,
|
||||
loader: 'file-loader',
|
||||
loader: "file-loader",
|
||||
options: {
|
||||
publicPath: '/fonts',
|
||||
publicPath: "/fonts",
|
||||
outputPath: (url, resourcePath, context) => {
|
||||
return `/fonts/${url}`;
|
||||
},
|
||||
}
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.js$/,
|
||||
exclude: /node_modules/,
|
||||
use: {
|
||||
loader: 'babel-loader'
|
||||
}
|
||||
loader: "babel-loader",
|
||||
},
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: [
|
||||
{loader: MiniCssExtractPlugin.loader},
|
||||
{loader: 'css-loader', options: {sourceMap: true}},
|
||||
{loader: 'postcss-loader', options: {sourceMap: true}},
|
||||
{ loader: MiniCssExtractPlugin.loader },
|
||||
{ loader: "css-loader", options: { sourceMap: true } },
|
||||
{ loader: "postcss-loader", options: { sourceMap: true } },
|
||||
],
|
||||
},
|
||||
]
|
||||
],
|
||||
},
|
||||
plugins: [
|
||||
new MiniCssExtractPlugin({
|
||||
filename: 'css/[name].css',
|
||||
chunkFilename: '[id].css',
|
||||
filename: "css/[name].css",
|
||||
chunkFilename: "[id].css",
|
||||
}),
|
||||
new CopyWebpackPlugin({
|
||||
patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, "static"),
|
||||
to: path.resolve(__dirname, "../priv/static"),
|
||||
},
|
||||
],
|
||||
}),
|
||||
new CopyWebpackPlugin({patterns: [
|
||||
{
|
||||
from: path.resolve(__dirname, 'static'),
|
||||
to: path.resolve(__dirname, '../priv/static'),
|
||||
},
|
||||
]}),
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
"../webfonts/fa-brands-400.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.eot"),
|
||||
"../webfonts/fa-brands-400.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2"),
|
||||
"../webfonts/fa-brands-400.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff"),
|
||||
"../webfonts/fa-brands-400.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.ttf"),
|
||||
"../webfonts/fa-brands-400.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.svg"),
|
||||
"../webfonts/fa-regular-400.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.eot"),
|
||||
"../webfonts/fa-regular-400.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff2"),
|
||||
"../webfonts/fa-regular-400.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff"),
|
||||
"../webfonts/fa-regular-400.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.ttf"),
|
||||
"../webfonts/fa-regular-400.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.svg"),
|
||||
"../webfonts/fa-solid-900.eot": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.eot"),
|
||||
"../webfonts/fa-solid-900.woff2": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2"),
|
||||
"../webfonts/fa-solid-900.woff": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff"),
|
||||
"../webfonts/fa-solid-900.ttf": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.ttf"),
|
||||
"../webfonts/fa-solid-900.svg": path.resolve(__dirname, "node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.svg"),
|
||||
}
|
||||
"../webfonts/fa-brands-400.eot": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.eot"
|
||||
),
|
||||
"../webfonts/fa-brands-400.woff2": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff2"
|
||||
),
|
||||
"../webfonts/fa-brands-400.woff": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.woff"
|
||||
),
|
||||
"../webfonts/fa-brands-400.ttf": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.ttf"
|
||||
),
|
||||
"../webfonts/fa-brands-400.svg": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-brands-400.svg"
|
||||
),
|
||||
"../webfonts/fa-regular-400.eot": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.eot"
|
||||
),
|
||||
"../webfonts/fa-regular-400.woff2": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff2"
|
||||
),
|
||||
"../webfonts/fa-regular-400.woff": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.woff"
|
||||
),
|
||||
"../webfonts/fa-regular-400.ttf": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.ttf"
|
||||
),
|
||||
"../webfonts/fa-regular-400.svg": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-regular-400.svg"
|
||||
),
|
||||
"../webfonts/fa-solid-900.eot": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.eot"
|
||||
),
|
||||
"../webfonts/fa-solid-900.woff2": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff2"
|
||||
),
|
||||
"../webfonts/fa-solid-900.woff": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.woff"
|
||||
),
|
||||
"../webfonts/fa-solid-900.ttf": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.ttf"
|
||||
),
|
||||
"../webfonts/fa-solid-900.svg": path.resolve(
|
||||
__dirname,
|
||||
"node_modules/@fortawesome/fontawesome-free/webfonts/fa-solid-900.svg"
|
||||
),
|
||||
},
|
||||
},
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -4,10 +4,6 @@ defmodule AppWeb.LiveHelpers do
|
|||
"""
|
||||
import Phoenix.LiveView
|
||||
|
||||
alias Legendary.Auth.User
|
||||
alias Pow.Store.CredentialsCache
|
||||
alias AppWeb.Pow.Routes
|
||||
|
||||
def assign_defaults(socket, session) do
|
||||
assign_new(socket, :current_user, fn -> get_user(socket, session) end)
|
||||
end
|
||||
|
@ -16,7 +12,7 @@ defmodule AppWeb.LiveHelpers do
|
|||
if socket.assigns.current_user do
|
||||
socket
|
||||
else
|
||||
redirect(socket, to: Routes.after_sign_out_path(%Plug.Conn{}))
|
||||
redirect(socket, to: "/")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule AppWeb.Telemetry do
|
||||
@moduledoc """
|
||||
Collect metrics on your app.
|
||||
"""
|
||||
|
||||
use Supervisor
|
||||
import Telemetry.Metrics
|
||||
|
||||
|
|
|
@ -7,12 +7,11 @@ defmodule Legendary.Content.Application do
|
|||
# See https://hexdocs.pm/elixir/Application.html
|
||||
# for more information on OTP Applications
|
||||
def start(_type, _args) do
|
||||
import Supervisor.Spec
|
||||
|
||||
# Define workers and child supervisors to be supervised
|
||||
children = [
|
||||
# Start the Ecto repository
|
||||
supervisor(Legendary.Content.Repo, []),
|
||||
Legendary.Content.Repo,
|
||||
# Start the endpoint when the application starts
|
||||
# Start your own worker by calling: Legendary.Content.Worker.start_link(arg1, arg2, arg3)
|
||||
# worker(Legendary.Content.Worker, [arg1, arg2, arg3]),
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Legendary.Content.CommentAdmin do
|
||||
@moduledoc """
|
||||
Custom admin logic for blog post comments.
|
||||
"""
|
||||
|
||||
def index(_) do
|
||||
[
|
||||
id: nil,
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Legendary.Content.MarkupField do
|
||||
@moduledoc """
|
||||
Custom field type definition for markdown fields. Currently uses simplemde
|
||||
to provide a markdown editing GUI.
|
||||
"""
|
||||
use Ecto.Type
|
||||
def type, do: :string
|
||||
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Legendary.Content.PostAdmin do
|
||||
@moduledoc """
|
||||
Custom admin logic for content posts and pages.
|
||||
"""
|
||||
|
||||
import Ecto.Query, only: [from: 2]
|
||||
|
||||
def singular_name(_) do
|
||||
|
|
|
@ -4,7 +4,7 @@ defmodule Legendary.Content.TermRelationship do
|
|||
"""
|
||||
use Ecto.Schema
|
||||
import Ecto.Changeset
|
||||
alias Legendary.Content.{Post}
|
||||
alias Legendary.Content.Post
|
||||
|
||||
@primary_key {:object_id, :integer, []}
|
||||
@primary_key {:term_taxonomy_id, :integer, []}
|
||||
|
|
|
@ -42,7 +42,7 @@ defmodule Legendary.Content do
|
|||
|
||||
def process_content(text) do
|
||||
text
|
||||
|> Earmark.as_html!(encode: false)
|
||||
|> Earmark.as_html!()
|
||||
end
|
||||
|
||||
# Include shared imports and aliases for views
|
||||
|
|
|
@ -87,11 +87,12 @@ defmodule Legendary.Content.PostsController do
|
|||
end
|
||||
|
||||
# The static page we're looking for is missing, so this is just a 404
|
||||
# credo:disable-for-next-line
|
||||
raise Phoenix.Router.NoRouteError.exception(conn: conn, router: router)
|
||||
_ ->
|
||||
# We aren't missing the static page, we're missing a partial. This is probably
|
||||
# a developer error, so bubble it up
|
||||
raise e
|
||||
reraise e, System.stacktrace
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Legendary.Content.Routes do
|
||||
@moduledoc """
|
||||
Routes for the content engine, including blog posts, feeds, and pages.
|
||||
"""
|
||||
|
||||
defmacro __using__(_opts \\ []) do
|
||||
quote do
|
||||
pipeline :feed do
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Legendary.Content.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
@version "2.10.0"
|
||||
@version "3.1.2"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
@ -42,7 +42,7 @@ defmodule Legendary.Content.MixProject do
|
|||
defp deps do
|
||||
[
|
||||
{:core, in_umbrella: true},
|
||||
{:earmark, "1.4.3"},
|
||||
{:earmark, "1.4.15"},
|
||||
{:excoveralls, "~> 0.10", only: [:dev, :test]},
|
||||
{:floki, ">= 0.30.0"},
|
||||
{:gettext, "~> 0.11"},
|
||||
|
@ -57,7 +57,7 @@ defmodule Legendary.Content.MixProject do
|
|||
{:phoenix_html_sanitizer, "~> 1.1.0"},
|
||||
{:phoenix_live_reload, "~> 1.2", only: :dev},
|
||||
{:phoenix_live_dashboard, "~> 0.4.0"},
|
||||
{:php_serializer, "~> 0.9.0"},
|
||||
{:php_serializer, "~> 2.0.0"},
|
||||
{:plug_cowboy, "~> 2.0"},
|
||||
{:sitemap, "~> 1.1"},
|
||||
{:slugger, "~> 0.3"},
|
||||
|
|
|
@ -52,7 +52,7 @@ defmodule Legendary.Content.PostsTest do
|
|||
test "delete_posts/1", %{public_post: post} do
|
||||
assert Enum.count(Posts.list_posts()) == 1
|
||||
assert {:ok, _} = Posts.delete_posts(post)
|
||||
assert Enum.count(Posts.list_posts()) == 0
|
||||
assert Enum.empty?(Posts.list_posts())
|
||||
end
|
||||
|
||||
test "change_posts/1", %{public_post: post} do
|
||||
|
|
31
apps/core/guides/features/linters.md
Normal file
31
apps/core/guides/features/linters.md
Normal file
|
@ -0,0 +1,31 @@
|
|||
# Linters
|
||||
|
||||
Legendary ships with a set of reasonable default linter configurations to help
|
||||
enforce consistent code style in your application. This is particularly valuable
|
||||
when working together as a team. However, even when working solo, linters will
|
||||
find some errors in your code and help you to avoid needless changes in the future.
|
||||
|
||||
Included linters:
|
||||
|
||||
- *credo* for Elixir
|
||||
- *prettier* for JavaScript
|
||||
- *stylelint* for CSS
|
||||
|
||||
## Pre-commit hooks
|
||||
|
||||
If you would like to lint your code before every commit, you can use
|
||||
[lefthook](https://github.com/evilmartians/lefthook) to do so. We include a
|
||||
lefthook.yml that runs credo, prettier, and stylelint for you.
|
||||
|
||||
First, if you do not have it installed already, you will need to
|
||||
[install lefthook](https://github.com/evilmartians/lefthook/blob/master/docs/other.md#installation).
|
||||
On the Mac with Homebrew, this is as simple as `brew install lefthook`. Instructions
|
||||
for other environments are available in the lefthook documentation linked above.
|
||||
|
||||
Then you can install the hooks via `lefthook install`. You can test them without
|
||||
committing by running `lefthook run pre-commit`.
|
||||
|
||||
## Linters in CI
|
||||
|
||||
The included `.gitlab-ci.yml` runs credo, prettier, and stylelint in CI as an
|
||||
additional consistency check.
|
|
@ -301,7 +301,7 @@ We also need to filter the items shown based on the current user. In inventory.e
|
|||
```elixir
|
||||
def list_items(user_id) do
|
||||
Item
|
||||
|> where(owner_id: user_id)
|
||||
|> where(owner_id: ^user_id)
|
||||
|> Repo.all()
|
||||
end
|
||||
```
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
defmodule Legendary.Auth.MnesiaClusterSupervisor do
|
||||
@moduledoc """
|
||||
Manages the cache in Mnesia for Pow. This allows users to remain logged in
|
||||
even if their traffic is hitting different nodes in the cluster.
|
||||
"""
|
||||
|
||||
use Supervisor
|
||||
|
||||
def start_link(init_arg) do
|
||||
|
|
|
@ -1,7 +1,12 @@
|
|||
defmodule Legendary.Auth.Roles do
|
||||
@moduledoc """
|
||||
Functions for working with roles on users, such as testing whether a user has
|
||||
a role.
|
||||
"""
|
||||
|
||||
def has_role?(userlike, role) when is_atom(role), do: has_role?(userlike, Atom.to_string(role))
|
||||
def has_role?(nil, _), do: false
|
||||
def has_role?(user = %Legendary.Auth.User{}, role) do
|
||||
def has_role?(%Legendary.Auth.User{} = user, role) do
|
||||
Enum.any?(user.roles || [], & &1 == role)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -40,7 +40,7 @@ defmodule Legendary.Auth.User do
|
|||
|> pow_extension_changeset(attrs)
|
||||
end
|
||||
|
||||
def reset_password_changeset(user = %Legendary.Auth.User{}, params) do
|
||||
def reset_password_changeset(%Legendary.Auth.User{} = user, params) do
|
||||
user
|
||||
|> new_password_changeset(params, @pow_config)
|
||||
|> Changeset.validate_required([:password])
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
defmodule Legendary.Auth.UserAdmin do
|
||||
@moduledoc """
|
||||
Custom admin login for user records.
|
||||
"""
|
||||
import Ecto.Query, only: [from: 2]
|
||||
alias Legendary.Auth.User
|
||||
alias Legendary.Core.Repo
|
||||
|
||||
def custom_links(_schema) do
|
||||
# We add the funwithflags admin URL under this custom admin because kaffy
|
||||
# doesn't have global custom links that work in this way and user is the
|
||||
# closest fit.
|
||||
[
|
||||
%{name: "Feature Flags", url: "/admin/feature-flags", order: 2, location: :top, icon: "flag"},
|
||||
]
|
||||
|
|
|
@ -24,8 +24,14 @@ defmodule AuthWeb.Pow.ControllerCallbacks do
|
|||
end
|
||||
|
||||
def before_respond(Pow.Phoenix.SessionController, :delete, {:ok, conn}, config) do
|
||||
live_socket_id = Conn.get_session(conn, :live_socket_id)
|
||||
AppWeb.Endpoint.broadcast(live_socket_id, "disconnect", %{})
|
||||
case Conn.get_session(conn, :live_socket_id) do
|
||||
nil ->
|
||||
nil
|
||||
live_socket_id ->
|
||||
%{private: %{phoenix_endpoint: endpoint}} = conn
|
||||
|
||||
apply(endpoint, :broadcast, [live_socket_id, "disconnect", %{}])
|
||||
end
|
||||
|
||||
conn =
|
||||
conn
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
defmodule Legendary.AuthWeb.Helpers do
|
||||
def current_user(socket = %Phoenix.LiveView.Socket{assigns: %{current_user: user}}), do: user
|
||||
def current_user(socket = %Phoenix.LiveView.Socket{assigns: %{__assigns__: %{current_user: user}}}), do: user
|
||||
@moduledoc """
|
||||
Utility functions for working with users and roles.
|
||||
"""
|
||||
|
||||
def current_user(%Phoenix.LiveView.Socket{assigns: %{current_user: user}}), do: user
|
||||
def current_user(%Phoenix.LiveView.Socket{assigns: %{__assigns__: %{current_user: user}}}), do: user
|
||||
def current_user(%Phoenix.LiveView.Socket{}), do: nil
|
||||
def current_user(conn), do: Pow.Plug.current_user(conn)
|
||||
|
||||
|
|
|
@ -7,7 +7,7 @@ defmodule Legendary.Core.MapUtils do
|
|||
Map.merge(base, override, &deep_value/3)
|
||||
end
|
||||
|
||||
defp deep_value(_key, base = %{}, override = %{}) do
|
||||
defp deep_value(_key, %{} = base, %{} = override) do
|
||||
deep_merge(base, override)
|
||||
end
|
||||
|
||||
|
|
|
@ -18,7 +18,11 @@ defmodule Legendary.Core.SharedDBConnectionPool do
|
|||
|
||||
def child_spec({mod, opts}) do
|
||||
opts = Keyword.put_new(opts, :name, key(opts))
|
||||
Supervisor.Spec.worker(Legendary.Core.SharedDBConnectionPool, [{mod, opts}])
|
||||
|
||||
%{
|
||||
id: __MODULE__,
|
||||
start: {Legendary.Core.SharedDBConnectionPool, :start_link, [{mod, opts}]}
|
||||
}
|
||||
end
|
||||
|
||||
defp key(opts) do
|
||||
|
|
|
@ -1,4 +1,10 @@
|
|||
defmodule Legendary.Core.Routes do
|
||||
@moduledoc """
|
||||
Router module that brings in core framework routes, such as the feature flag
|
||||
admin interface. Can be included like:
|
||||
|
||||
use Legendary.Core.Routes
|
||||
"""
|
||||
defmacro __using__(_opts \\ []) do
|
||||
quote do
|
||||
scope path: "/admin/feature-flags" do
|
||||
|
|
|
@ -119,8 +119,8 @@ defmodule Legendary.CoreWeb.Helpers do
|
|||
defp default_classes_for_type(type) when type in [:date_select, :time_select, :datetime_select] do
|
||||
"bg-white shadow rounded p-3"
|
||||
end
|
||||
defp default_classes_for_type(:checkbox), do: "appearance-none h-10 w-10 bg-white checked:bg-gray-500 rounded shadow focus:outline-none focus:shadow-outline text-white text-xl font-bold mb-2"
|
||||
defp default_classes_for_type(_), do: "px-4 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:shadow-outline w-full"
|
||||
defp default_classes_for_type(:checkbox), do: "appearance-none h-10 w-10 bg-white checked:bg-gray-500 rounded shadow focus:outline-none focus:ring text-white text-xl font-bold mb-2"
|
||||
defp default_classes_for_type(_), do: "px-4 py-3 placeholder-gray-400 text-gray-700 bg-white rounded text-sm shadow focus:outline-none focus:ring w-full"
|
||||
|
||||
def styled_button(text) do
|
||||
~E"""
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
defmodule Mix.Legendary do
|
||||
@moduledoc """
|
||||
Parent module for all Legendary framework mix tasks. Provides some helpers
|
||||
used by tasks and generators.
|
||||
"""
|
||||
alias Mix.Phoenix.{Schema}
|
||||
|
||||
@doc false
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
defmodule Legendary.Core.MixProject do
|
||||
use Mix.Project
|
||||
|
||||
@version "2.10.0"
|
||||
@version "3.1.2"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
@ -61,6 +61,7 @@ defmodule Legendary.Core.MixProject do
|
|||
"guides/features/feature-flags.md",
|
||||
"guides/features/i18n.md",
|
||||
"guides/features/tasks-and-scripts.md",
|
||||
"guides/features/linters.md",
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -137,6 +138,7 @@ defmodule Legendary.Core.MixProject do
|
|||
{:bamboo, "~> 1.5"},
|
||||
{:bamboo_smtp, "~> 3.0"},
|
||||
{:credo, "~> 1.4", only: [:dev, :test], runtime: false},
|
||||
{:dialyxir, "~> 1.0", only: [:dev], runtime: false},
|
||||
{:ex_cldr, "~> 2.23.0"},
|
||||
{:ex_doc, "~> 0.24", only: :dev, runtime: false},
|
||||
{:excoveralls, "~> 0.10", only: [:dev, :test]},
|
||||
|
@ -145,7 +147,7 @@ defmodule Legendary.Core.MixProject do
|
|||
{:phoenix, "~> 1.5.8"},
|
||||
{:phoenix_ecto, "~> 4.1"},
|
||||
{:ecto_sql, "~> 3.4"},
|
||||
{:ex_prompt, "~> 0.1.5"},
|
||||
{:ex_prompt, "~> 0.2.0"},
|
||||
{:linguist, git: "https://github.com/change/linguist.git", ref: "d67b60fd597bfe894c69773efd05ad690dad8663"},
|
||||
{:postgrex, ">= 0.0.0"},
|
||||
{:phoenix_html, "~> 2.11"},
|
||||
|
|
|
@ -26,6 +26,7 @@ use Mix.Config
|
|||
"development",
|
||||
"--watch",
|
||||
"--watch-options-stdin",
|
||||
"--progress",
|
||||
cd: Path.expand("../apps/#{otp_app}/assets", __DIR__)
|
||||
]
|
||||
]
|
||||
|
|
|
@ -20,7 +20,7 @@ spec:
|
|||
spec:
|
||||
containers:
|
||||
- name: app
|
||||
image: registry.gitlab.com/mythic-insight/legendary:2.10.0
|
||||
image: registry.gitlab.com/mythic-insight/legendary:3.1.2
|
||||
command: ["elixir"]
|
||||
args:
|
||||
- "--name"
|
||||
|
|
13
lefthook.yml
Normal file
13
lefthook.yml
Normal file
|
@ -0,0 +1,13 @@
|
|||
pre-commit:
|
||||
parallel: true
|
||||
commands:
|
||||
credo:
|
||||
runner: mix credo diff master
|
||||
stylelint:
|
||||
root: "apps/app/assets/"
|
||||
glob: "*.{css}"
|
||||
runner: npx stylelint {staged_files}
|
||||
prettier:
|
||||
root: "apps/app/assets/"
|
||||
glob: "*.{js}"
|
||||
runner: npx prettier --check {staged_files}
|
21
mix.exs
21
mix.exs
|
@ -1,7 +1,7 @@
|
|||
defmodule Legendary.Mixfile do
|
||||
use Mix.Project
|
||||
|
||||
@version "2.10.0"
|
||||
@version "3.1.2"
|
||||
|
||||
def project do
|
||||
[
|
||||
|
@ -11,9 +11,20 @@ defmodule Legendary.Mixfile do
|
|||
build_embedded: Mix.env() == :prod,
|
||||
start_permanent: Mix.env() == :prod,
|
||||
deps: deps(),
|
||||
aliases: aliases(),
|
||||
test_coverage: [tool: ExCoveralls],
|
||||
preferred_cli_env: [coveralls: :test, "coveralls.detail": :test, "coveralls.post": :test, "coveralls.html": :test],
|
||||
aliases: aliases(),
|
||||
dialyzer: [
|
||||
plt_add_apps: [:mix],
|
||||
ignore_warnings: ".dialyzer_ignore.exs"
|
||||
],
|
||||
preferred_cli_env: [
|
||||
coveralls: :test,
|
||||
"coveralls.detail": :test,
|
||||
"coveralls.post": :test,
|
||||
"coveralls.html": :test,
|
||||
"coveralls.json": :test,
|
||||
"coveralls.xml": :test
|
||||
],
|
||||
]
|
||||
end
|
||||
|
||||
|
@ -24,10 +35,8 @@ defmodule Legendary.Mixfile do
|
|||
defp aliases do
|
||||
[
|
||||
"deps.get": ["cmd mix deps.get"],
|
||||
"coveralls.html": ["cmd mix coveralls.html"],
|
||||
"ecto.migrate": ["cmd mix ecto.migrate"],
|
||||
"npm.install": ["cmd mix npm.install"],
|
||||
test: ["cmd mix test"]
|
||||
"npm.install": ["cmd mix npm.install"]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
26
mix.lock
26
mix.lock
|
@ -3,7 +3,7 @@
|
|||
"bamboo_smtp": {:hex, :bamboo_smtp, "3.0.0", "b7f0c371af96a1cb7131908918b02abb228f9db234910bf10cf4fb177c083259", [:mix], [{:bamboo, "~> 1.2", [hex: :bamboo, repo: "hexpm", optional: false]}, {:gen_smtp, "~> 0.15.0", [hex: :gen_smtp, repo: "hexpm", optional: false]}], "hexpm", "77cb1fa3076b24109e54df622161fe1e5619376b4ecf86d8b99b46f327acc49f"},
|
||||
"bcrypt_elixir": {:hex, :bcrypt_elixir, "1.1.1", "6b5560e47a02196ce5f0ab3f1d8265db79a23868c137e973b27afef928ed8006", [:make, :mix], [{:elixir_make, "~> 0.4", [hex: :elixir_make, repo: "hexpm", optional: false]}], "hexpm", "10f658be786bd2daaadcd45cc5b598da01d5bbc313da4d0e3efb2d6a511d896d"},
|
||||
"bunt": {:hex, :bunt, "0.2.0", "951c6e801e8b1d2cbe58ebbd3e616a869061ddadcc4863d0a2182541acae9a38", [:mix], [], "hexpm", "7af5c7e09fe1d40f76c8e4f9dd2be7cebd83909f31fee7cd0e9eadc567da8353"},
|
||||
"certifi": {:hex, :certifi, "2.5.2", "b7cfeae9d2ed395695dd8201c57a2d019c0c43ecaf8b8bcb9320b40d6662f340", [:rebar3], [{:parse_trans, "~>3.3", [hex: :parse_trans, repo: "hexpm", optional: false]}], "hexpm", "3b3b5f36493004ac3455966991eaf6e768ce9884693d9968055aeeeb1e575040"},
|
||||
"certifi": {:hex, :certifi, "2.6.1", "dbab8e5e155a0763eea978c913ca280a6b544bfa115633fa20249c3d396d9493", [:rebar3], [], "hexpm", "524c97b4991b3849dd5c17a631223896272c6b0af446778ba4675a1dff53bb7e"},
|
||||
"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"},
|
||||
"comeonin": {:hex, :comeonin, "4.1.2", "3eb5620fd8e35508991664b4c2b04dd41e52f1620b36957be837c1d7784b7592", [:mix], [{:argon2_elixir, "~> 1.2", [hex: :argon2_elixir, repo: "hexpm", optional: true]}, {:bcrypt_elixir, "~> 0.12.1 or ~> 1.0", [hex: :bcrypt_elixir, repo: "hexpm", optional: true]}, {:pbkdf2_elixir, "~> 0.12", [hex: :pbkdf2_elixir, repo: "hexpm", optional: true]}], "hexpm", "d8700a0ca4dbb616c22c9b3f6dd539d88deaafec3efe66869d6370c9a559b3e9"},
|
||||
|
@ -11,20 +11,20 @@
|
|||
"cowboy": {:hex, :cowboy, "2.9.0", "865dd8b6607e14cf03282e10e934023a1bd8be6f6bacf921a7e2a96d800cd452", [:make, :rebar3], [{:cowlib, "2.11.0", [hex: :cowlib, repo: "hexpm", optional: false]}, {:ranch, "1.8.0", [hex: :ranch, repo: "hexpm", optional: false]}], "hexpm", "2c729f934b4e1aa149aff882f57c6372c15399a20d54f65c8d67bef583021bde"},
|
||||
"cowboy_telemetry": {:hex, :cowboy_telemetry, "0.3.1", "ebd1a1d7aff97f27c66654e78ece187abdc646992714164380d8a041eda16754", [:rebar3], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a6efd3366130eab84ca372cbd4a7d3c3a97bdfcfb4911233b035d117063f0af"},
|
||||
"cowlib": {:hex, :cowlib, "2.11.0", "0b9ff9c346629256c42ebe1eeb769a83c6cb771a6ee5960bd110ab0b9b872063", [:make, :rebar3], [], "hexpm", "2b3e9da0b21c4565751a6d4901c20d1b4cc25cbb7fd50d91d2ab6dd287bc86a9"},
|
||||
"credo": {:hex, :credo, "1.4.0", "92339d4cbadd1e88b5ee43d427b639b68a11071b6f73854e33638e30a0ea11f5", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "1fd3b70dce216574ce3c18bdf510b57e7c4c85c2ec9cad4bff854abaf7e58658"},
|
||||
"credo": {:hex, :credo, "1.5.6", "e04cc0fdc236fefbb578e0c04bd01a471081616e741d386909e527ac146016c6", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "4b52a3e558bd64e30de62a648518a5ea2b6e3e5d2b164ef5296244753fc7eb17"},
|
||||
"crontab": {:hex, :crontab, "1.1.10", "dc9bb1f4299138d47bce38341f5dcbee0aa6c205e864fba7bc847f3b5cb48241", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm", "1347d889d1a0eda997990876b4894359e34bfbbd688acbb0ba28a2795ca40685"},
|
||||
"db_connection": {:hex, :db_connection, "2.2.2", "3bbca41b199e1598245b716248964926303b5d4609ff065125ce98bcd368939e", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "642af240d8a8affb93b4ba5a6fcd2bbcbdc327e1a524b825d383711536f8070c"},
|
||||
"decimal": {:hex, :decimal, "1.9.0", "83e8daf59631d632b171faabafb4a9f4242c514b0a06ba3df493951c08f64d07", [:mix], [], "hexpm", "b1f2343568eed6928f3e751cf2dffde95bfaa19dd95d09e8a9ea92ccfd6f7d85"},
|
||||
"dialyxir": {:hex, :dialyxir, "1.0.0", "6a1fa629f7881a9f5aaf3a78f094b2a51a0357c843871b8bc98824e7342d00a5", [:mix], [{:erlex, ">= 0.2.6", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm", "aeb06588145fac14ca08d8061a142d52753dbc2cf7f0d00fc1013f53f8654654"},
|
||||
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.12", "b245e875ec0a311a342320da0551da407d9d2b65d98f7a9597ae078615af3449", [:mix], [], "hexpm", "711e2cc4d64abb7d566d43f54b78f7dc129308a63bc103fbd88550d2174b3160"},
|
||||
"earmark": {:hex, :earmark, "1.4.15", "2c7f924bf495ec1f65bd144b355d0949a05a254d0ec561740308a54946a67888", [:mix], [{:earmark_parser, ">= 1.4.13", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "3b1209b85bc9f3586f370f7c363f6533788fb4e51db23aa79565875e7f9999ee"},
|
||||
"earmark_parser": {:hex, :earmark_parser, "1.4.13", "0c98163e7d04a15feb62000e1a891489feb29f3d10cb57d4f845c405852bbef8", [:mix], [], "hexpm", "d602c26af3a0af43d2f2645613f65841657ad6efc9f0e361c3b6c06b578214ba"},
|
||||
"ecto": {:hex, :ecto, "3.4.6", "08f7afad3257d6eb8613309af31037e16c36808dfda5a3cd0cb4e9738db030e4", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "6f13a9e2a62e75c2dcfc7207bfc65645ab387af8360db4c89fee8b5a4bf3f70b"},
|
||||
"ecto_sql": {:hex, :ecto_sql, "3.4.4", "d28bac2d420f708993baed522054870086fd45016a9d09bb2cd521b9c48d32ea", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0 or ~> 0.4.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:tds, "~> 2.1.0", [hex: :tds, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "edb49af715dd72f213b66adfd0f668a43c17ed510b5d9ac7528569b23af57fe8"},
|
||||
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
|
||||
"erlex": {:hex, :erlex, "0.2.6", "c7987d15e899c7a2f34f5420d2a2ea0d659682c06ac607572df55a43753aa12e", [:mix], [], "hexpm", "2ed2e25711feb44d52b17d2780eabf998452f6efda104877a3881c2f8c0c0c75"},
|
||||
"ex_cldr": {:hex, :ex_cldr, "2.23.0", "16aa883c3388a0b27485a810ae2a60d815968a473b5315454ebe2b5264e92a80", [: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]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm", "7c9dad3115e2622a4902390591d9c4a2f7c5333bd73f02a02f7b4190394c7347"},
|
||||
"ex_doc": {:hex, :ex_doc, "0.24.0", "2df14354835afaabdf87cb2971ea9485d8a36ff590e4b6c250b4f60c8fdf9143", [:mix], [{:earmark_parser, "~> 1.4.0", [hex: :earmark_parser, repo: "hexpm", optional: false]}, {:makeup_elixir, "~> 0.14", [hex: :makeup_elixir, repo: "hexpm", optional: false]}, {:makeup_erlang, "~> 0.1", [hex: :makeup_erlang, repo: "hexpm", optional: false]}], "hexpm", "a0f4bcff21ceebea48414e49885d2a3e542200f76a2facf3f8faa54935eeb721"},
|
||||
"ex_prompt": {:hex, :ex_prompt, "0.1.5", "b136642d0962f8ea37b3c9fa185ad1f42c71c3b9c6c3950f0358d7f3d2db2970", [:mix], [], "hexpm", "ad19a404708c9c7b05d36090b2d074ceafbed248a8de1a22d45a05ebe6994b83"},
|
||||
"ex_prompt": {:hex, :ex_prompt, "0.2.0", "4030424e9a7710e1939d81eea4a82af2e0a1826065adb28d59bc01e919af4a60", [:mix], [], "hexpm", "220ac023d87d529457b87c9db4b40ce542bff93ae2de16c582808c6822dfe3e8"},
|
||||
"excoveralls": {:hex, :excoveralls, "0.13.0", "4e1b7cc4e0351d8d16e9be21b0345a7e165798ee5319c7800b9138ce17e0b38e", [:mix], [{:hackney, "~> 1.16", [hex: :hackney, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "fe2a56c8909564e2e6764765878d7d5e141f2af3bc8ff3b018a68ee2a218fced"},
|
||||
"file_system": {:hex, :file_system, "0.2.8", "f632bd287927a1eed2b718f22af727c5aeaccc9a98d8c2bd7bff709e851dc986", [:mix], [], "hexpm", "97a3b6f8d63ef53bd0113070102db2ce05352ecf0d25390eb8d747c2bde98bca"},
|
||||
"floki": {:hex, :floki, "0.31.0", "f05ee8a8e6a3ced4e62beeb2c79a63bc8e12ab98fbaaf6e6a3d9b76b1278e23f", [:mix], [{:html_entities, "~> 0.5.0", [hex: :html_entities, repo: "hexpm", optional: false]}], "hexpm", "b05afa372f5c345a5bf240ac25ea1f0f3d5fcfd7490ac0beeb4a203f9444891e"},
|
||||
|
@ -34,15 +34,15 @@
|
|||
"gen_stage": {:hex, :gen_stage, "1.0.0", "51c8ae56ff54f9a2a604ca583798c210ad245f415115453b773b621c49776df5", [:mix], [], "hexpm", "1d9fc978db5305ac54e6f5fec7adf80cd893b1000cf78271564c516aa2af7706"},
|
||||
"gen_state_machine": {:hex, :gen_state_machine, "2.1.0", "a38b0e53fad812d29ec149f0d354da5d1bc0d7222c3711f3a0bd5aa608b42992", [:mix], [], "hexpm", "ae367038808db25cee2f2c4b8d0531522ea587c4995eb6f96ee73410a60fa06b"},
|
||||
"gettext": {:hex, :gettext, "0.18.2", "7df3ea191bb56c0309c00a783334b288d08a879f53a7014341284635850a6e55", [:mix], [], "hexpm", "f9f537b13d4fdd30f3039d33cb80144c3aa1f8d9698e47d7bcbcc8df93b1f5c5"},
|
||||
"hackney": {:hex, :hackney, "1.16.0", "5096ac8e823e3a441477b2d187e30dd3fff1a82991a806b2003845ce72ce2d84", [:rebar3], [{:certifi, "2.5.2", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "6.0.1", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "1.0.1", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.0", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "1.1.6", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}], "hexpm", "3bf0bebbd5d3092a3543b783bf065165fa5d3ad4b899b836810e513064134e18"},
|
||||
"hackney": {:hex, :hackney, "1.17.4", "99da4674592504d3fb0cfef0db84c3ba02b4508bae2dff8c0108baa0d6e0977c", [:rebar3], [{:certifi, "~>2.6.1", [hex: :certifi, repo: "hexpm", optional: false]}, {:idna, "~>6.1.0", [hex: :idna, repo: "hexpm", optional: false]}, {:metrics, "~>1.0.0", [hex: :metrics, repo: "hexpm", optional: false]}, {:mimerl, "~>1.1", [hex: :mimerl, repo: "hexpm", optional: false]}, {:parse_trans, "3.3.1", [hex: :parse_trans, repo: "hexpm", optional: false]}, {:ssl_verify_fun, "~>1.1.0", [hex: :ssl_verify_fun, repo: "hexpm", optional: false]}, {:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "de16ff4996556c8548d512f4dbe22dd58a587bf3332e7fd362430a7ef3986b16"},
|
||||
"html_entities": {:hex, :html_entities, "0.5.2", "9e47e70598da7de2a9ff6af8758399251db6dbb7eebe2b013f2bbd2515895c3c", [:mix], [], "hexpm", "c53ba390403485615623b9531e97696f076ed415e8d8058b1dbaa28181f4fdcc"},
|
||||
"html_sanitize_ex": {:hex, :html_sanitize_ex, "1.4.1", "e8a67da405fe9f0d1be121a40a60f70811192033a5b8d00a95dddd807f5e053e", [:mix], [{:mochiweb, "~> 2.15", [hex: :mochiweb, repo: "hexpm", optional: false]}], "hexpm", "68d92656f47cd73598c45ad2394561f025c8c65d146001b955fd7b517858962a"},
|
||||
"idna": {:hex, :idna, "6.0.1", "1d038fb2e7668ce41fbf681d2c45902e52b3cb9e9c77b55334353b222c2ee50c", [:rebar3], [{:unicode_util_compat, "0.5.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "a02c8a1c4fd601215bb0b0324c8a6986749f807ce35f25449ec9e69758708122"},
|
||||
"idna": {:hex, :idna, "6.1.1", "8a63070e9f7d0c62eb9d9fcb360a7de382448200fbbd1b106cc96d3d8099df8d", [:rebar3], [{:unicode_util_compat, "~>0.7.0", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "92376eb7894412ed19ac475e4a86f7b413c1b9fbb5bd16dccd57934157944cea"},
|
||||
"jason": {:hex, :jason, "1.2.2", "ba43e3f2709fd1aa1dce90aaabfd039d000469c05c56f0b8e31978e03fa39052", [:mix], [{:decimal, "~> 1.0 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "18a228f5f0058ee183f29f9eae0805c6e59d61c3b006760668d8d18ff0d12179"},
|
||||
"kaffy": {:hex, :kaffy, "0.9.0", "bef34c9729f6a3af4d0dea8eede8bcb9e11371a83ac9a8b393991bce81839517", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix, "~> 1.4", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.11", [hex: :phoenix_html, repo: "hexpm", optional: false]}], "hexpm", "d18ff57b8e68feb433aed11e71510cd357abc7034e75358af5deff7d0d4c6ed3"},
|
||||
"libcluster": {:hex, :libcluster, "3.3.0", "f7d45ff56d88e9fb4c30aee662480cbab69ebc0e7f7da4ad8d01b1e4f7492da8", [:mix], [{:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "ecdcdc88334ec8eb18b10a13a1d5f22a3319a970b5b1e66cfe71c7719a4ab6cc"},
|
||||
"libring": {:hex, :libring, "1.5.0", "44313eb6862f5c9168594a061e9d5f556a9819da7c6444706a9e2da533396d70", [:mix], [], "hexpm", "04e843d4fdcff49a62d8e03778d17c6cb2a03fe2d14020d3825a1761b55bd6cc"},
|
||||
"linguist": {:hex, :linguist, "0.3.1", "8ce81114691be8ef4a122e7f57bd1842bc96b1f5650b66b246d7035238cab69d", [:mix], [{:ex_cldr, "~> 2.0", [hex: :ex_cldr, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}, {:yaml_elixir, "~> 2.0", [hex: :yaml_elixir, repo: "hexpm", optional: false]}], "hexpm", "5b06f97912e298f60dd00bc6a588b1fe1ec8838b268e4fdbf4443a25511f0614"},
|
||||
"linguist": {:git, "https://github.com/change/linguist.git", "d67b60fd597bfe894c69773efd05ad690dad8663", [ref: "d67b60fd597bfe894c69773efd05ad690dad8663"]},
|
||||
"makeup": {:hex, :makeup, "1.0.5", "d5a830bc42c9800ce07dd97fa94669dfb93d3bf5fcf6ea7a0c67b2e0e4a7f26c", [:mix], [{:nimble_parsec, "~> 0.5 or ~> 1.0", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "cfa158c02d3f5c0c665d0af11512fed3fba0144cf1aadee0f2ce17747fba2ca9"},
|
||||
"makeup_elixir": {:hex, :makeup_elixir, "0.15.1", "b5888c880d17d1cc3e598f05cdb5b5a91b7b17ac4eaf5f297cb697663a1094dd", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}, {:nimble_parsec, "~> 1.1", [hex: :nimble_parsec, repo: "hexpm", optional: false]}], "hexpm", "db68c173234b07ab2a07f645a5acdc117b9f99d69ebf521821d89690ae6c6ec8"},
|
||||
"makeup_erlang": {:hex, :makeup_erlang, "0.1.1", "3fcb7f09eb9d98dc4d208f49cc955a34218fc41ff6b84df7c75b3e6e533cc65f", [:mix], [{:makeup, "~> 1.0", [hex: :makeup, repo: "hexpm", optional: false]}], "hexpm", "174d0809e98a4ef0b3309256cbf97101c6ec01c4ab0b23e926a9e17df2077cbb"},
|
||||
|
@ -55,7 +55,7 @@
|
|||
"neotomex": {:hex, :neotomex, "0.1.7", "64f76513653aa87ea7abdde0fd600e56955d838020a13d88f2bf334c88ac3e7a", [:mix], [], "hexpm", "4b87b8f614d1cd89dc8ba80ba0e559bedb3ebf6f6d74cd774fcfdd215e861445"},
|
||||
"nimble_parsec": {:hex, :nimble_parsec, "1.1.0", "3a6fca1550363552e54c216debb6a9e95bd8d32348938e13de5eda962c0d7f89", [:mix], [], "hexpm", "08eb32d66b706e913ff748f11694b17981c0b04a33ef470e33e11b3d3ac8f54b"},
|
||||
"oban": {:hex, :oban, "2.1.0", "034144686f7e76a102b5d67731f098d98a9e4a52b07c25ad580a01f83a7f1cf5", [:mix], [{:ecto_sql, ">= 3.4.3", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:jason, "~> 1.1", [hex: :jason, repo: "hexpm", optional: false]}, {:postgrex, "~> 0.14", [hex: :postgrex, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "c6f067fa3b308ed9e0e6beb2b34277c9c4e48bf95338edabd8f4a757a26e04c2"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.0", "09765507a3c7590a784615cfd421d101aec25098d50b89d7aa1d66646bc571c1", [:rebar3], [], "hexpm", "17ef63abde837ad30680ea7f857dd9e7ced9476cdd7b0394432af4bfc241b960"},
|
||||
"parse_trans": {:hex, :parse_trans, "3.3.1", "16328ab840cc09919bd10dab29e431da3af9e9e7e7e6f0089dd5a2d2820011d8", [:rebar3], [], "hexpm", "07cd9577885f56362d414e8c4c4e6bdf10d43a8767abb92d24cbe8b24c54888b"},
|
||||
"phoenix": {:hex, :phoenix, "1.5.9", "a6368d36cfd59d917b37c44386e01315bc89f7609a10a45a22f47c007edf2597", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_html, "~> 2.13 or ~> 3.0", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 2.0", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.10", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.2", [hex: :plug_cowboy, repo: "hexpm", optional: true]}, {:plug_crypto, "~> 1.1.2 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "7e4bce20a67c012f1fbb0af90e5da49fa7bf0d34e3a067795703b74aef75427d"},
|
||||
"phoenix_ecto": {:hex, :phoenix_ecto, "4.1.0", "a044d0756d0464c5a541b4a0bf4bcaf89bffcaf92468862408290682c73ae50d", [:mix], [{:ecto, "~> 3.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.9", [hex: :phoenix_html, repo: "hexpm", optional: true]}, {:plug, "~> 1.0", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "c5e666a341ff104d0399d8f0e4ff094559b2fde13a5985d4cb5023b2c2ac558b"},
|
||||
"phoenix_html": {:hex, :phoenix_html, "2.14.3", "51f720d0d543e4e157ff06b65de38e13303d5778a7919bcc696599e5934271b8", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm", "efd697a7fff35a13eeeb6b43db884705cba353a1a41d127d118fda5f90c8e80f"},
|
||||
|
@ -64,7 +64,7 @@
|
|||
"phoenix_live_reload": {:hex, :phoenix_live_reload, "1.2.4", "940c0344b1d66a2e46eef02af3a70e0c5bb45a4db0bf47917add271b76cd3914", [: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", "38f9308357dea4cc77f247e216da99fcb0224e05ada1469167520bed4cb8cccd"},
|
||||
"phoenix_live_view": {:hex, :phoenix_live_view, "0.15.7", "09720b8e5151b3ca8ef739cd7626d4feb987c69ba0b509c9bbdb861d5a365881", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix, "~> 1.5.7", [hex: :phoenix, repo: "hexpm", optional: false]}, {:phoenix_html, "~> 2.14", [hex: :phoenix_html, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.2 or ~> 0.5", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "3a756cf662420272d0f1b3b908cce5222163b5a95aa9bab404f9d29aff53276e"},
|
||||
"phoenix_pubsub": {:hex, :phoenix_pubsub, "2.0.0", "a1ae76717bb168cdeb10ec9d92d1480fec99e3080f011402c0a2d68d47395ffb", [:mix], [], "hexpm", "c52d948c4f261577b9c6fa804be91884b381a7f8f18450c5045975435350f771"},
|
||||
"php_serializer": {:hex, :php_serializer, "0.9.2", "59c5fd6bd3096671fd89358fb8229341ac7423b50ad8d45a15213b02ea2edab2", [:mix], [], "hexpm", "34eb835a460944f7fc216773b363c02e7dcf8ac0390c9e9ccdbd92b31a7ca59a"},
|
||||
"php_serializer": {:hex, :php_serializer, "2.0.0", "b43f31aca22ed7321f32da2b94fe2ddf9b6739a965cb51541969119e572e821d", [:mix], [], "hexpm", "61e402e99d9062c0225a3f4fcf7e43b4cba1b8654944c0e7c139c3ca9de481da"},
|
||||
"plug": {:hex, :plug, "1.12.1", "645678c800601d8d9f27ad1aebba1fdb9ce5b2623ddb961a074da0b96c35187d", [:mix], [{:mime, "~> 1.0 or ~> 2.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.1.1 or ~> 1.2", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4.3 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "d57e799a777bc20494b784966dc5fbda91eb4a09f571f76545b72a634ce0d30b"},
|
||||
"plug_cowboy": {:hex, :plug_cowboy, "2.5.1", "7cc96ff645158a94cf3ec9744464414f02287f832d6847079adfe0b58761cbd0", [:mix], [{:cowboy, "~> 2.7", [hex: :cowboy, repo: "hexpm", optional: false]}, {:cowboy_telemetry, "~> 0.3", [hex: :cowboy_telemetry, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "107d0a5865fa92bcb48e631cc0729ae9ccfa0a9f9a1bd8f01acb513abf1c2d64"},
|
||||
"plug_crypto": {:hex, :plug_crypto, "1.2.2", "05654514ac717ff3a1843204b424477d9e60c143406aa94daf2274fdd280794d", [:mix], [], "hexpm", "87631c7ad914a5a445f0a3809f99b079113ae4ed4b867348dd9eec288cecb6db"},
|
||||
|
@ -79,9 +79,9 @@
|
|||
"telemetry": {:hex, :telemetry, "0.4.3", "a06428a514bdbc63293cd9a6263aad00ddeb66f608163bdec7c8995784080818", [:rebar3], [], "hexpm", "eb72b8365ffda5bed68a620d1da88525e326cb82a75ee61354fc24b844768041"},
|
||||
"telemetry_metrics": {:hex, :telemetry_metrics, "0.6.0", "da9d49ee7e6bb1c259d36ce6539cd45ae14d81247a2b0c90edf55e2b50507f7b", [:mix], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5cfe67ad464b243835512aa44321cee91faed6ea868d7fb761d7016e02915c3d"},
|
||||
"telemetry_poller": {:hex, :telemetry_poller, "0.5.1", "21071cc2e536810bac5628b935521ff3e28f0303e770951158c73eaaa01e962a", [:rebar3], [{:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "4cab72069210bc6e7a080cec9afffad1b33370149ed5d379b81c7c5f0c663fd4"},
|
||||
"timex": {:hex, :timex, "3.6.2", "845cdeb6119e2fef10751c0b247b6c59d86d78554c83f78db612e3290f819bc2", [:mix], [{:combine, "~> 0.10", [hex: :combine, repo: "hexpm", optional: false]}, {:gettext, "~> 0.10", [hex: :gettext, repo: "hexpm", optional: false]}, {:tzdata, "~> 0.1.8 or ~> 0.5 or ~> 1.0.0", [hex: :tzdata, repo: "hexpm", optional: false]}], "hexpm", "26030b46199d02a590be61c2394b37ea25a3664c02fafbeca0b24c972025d47a"},
|
||||
"tzdata": {:hex, :tzdata, "1.0.3", "73470ad29dde46e350c60a66e6b360d3b99d2d18b74c4c349dbebbc27a09a3eb", [:mix], [{:hackney, "~> 1.0", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "a6e1ee7003c4d04ecbd21dd3ec690d4c6662db5d3bbdd7262d53cdf5e7c746c1"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.5.0", "8516502659002cec19e244ebd90d312183064be95025a319a6c7e89f4bccd65b", [:rebar3], [], "hexpm", "d48d002e15f5cc105a696cf2f1bbb3fc72b4b770a184d8420c8db20da2674b38"},
|
||||
"timex": {:hex, :timex, "3.7.5", "3eca56e23bfa4e0848f0b0a29a92fa20af251a975116c6d504966e8a90516dfd", [: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", "a15608dca680f2ef663d71c95842c67f0af08a0f3b1d00e17bbd22872e2874e4"},
|
||||
"tzdata": {:hex, :tzdata, "1.1.0", "72f5babaa9390d0f131465c8702fa76da0919e37ba32baa90d93c583301a8359", [:mix], [{:hackney, "~> 1.17", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "18f453739b48d3dc5bcf0e8906d2dc112bb40baafe2c707596d89f3c8dd14034"},
|
||||
"unicode_util_compat": {:hex, :unicode_util_compat, "0.7.0", "bc84380c9ab48177092f43ac89e4dfa2c6d62b40b8bd132b1059ecc7232f9a78", [:rebar3], [], "hexpm", "25eee6d67df61960cf6a794239566599b09e17e668d3700247bc498638152521"},
|
||||
"xml_builder": {:hex, :xml_builder, "2.1.2", "90cb9ad382958934c78c6ddfbe6d385a8ce147d84b61cbfa83ec93a169d0feab", [:mix], [], "hexpm", "b89046041da2fbc1d51d31493ba31b9d5fc6223c93384bf513a1a9e1df9ec081"},
|
||||
"yamerl": {:hex, :yamerl, "0.8.1", "07da13ffa1d8e13948943789665c62ccd679dfa7b324a4a2ed3149df17f453a4", [:rebar3], [], "hexpm", "96cb30f9d64344fed0ef8a92e9f16f207de6c04dfff4f366752ca79f5bceb23f"},
|
||||
"yaml_elixir": {:hex, :yaml_elixir, "2.8.0", "c7ff0034daf57279c2ce902788ce6fdb2445532eb4317e8df4b044209fae6832", [:mix], [{:yamerl, "~> 0.8", [hex: :yamerl, repo: "hexpm", optional: false]}], "hexpm", "4b674bd881e373d1ac6a790c64b2ecb69d1fd612c2af3b22de1619c15473830b"},
|
||||
|
|
16
package-lock.json
generated
16
package-lock.json
generated
|
@ -1,12 +1,12 @@
|
|||
{
|
||||
"name": "@mythic-insight/legendary",
|
||||
"version": "2.9.1",
|
||||
"version": "2.12.0",
|
||||
"lockfileVersion": 2,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@mythic-insight/legendary",
|
||||
"version": "2.9.1",
|
||||
"version": "2.12.0",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@google/semantic-release-replace-plugin": "^1.0.2",
|
||||
|
@ -5035,9 +5035,9 @@
|
|||
}
|
||||
},
|
||||
"node_modules/hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/http-proxy": {
|
||||
|
@ -10844,9 +10844,9 @@
|
|||
"dev": true
|
||||
},
|
||||
"hosted-git-info": {
|
||||
"version": "2.8.8",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz",
|
||||
"integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==",
|
||||
"version": "2.8.9",
|
||||
"resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
|
||||
"integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==",
|
||||
"dev": true
|
||||
},
|
||||
"http-proxy": {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "@mythic-insight/legendary",
|
||||
"version": "2.10.0",
|
||||
"version": "3.1.2",
|
||||
"private": true,
|
||||
"description": "The Legendary Phoenix Boilerplate.",
|
||||
"main": "index.js",
|
||||
|
|
|
@ -12,6 +12,10 @@ mix deps.get
|
|||
mix ecto.create
|
||||
mix ecto.migrate
|
||||
|
||||
mix test
|
||||
if [ $1 == 'covered' ]; then
|
||||
mix coveralls.json --umbrella
|
||||
else
|
||||
mix test
|
||||
fi;
|
||||
|
||||
script/restore-timestamps
|
||||
|
|
124
script/coverage-json-to-cobertura
Executable file
124
script/coverage-json-to-cobertura
Executable file
|
@ -0,0 +1,124 @@
|
|||
#!/usr/bin/env elixir
|
||||
|
||||
Mix.install([
|
||||
{:jason, "~> 1.0"},
|
||||
{:xml_builder, "~> 2.1"}
|
||||
])
|
||||
|
||||
%{"source_files" => data} =
|
||||
"cover/excoveralls.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
{total_covered, total_total} =
|
||||
data
|
||||
|> Enum.reduce({0,0}, fn %{"coverage" => cover}, {covered, total} ->
|
||||
file_covered =
|
||||
cover
|
||||
|> Enum.reduce(0, &(if is_integer(&1) && &1 > 0, do: &2 + 1, else: &2))
|
||||
|
||||
file_total =
|
||||
cover
|
||||
|> Enum.reduce(0, &(if is_nil(&1), do: &2, else: &2 + 1))
|
||||
|
||||
{covered + file_covered, total + file_total}
|
||||
end)
|
||||
|
||||
ratio = total_covered / total_total
|
||||
|
||||
files =
|
||||
data
|
||||
|> Enum.map(fn %{"coverage" => cover, "name" => name} ->
|
||||
file_covered =
|
||||
cover
|
||||
|> Enum.reduce(0, &(if is_integer(&1) && &1 > 0, do: &2 + 1, else: &2))
|
||||
|
||||
file_total =
|
||||
cover
|
||||
|> Enum.reduce(0, &(if is_nil(&1), do: &2, else: &2 + 1))
|
||||
|
||||
lines =
|
||||
cover
|
||||
|> Enum.with_index
|
||||
|> Enum.map(fn
|
||||
{nil, _index} ->
|
||||
nil
|
||||
{line, index} ->
|
||||
{:line, %{"number" => index, "hits" => line}, []}
|
||||
end)
|
||||
|> Enum.reject(&is_nil/1)
|
||||
|
||||
ratio =
|
||||
if file_total == 0 do
|
||||
1.0
|
||||
else
|
||||
file_covered / file_total
|
||||
end
|
||||
|
||||
{
|
||||
:class,
|
||||
%{"filename" => name, "line-rate" => ratio},
|
||||
[
|
||||
{
|
||||
:lines,
|
||||
%{},
|
||||
lines
|
||||
}
|
||||
]
|
||||
}
|
||||
end)
|
||||
|
||||
source =
|
||||
if System.get_env("CI_PROJECT_NAME") do
|
||||
"#{System.get_env("CI_BUILDS_DIR")}/#{System.get_env("CI_PROJECT_NAMESPACE")}/#{System.get_env("CI_PROJECT_NAME")}"
|
||||
else
|
||||
File.cwd!
|
||||
end
|
||||
|
||||
|
||||
buffer =
|
||||
XmlBuilder.document([
|
||||
XmlBuilder.doctype(
|
||||
"coverage",
|
||||
system: ["http://cobertura.sourceforge.net/xml/coverage-03.dtd"]
|
||||
),
|
||||
{
|
||||
:coverage,
|
||||
%{
|
||||
"line-rate" => ratio,
|
||||
},
|
||||
[
|
||||
{
|
||||
:sources,
|
||||
%{},
|
||||
[
|
||||
{
|
||||
:source,
|
||||
%{},
|
||||
source
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
:packages,
|
||||
%{},
|
||||
[
|
||||
{
|
||||
:package,
|
||||
%{"name" => "", "line-rate" => ratio},
|
||||
[
|
||||
{
|
||||
:classes,
|
||||
%{},
|
||||
files
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
])
|
||||
|> XmlBuilder.generate
|
||||
|
||||
File.write!("cover/cobertura.xml", buffer)
|
30
script/coverage-json-to-metrics
Executable file
30
script/coverage-json-to-metrics
Executable file
|
@ -0,0 +1,30 @@
|
|||
#!/usr/bin/env elixir
|
||||
|
||||
Mix.install([
|
||||
{:jason, "~> 1.0"}
|
||||
])
|
||||
|
||||
%{"source_files" => data} =
|
||||
"cover/excoveralls.json"
|
||||
|> File.read!()
|
||||
|> Jason.decode!()
|
||||
|
||||
{total_covered, total_total} =
|
||||
data
|
||||
|> Enum.reduce({0,0}, fn %{"coverage" => cover}, {covered, total} ->
|
||||
file_covered =
|
||||
cover
|
||||
|> Enum.reduce(0, &(if is_integer(&1) && &1 > 0, do: &2 + 1, else: &2))
|
||||
|
||||
file_total =
|
||||
cover
|
||||
|> Enum.reduce(0, &(if is_nil(&1), do: &2, else: &2 + 1))
|
||||
|
||||
{covered + file_covered, total + file_total}
|
||||
end)
|
||||
|
||||
ratio =
|
||||
(total_covered / total_total)
|
||||
|> Float.round(3)
|
||||
|
||||
File.write!("metrics.txt", "coverage #{ratio}")
|
Loading…
Reference in a new issue