mirror of
https://code.castopod.org/adaures/castopod
synced 2025-04-18 20:41:18 +00:00
refactor: update js files to typescript and replace parcel with rollup
- add basic rollup config to bundle minified and browser compatible js - use babel to transpile typescript files to js - add static code checkers: eslint and stylelint - update package.json scripts - update DEPENDENCIES.md file to include rollup and popper - set html in rss feed description fields - update Podcast and Episode entities to add description_html attribute generated by parsing markdown to html using parsedown #9
This commit is contained in:
parent
c0e66d5f70
commit
e0da11517d
4
.babelrc
Normal file
4
.babelrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"presets": ["@babel/preset-typescript", "@babel/preset-env"],
|
||||
"plugins": ["@babel/plugin-proposal-class-properties"]
|
||||
}
|
5
.browserslistrc
Normal file
5
.browserslistrc
Normal file
@ -0,0 +1,5 @@
|
||||
# Browsers that we support
|
||||
|
||||
>0.2%,
|
||||
not dead,
|
||||
not op_mini all
|
@ -6,24 +6,22 @@
|
||||
"settings": {
|
||||
"terminal.integrated.shell.linux": "/bin/bash",
|
||||
"editor.formatOnSave": true,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.organizeImports": true
|
||||
},
|
||||
"[php]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"color-highlight.markerType": "dot-before"
|
||||
},
|
||||
"extensions": [
|
||||
"mikestead.dotenv",
|
||||
"bmewburn.vscode-intelephense-client",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"naumovs.color-highlight",
|
||||
"heybourn.headwind",
|
||||
"wayou.vscode-todo-highlight",
|
||||
"esbenp.prettier-vscode",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"jamesbirtles.svelte-vscode",
|
||||
"dbaeumer.vscode-eslint"
|
||||
]
|
||||
"mikestead.dotenv",
|
||||
"bmewburn.vscode-intelephense-client",
|
||||
"streetsidesoftware.code-spell-checker",
|
||||
"naumovs.color-highlight",
|
||||
"heybourn.headwind",
|
||||
"wayou.vscode-todo-highlight",
|
||||
"esbenp.prettier-vscode",
|
||||
"bradlc.vscode-tailwindcss",
|
||||
"jamesbirtles.svelte-vscode",
|
||||
"dbaeumer.vscode-eslint",
|
||||
"stylelint.vscode-stylelint"
|
||||
]
|
||||
}
|
||||
|
@ -3,7 +3,14 @@
|
||||
"browser": true,
|
||||
"es2020": true
|
||||
},
|
||||
"extends": ["eslint:recommended", "plugin:prettier/recommended"],
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": [
|
||||
"eslint:recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"prettier/@typescript-eslint",
|
||||
"plugin:prettier/recommended"
|
||||
],
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 11,
|
||||
"sourceType": "module"
|
||||
|
18
.stylelintrc.json
Normal file
18
.stylelintrc.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"extends": "stylelint-config-recommended",
|
||||
"rules": {
|
||||
"at-rule-no-unknown": [
|
||||
true,
|
||||
{
|
||||
"ignoreAtRules": [
|
||||
"tailwind",
|
||||
"apply",
|
||||
"responsive",
|
||||
"variants",
|
||||
"screen"
|
||||
]
|
||||
}
|
||||
],
|
||||
"no-descending-specificity": null
|
||||
}
|
||||
}
|
@ -14,10 +14,11 @@ PHP Dependencies:
|
||||
|
||||
Javascript dependencies:
|
||||
|
||||
- [rollup](https://rollupjs.org/) ([MIT License](https://github.com/rollup/rollup/blob/master/LICENSE.md))
|
||||
- [tailwindcss](https://tailwindcss.com/) ([MIT License](https://github.com/tailwindcss/tailwindcss/blob/master/LICENSE))
|
||||
- [CodeMirror](https://github.com/codemirror/CodeMirror) ([MIT License](https://github.com/codemirror/CodeMirror/blob/master/LICENSE))
|
||||
- [ProseMirror](https://prosemirror.net/) ([MIT License](https://github.com/ProseMirror/prosemirror/blob/master/LICENSE))
|
||||
- [D3: Data-Driven Documents](https://github.com/d3/d3) ([BSD 3-Clause "New" or "Revised" License](https://github.com/d3/d3/blob/master/LICENSE))
|
||||
- [D3: Data-Driven Documents](https://d3js.org) ([BSD 3-Clause "New" or "Revised" License](https://github.com/d3/d3/blob/master/LICENSE))
|
||||
|
||||
Other:
|
||||
|
||||
|
@ -159,23 +159,19 @@ class Episode extends Entity
|
||||
|
||||
public function getDescriptionHtml()
|
||||
{
|
||||
$converter = new CommonMarkConverter([
|
||||
'html_input' => 'strip',
|
||||
'allow_unsafe_links' => false,
|
||||
'renderer' => [
|
||||
'soft_break' => '<br>',
|
||||
],
|
||||
]);
|
||||
$converter = new Parsedown();
|
||||
$converter->setBreaksEnabled(true);
|
||||
|
||||
if (
|
||||
$description_footer = $this->getPodcast()
|
||||
->episode_description_footer
|
||||
) {
|
||||
return $converter->convertToHtml(
|
||||
$this->attributes['description'] . '---'
|
||||
) . $converter->convertToHtml($description_footer);
|
||||
return $converter->text($this->attributes['description']) .
|
||||
'<footer>' .
|
||||
$converter->text($description_footer) .
|
||||
'</footer>';
|
||||
}
|
||||
|
||||
return $converter->convertToHtml($this->attributes['description']);
|
||||
return $converter->text($this->attributes['description']);
|
||||
}
|
||||
}
|
||||
|
@ -10,16 +10,18 @@ namespace App\Entities;
|
||||
use App\Models\EpisodeModel;
|
||||
use CodeIgniter\Entity;
|
||||
use Myth\Auth\Models\UserModel;
|
||||
use Parsedown;
|
||||
|
||||
class Podcast extends Entity
|
||||
{
|
||||
protected $link;
|
||||
protected string $link;
|
||||
protected \CodeIgniter\Files\File $image;
|
||||
protected $image_media_path;
|
||||
protected $image_url;
|
||||
protected string $image_media_path;
|
||||
protected string $image_url;
|
||||
protected $episodes;
|
||||
protected $owner;
|
||||
protected \Myth\Auth\Entities\User $owner;
|
||||
protected $contributors;
|
||||
protected string $description_html;
|
||||
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
@ -132,6 +134,11 @@ class Podcast extends Entity
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all podcast contributors
|
||||
*
|
||||
* @return \Myth\Auth\Entities\User[]
|
||||
*/
|
||||
public function getContributors()
|
||||
{
|
||||
return (new UserModel())
|
||||
@ -140,4 +147,12 @@ class Podcast extends Entity
|
||||
->where('users_podcasts.podcast_id', $this->attributes['id'])
|
||||
->findAll();
|
||||
}
|
||||
|
||||
public function getDescriptionHtml()
|
||||
{
|
||||
$converter = new Parsedown();
|
||||
$converter->setBreaksEnabled(true);
|
||||
|
||||
return $converter->text($this->attributes['description']);
|
||||
}
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ function get_rss_feed($podcast)
|
||||
$channel->addChild('docs', 'https://cyber.harvard.edu/rss/rss.html');
|
||||
|
||||
$channel->addChild('title', $podcast->title);
|
||||
$channel->addChildWithCDATA('description', $podcast->description);
|
||||
$channel->addChildWithCDATA('description', $podcast->description_html);
|
||||
$itunes_image = $channel->addChild('image', null, $itunes_namespace);
|
||||
$itunes_image->addAttribute('href', $podcast->image_url);
|
||||
$channel->addChild('language', $podcast->language);
|
||||
@ -124,7 +124,7 @@ function get_rss_feed($podcast)
|
||||
|
||||
$item->addChild('guid', $episode->guid);
|
||||
$item->addChild('pubDate', $episode->pub_date->format(DATE_RFC1123));
|
||||
$item->addChildWithCDATA('description', $episode->description);
|
||||
$item->addChildWithCDATA('description', $episode->description_html);
|
||||
$item->addChild(
|
||||
'duration',
|
||||
$enclosure_metadata['playtime_seconds'],
|
||||
|
@ -1 +0,0 @@
|
||||
console.log("main");
|
@ -1,56 +0,0 @@
|
||||
import { createPopper } from "@popperjs/core";
|
||||
|
||||
const Dropdown = () => {
|
||||
const dropdownContainers = document.querySelectorAll(
|
||||
"[data-toggle='dropdown']"
|
||||
);
|
||||
|
||||
for (let i = 0; i < dropdownContainers.length; i++) {
|
||||
const dropdownContainer = dropdownContainers[i];
|
||||
|
||||
const button = dropdownContainer.querySelector("[data-popper='button']");
|
||||
const menu = dropdownContainer.querySelector("[data-popper='menu']");
|
||||
|
||||
const popper = createPopper(button, menu, {
|
||||
placement: menu.dataset.popperPlacement,
|
||||
modifiers: [
|
||||
{
|
||||
name: "offset",
|
||||
options: {
|
||||
offset: [menu.dataset.popperOffsetX, menu.dataset.popperOffsetY],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const dropdownToggle = () => {
|
||||
const isExpanded = !menu.classList.contains("hidden");
|
||||
|
||||
if (isExpanded) {
|
||||
menu.classList.add("hidden");
|
||||
menu.classList.remove("flex");
|
||||
} else {
|
||||
menu.classList.add("flex");
|
||||
menu.classList.remove("hidden");
|
||||
}
|
||||
|
||||
button.setAttribute("aria-expanded", isExpanded);
|
||||
popper.update();
|
||||
};
|
||||
|
||||
// Toggle dropdown menu on button click event
|
||||
button.addEventListener("click", dropdownToggle);
|
||||
|
||||
// Toggle off when clicking outside of dropdown
|
||||
document.addEventListener("click", function (event) {
|
||||
const isExpanded = !menu.classList.contains("hidden");
|
||||
const isClickOutside = !dropdownContainer.contains(event.target);
|
||||
|
||||
if (isExpanded && isClickOutside) {
|
||||
dropdownToggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export default Dropdown;
|
64
app/Views/_assets/modules/Dropdown.ts
Normal file
64
app/Views/_assets/modules/Dropdown.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { createPopper, Placement } from "@popperjs/core";
|
||||
|
||||
const Dropdown = (): void => {
|
||||
const dropdownContainers: NodeListOf<HTMLElement> = document.querySelectorAll(
|
||||
"[data-toggle='dropdown']"
|
||||
);
|
||||
|
||||
for (let i = 0; i < dropdownContainers.length; i++) {
|
||||
const dropdownContainer = dropdownContainers[i];
|
||||
|
||||
const button: HTMLElement | null = dropdownContainer.querySelector(
|
||||
"[data-popper='button']"
|
||||
);
|
||||
const menu: HTMLElement | null = dropdownContainer.querySelector(
|
||||
"[data-popper='menu']"
|
||||
);
|
||||
|
||||
if (button && menu) {
|
||||
const popper = createPopper(button, menu, {
|
||||
placement: menu.dataset.popperPlacement as Placement,
|
||||
modifiers: [
|
||||
{
|
||||
name: "offset",
|
||||
options: {
|
||||
offset: [menu.dataset.popperOffsetX, menu.dataset.popperOffsetY],
|
||||
},
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const dropdownToggle = () => {
|
||||
const isExpanded = !menu.classList.contains("hidden");
|
||||
|
||||
if (isExpanded) {
|
||||
menu.classList.add("hidden");
|
||||
menu.classList.remove("flex");
|
||||
} else {
|
||||
menu.classList.add("flex");
|
||||
menu.classList.remove("hidden");
|
||||
}
|
||||
|
||||
button.setAttribute("aria-expanded", isExpanded.toString());
|
||||
popper.update();
|
||||
};
|
||||
|
||||
// Toggle dropdown menu on button click event
|
||||
button.addEventListener("click", dropdownToggle);
|
||||
|
||||
// Toggle off when clicking outside of dropdown
|
||||
document.addEventListener("click", function (event) {
|
||||
const isExpanded = !menu.classList.contains("hidden");
|
||||
const isClickOutside = !dropdownContainer.contains(
|
||||
event.target as Node
|
||||
);
|
||||
|
||||
if (isExpanded && isClickOutside) {
|
||||
dropdownToggle();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default Dropdown;
|
@ -1,8 +1,8 @@
|
||||
import CodeMirror from "codemirror";
|
||||
import "codemirror/lib/codemirror.css";
|
||||
|
||||
const HTMLEditor = () => {
|
||||
const allHTMLEditors = document.querySelectorAll(
|
||||
const HTMLEditor = (): void => {
|
||||
const allHTMLEditors: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll(
|
||||
"textarea[data-editor='html']"
|
||||
);
|
||||
|
@ -11,7 +11,9 @@ import { EditorView } from "prosemirror-view";
|
||||
import "prosemirror-view/style/prosemirror.css";
|
||||
|
||||
class MarkdownView {
|
||||
constructor(target) {
|
||||
textarea: HTMLTextAreaElement;
|
||||
|
||||
constructor(target: HTMLTextAreaElement) {
|
||||
this.textarea = target;
|
||||
this.textarea.classList.add("w-full", "h-full");
|
||||
}
|
||||
@ -31,16 +33,20 @@ class MarkdownView {
|
||||
}
|
||||
|
||||
class ProseMirrorView {
|
||||
constructor(target, content) {
|
||||
editorContainer: HTMLDivElement;
|
||||
view: EditorView;
|
||||
|
||||
constructor(target: HTMLTextAreaElement, content: string) {
|
||||
this.editorContainer = document.createElement("div");
|
||||
this.editorContainer.classList.add(
|
||||
"bg-white",
|
||||
"border",
|
||||
"px-2",
|
||||
"min-h-full"
|
||||
"min-h-full",
|
||||
"prose-sm"
|
||||
);
|
||||
this.editorContainer.style.minHeight = "200px";
|
||||
const editor = target.parentNode.insertBefore(
|
||||
const editor = target.parentNode?.insertBefore(
|
||||
this.editorContainer,
|
||||
target.nextSibling
|
||||
);
|
||||
@ -51,7 +57,7 @@ class ProseMirrorView {
|
||||
plugins: exampleSetup({ schema }),
|
||||
}),
|
||||
dispatchTransaction: (transaction) => {
|
||||
let newState = this.view.state.apply(transaction);
|
||||
const newState = this.view.state.apply(transaction);
|
||||
this.view.updateState(newState);
|
||||
|
||||
if (transaction.docChanged) {
|
||||
@ -75,16 +81,18 @@ class ProseMirrorView {
|
||||
}
|
||||
}
|
||||
|
||||
const MarkdownEditor = () => {
|
||||
const targets = document.querySelectorAll("textarea[data-editor='markdown']");
|
||||
const activeClass = ["font-bold"];
|
||||
const MarkdownEditor = (): void => {
|
||||
const targets: NodeListOf<HTMLTextAreaElement> = document.querySelectorAll(
|
||||
"textarea[data-editor='markdown']"
|
||||
);
|
||||
const activeClass = "font-bold";
|
||||
|
||||
for (let i = 0; i < targets.length; i++) {
|
||||
const target = targets[i];
|
||||
|
||||
const wysiwygBtn = document.createElement("button");
|
||||
wysiwygBtn.classList.add(
|
||||
...activeClass,
|
||||
activeClass,
|
||||
"py-1",
|
||||
"px-2",
|
||||
"bg-white",
|
||||
@ -112,7 +120,7 @@ const MarkdownEditor = () => {
|
||||
const markdownEditorContainer = document.createElement("div");
|
||||
markdownEditorContainer.classList.add("relative");
|
||||
markdownEditorContainer.style.minHeight = "200px";
|
||||
target.parentNode.appendChild(markdownEditorContainer);
|
||||
target.parentNode?.appendChild(markdownEditorContainer);
|
||||
markdownEditorContainer.appendChild(target);
|
||||
|
||||
// show WYSIWYG editor by default
|
||||
@ -123,17 +131,17 @@ const MarkdownEditor = () => {
|
||||
markdownEditorContainer.appendChild(viewButtons);
|
||||
|
||||
markdownBtn.addEventListener("click", () => {
|
||||
if (markdownBtn.classList.contains(...activeClass)) return;
|
||||
markdownBtn.classList.add(...activeClass);
|
||||
wysiwygBtn.classList.remove(...activeClass);
|
||||
if (markdownBtn.classList.contains(activeClass)) return;
|
||||
markdownBtn.classList.add(activeClass);
|
||||
wysiwygBtn.classList.remove(activeClass);
|
||||
wysiwygView.hide();
|
||||
markdownView.show();
|
||||
});
|
||||
|
||||
wysiwygBtn.addEventListener("click", () => {
|
||||
if (wysiwygBtn.classList.contains(...activeClass)) return;
|
||||
wysiwygBtn.classList.add(...activeClass);
|
||||
markdownBtn.classList.remove(...activeClass);
|
||||
if (wysiwygBtn.classList.contains(activeClass)) return;
|
||||
wysiwygBtn.classList.add(activeClass);
|
||||
markdownBtn.classList.remove(activeClass);
|
||||
markdownView.hide();
|
||||
wysiwygView.show();
|
||||
});
|
@ -1,12 +1,12 @@
|
||||
// Original code from: https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1
|
||||
const slugify = (string) => {
|
||||
const slugify = (text: string) => {
|
||||
const a =
|
||||
"àáâäæãåāăąçćčđďèéêëēėęěğǵḧîïíīįìłḿñńǹňôöòóœøōõőṕŕřßśšşșťțûüùúūǘůűųẃẍÿýžźż·/_,:;";
|
||||
const b =
|
||||
"aaaaaaaaaacccddeeeeeeeegghiiiiiilmnnnnoooooooooprrsssssttuuuuuuuuuwxyyzzz------";
|
||||
const p = new RegExp(a.split("").join("|"), "g");
|
||||
|
||||
return string
|
||||
return text
|
||||
.toString()
|
||||
.toLowerCase()
|
||||
.replace(/\s+/g, "-") // Replace spaces with -
|
||||
@ -18,9 +18,13 @@ const slugify = (string) => {
|
||||
.replace(/-+$/, ""); // Trim - from end of text
|
||||
};
|
||||
|
||||
const Slugify = () => {
|
||||
const title = document.querySelector("input[data-slugify='title']");
|
||||
const slug = document.querySelector("input[data-slugify='slug']");
|
||||
const Slugify = (): void => {
|
||||
const title: HTMLInputElement | null = document.querySelector(
|
||||
"input[data-slugify='title']"
|
||||
);
|
||||
const slug: HTMLInputElement | null = document.querySelector(
|
||||
"input[data-slugify='slug']"
|
||||
);
|
||||
|
||||
if (title && slug) {
|
||||
title.addEventListener("input", () => {
|
@ -1,7 +1,7 @@
|
||||
import { createPopper } from "@popperjs/core";
|
||||
import { createPopper, Placement } from "@popperjs/core";
|
||||
|
||||
const Tooltip = () => {
|
||||
const tooltipContainers = document.querySelectorAll(
|
||||
const Tooltip = (): void => {
|
||||
const tooltipContainers: NodeListOf<HTMLElement> = document.querySelectorAll(
|
||||
"[data-toggle='tooltip']"
|
||||
);
|
||||
|
||||
@ -18,7 +18,7 @@ const Tooltip = () => {
|
||||
tooltip.innerHTML = tooltipContent;
|
||||
|
||||
const popper = createPopper(tooltipReference, tooltip, {
|
||||
placement: tooltipReference.dataset.placement,
|
||||
placement: tooltipReference.dataset.placement as Placement,
|
||||
modifiers: [
|
||||
{
|
||||
name: "offset",
|
2
app/Views/_assets/typings.d.ts
vendored
Normal file
2
app/Views/_assets/typings.d.ts
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
declare module "prosemirror-markdown";
|
||||
declare module "prosemirror-example-setup";
|
@ -8,6 +8,9 @@
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
||||
<link rel="shortcut icon" type="image/png" href="/favicon.ico" />
|
||||
<link rel="stylesheet" href="/assets/index.css"/>
|
||||
<?php if (isset($podcast)): ?>
|
||||
<?= $podcast->custom_html_head ?>
|
||||
<?php endif; ?>
|
||||
</head>
|
||||
|
||||
<body class="flex flex-col min-h-screen mx-auto">
|
||||
|
@ -11,7 +11,7 @@
|
||||
"whichbrowser/parser": "^2.0",
|
||||
"geoip2/geoip2": "~2.0",
|
||||
"myth/auth": "1.0-beta.2",
|
||||
"league/commonmark": "^1.5"
|
||||
"erusev/parsedown": "^1.7"
|
||||
},
|
||||
"require-dev": {
|
||||
"mikey179/vfsstream": "1.6.*",
|
||||
|
143
composer.lock
generated
143
composer.lock
generated
@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "df18ba9c8ecbb43a37d2a90ebd4316f6",
|
||||
"content-hash": "3656eaed72238d7b46af985ec86f6533",
|
||||
"packages": [
|
||||
{
|
||||
"name": "codeigniter4/framework",
|
||||
@ -116,6 +116,52 @@
|
||||
],
|
||||
"time": "2020-04-08T08:27:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "erusev/parsedown",
|
||||
"version": "1.7.4",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/erusev/parsedown.git",
|
||||
"reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/erusev/parsedown/zipball/cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
|
||||
"reference": "cb17b6477dfff935958ba01325f2e8a2bfa6dab3",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": ">=5.3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8.35"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-0": {
|
||||
"Parsedown": ""
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Emanuil Rusev",
|
||||
"email": "hello@erusev.com",
|
||||
"homepage": "http://erusev.com"
|
||||
}
|
||||
],
|
||||
"description": "Parser for Markdown.",
|
||||
"homepage": "http://parsedown.org",
|
||||
"keywords": [
|
||||
"markdown",
|
||||
"parser"
|
||||
],
|
||||
"time": "2019-12-30T22:54:17+00:00"
|
||||
},
|
||||
{
|
||||
"name": "geoip2/geoip2",
|
||||
"version": "v2.10.0",
|
||||
@ -427,101 +473,6 @@
|
||||
],
|
||||
"time": "2020-05-20T16:45:56+00:00"
|
||||
},
|
||||
{
|
||||
"name": "league/commonmark",
|
||||
"version": "1.5.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/thephpleague/commonmark.git",
|
||||
"reference": "2574454b97e4103dc4e36917bd783b25624aefcd"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/thephpleague/commonmark/zipball/2574454b97e4103dc4e36917bd783b25624aefcd",
|
||||
"reference": "2574454b97e4103dc4e36917bd783b25624aefcd",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"conflict": {
|
||||
"scrutinizer/ocular": "1.7.*"
|
||||
},
|
||||
"require-dev": {
|
||||
"cebe/markdown": "~1.0",
|
||||
"commonmark/commonmark.js": "0.29.1",
|
||||
"erusev/parsedown": "~1.0",
|
||||
"ext-json": "*",
|
||||
"github/gfm": "0.29.0",
|
||||
"michelf/php-markdown": "~1.4",
|
||||
"mikehaertl/php-shellcommand": "^1.4",
|
||||
"phpstan/phpstan": "^0.12",
|
||||
"phpunit/phpunit": "^7.5 || ^8.5 || ^9.2",
|
||||
"scrutinizer/ocular": "^1.5",
|
||||
"symfony/finder": "^4.2"
|
||||
},
|
||||
"bin": [
|
||||
"bin/commonmark"
|
||||
],
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"League\\CommonMark\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"BSD-3-Clause"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Colin O'Dell",
|
||||
"email": "colinodell@gmail.com",
|
||||
"homepage": "https://www.colinodell.com",
|
||||
"role": "Lead Developer"
|
||||
}
|
||||
],
|
||||
"description": "Highly-extensible PHP Markdown parser which fully supports the CommonMark spec and Github-Flavored Markdown (GFM)",
|
||||
"homepage": "https://commonmark.thephpleague.com",
|
||||
"keywords": [
|
||||
"commonmark",
|
||||
"flavored",
|
||||
"gfm",
|
||||
"github",
|
||||
"github-flavored",
|
||||
"markdown",
|
||||
"md",
|
||||
"parser"
|
||||
],
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://enjoy.gitstore.app/repositories/thephpleague/commonmark",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.colinodell.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://www.paypal.me/colinpodell/10.00",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/colinodell",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://www.patreon.com/colinodell",
|
||||
"type": "patreon"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/league/commonmark",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2020-07-19T22:47:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maxmind-db/reader",
|
||||
"version": "v1.6.0",
|
||||
|
@ -60,12 +60,15 @@ docker-compose run --rm composer install --ignore-platform-reqs
|
||||
docker-compose run --rm node npm install
|
||||
```
|
||||
|
||||
6. Build styles using postcss
|
||||
6. Build assets: javascript, styles, icons and svg images
|
||||
|
||||
> To generate the `public/index.css` file, you must run the following command.
|
||||
> To generate public assets, you must run the following commands.
|
||||
|
||||
```bash
|
||||
docker-compose run --rm node npm run build:js
|
||||
docker-compose run --rm node npm run build:css
|
||||
docker-compose run --rm node npm run build:icons
|
||||
docker-compose run --rm node npm run build:svg
|
||||
```
|
||||
|
||||
## Start docker containers
|
||||
|
4175
package-lock.json
generated
4175
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
46
package.json
46
package.json
@ -9,30 +9,47 @@
|
||||
"url": "https://code.podlibre.org/podlibre/castopod.git"
|
||||
},
|
||||
"scripts": {
|
||||
"watch:js": "parcel watch app/Views/_assets/*.js --out-dir public/assets",
|
||||
"build:js": "parcel build app/Views/_assets/*.js --out-dir public/assets",
|
||||
"build": "npm run build:js && cross-env NODE_ENV=production npm run build:css && npm run build:icons && npm run build:svg",
|
||||
"watch:js": "rollup --config --watch",
|
||||
"build:js": "rollup --config",
|
||||
"watch:css": "postcss app/Views/_assets/styles/index.css -o public/assets/index.css -w",
|
||||
"build:css": "postcss app/Views/_assets/styles/index.css -o public/assets/index.css",
|
||||
"build:icons": "svgo -f app/Views/_assets/icons -o public/assets/icons --config=./.svgo.icons.yml",
|
||||
"build:svg": "svgo -f app/Views/_assets/images -o public/assets/images --config=./.svgo.yml",
|
||||
"build": "npm run build:js && cross-env NODE_ENV=production npm run build:css && npm run build:icons && npm run build:svg",
|
||||
"lint": "eslint --ext js,ts app/Views/_assets",
|
||||
"lint:fix": "eslint --ext js,ts app/Views/_assets --fix",
|
||||
"lint:css": "stylelint \"app/Views/_assets/**/*.css\"",
|
||||
"typecheck": "tsc",
|
||||
"commit": "git-cz"
|
||||
},
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.4.4",
|
||||
"codemirror": "^5.55.0",
|
||||
"easymde": "^2.11.0",
|
||||
"prosemirror-example-setup": "^1.1.2",
|
||||
"prosemirror-markdown": "^1.5.0",
|
||||
"prosemirror-state": "^1.3.3",
|
||||
"prosemirror-view": "^1.15.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@babel/core": "^7.10.5",
|
||||
"@babel/plugin-proposal-class-properties": "^7.10.4",
|
||||
"@babel/preset-env": "^7.10.4",
|
||||
"@babel/preset-typescript": "^7.10.4",
|
||||
"@commitlint/cli": "^9.0.1",
|
||||
"@commitlint/config-conventional": "^9.0.1",
|
||||
"@prettier/plugin-php": "^0.14.2",
|
||||
"@rollup/plugin-babel": "^5.1.0",
|
||||
"@rollup/plugin-commonjs": "^14.0.0",
|
||||
"@rollup/plugin-json": "^4.1.0",
|
||||
"@rollup/plugin-multi-entry": "^3.0.1",
|
||||
"@rollup/plugin-node-resolve": "^8.4.0",
|
||||
"@tailwindcss/custom-forms": "^0.2.1",
|
||||
"@tailwindcss/typography": "^0.2.0",
|
||||
"@types/codemirror": "0.0.97",
|
||||
"@types/prosemirror-markdown": "^1.0.3",
|
||||
"@types/prosemirror-view": "^1.15.0",
|
||||
"@typescript-eslint/eslint-plugin": "^3.7.0",
|
||||
"@typescript-eslint/parser": "^3.7.0",
|
||||
"cross-env": "^7.0.2",
|
||||
"cssnano": "^4.1.10",
|
||||
"cz-conventional-changelog": "^3.2.0",
|
||||
@ -41,19 +58,22 @@
|
||||
"eslint-plugin-prettier": "^3.1.4",
|
||||
"husky": "^4.2.5",
|
||||
"lint-staged": "^10.2.11",
|
||||
"parcel-bundler": "^1.12.4",
|
||||
"postcss-cli": "^7.1.1",
|
||||
"postcss-import": "^12.0.1",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"prettier": "2.0.5",
|
||||
"prettier-plugin-organize-imports": "^1.1.1",
|
||||
"rollup": "^2.23.0",
|
||||
"rollup-plugin-multi-input": "^1.1.1",
|
||||
"rollup-plugin-node-polyfills": "^0.2.1",
|
||||
"rollup-plugin-postcss": "^3.1.3",
|
||||
"rollup-plugin-terser": "^6.1.0",
|
||||
"stylelint": "^13.6.1",
|
||||
"stylelint-config-standard": "^20.0.0",
|
||||
"svgo": "^1.3.2",
|
||||
"tailwindcss": "^1.4.6"
|
||||
"tailwindcss": "^1.4.6",
|
||||
"typescript": "^3.9.7"
|
||||
},
|
||||
"browserslist": [
|
||||
">0.2%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"husky": {
|
||||
"hooks": {
|
||||
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS",
|
||||
@ -61,7 +81,9 @@
|
||||
}
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{js,css,md,php}": "prettier --write"
|
||||
"*.{js,ts,css,md,json,php}": "prettier --write",
|
||||
"*.{ts,js}": "eslint --ext js,ts,tsx app/Views/_assets --fix",
|
||||
"*.css": "stylelint --fix"
|
||||
},
|
||||
"config": {
|
||||
"commitizen": {
|
||||
|
44
rollup.config.js
Normal file
44
rollup.config.js
Normal file
@ -0,0 +1,44 @@
|
||||
import babel from "@rollup/plugin-babel";
|
||||
import commonjs from "@rollup/plugin-commonjs";
|
||||
import json from "@rollup/plugin-json";
|
||||
import resolve from "@rollup/plugin-node-resolve";
|
||||
import multiInput from "rollup-plugin-multi-input";
|
||||
import nodePolyfills from "rollup-plugin-node-polyfills";
|
||||
import postcss from "rollup-plugin-postcss";
|
||||
import { terser } from "rollup-plugin-terser";
|
||||
|
||||
const INPUT_DIR = "app/Views/_assets";
|
||||
const OUTPUT_DIR = "public/assets";
|
||||
|
||||
export default {
|
||||
input: [`${INPUT_DIR}/*.ts`, `!${INPUT_DIR}/*.d.ts`],
|
||||
output: {
|
||||
dir: OUTPUT_DIR,
|
||||
format: "esm",
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [
|
||||
multiInput({ relative: INPUT_DIR }),
|
||||
resolve({
|
||||
preferBuiltins: false,
|
||||
extensions: [".js", ".ts"],
|
||||
}),
|
||||
commonjs(),
|
||||
postcss({ extract: true, sourceMap: true, minimize: true }),
|
||||
json(),
|
||||
nodePolyfills(),
|
||||
babel({
|
||||
babelHelpers: "bundled",
|
||||
extensions: [".js", ".ts"],
|
||||
exclude: "node_modules/**",
|
||||
}),
|
||||
terser(),
|
||||
],
|
||||
watch: {
|
||||
chokidar: {
|
||||
usePolling: true,
|
||||
},
|
||||
include: `${INPUT_DIR}/**/*.ts`,
|
||||
exclude: `${INPUT_DIR}/**/*.d.ts`,
|
||||
},
|
||||
};
|
25
tsconfig.json
Normal file
25
tsconfig.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
/* Basic Options */
|
||||
"target": "es5" /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', or 'ESNEXT'. */,
|
||||
"module": "commonjs" /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */,
|
||||
"lib": [
|
||||
"DOM",
|
||||
"DOM.Iterable",
|
||||
"ESNext"
|
||||
] /* Specify library files to be included in the compilation. */,
|
||||
"allowJs": true /* Allow javascript files to be compiled. */,
|
||||
"noEmit": true /* Do not emit outputs. */,
|
||||
|
||||
/* Strict Type-Checking Options */
|
||||
"strict": true /* Enable all strict type-checking options. */,
|
||||
|
||||
/* Module Resolution Options */
|
||||
"baseUrl": "./app/Views/_assets" /* Base directory to resolve non-absolute module names. */,
|
||||
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */,
|
||||
|
||||
/* Advanced Options */
|
||||
"skipLibCheck": true /* Skip type checking of declaration files. */,
|
||||
"forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user