/, '');
+// };
+// };
diff --git a/src/tutorial/utils.ts b/.vitepress/theme/components/Repl/utils.ts
similarity index 100%
rename from src/tutorial/utils.ts
rename to .vitepress/theme/components/Repl/utils.ts
diff --git a/.vitepress/theme/components/ReplLoading.vue b/.vitepress/theme/components/ReplLoading.vue
deleted file mode 100644
index 39233b80..00000000
--- a/.vitepress/theme/components/ReplLoading.vue
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
diff --git a/.vitepress/theme/components/SponsorsAside.vue b/.vitepress/theme/components/SponsorsAside.vue
deleted file mode 100644
index c53f9460..00000000
--- a/.vitepress/theme/components/SponsorsAside.vue
+++ /dev/null
@@ -1,25 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.vitepress/theme/components/SponsorsGroup.vue b/.vitepress/theme/components/SponsorsGroup.vue
deleted file mode 100644
index 75be0cb3..00000000
--- a/.vitepress/theme/components/SponsorsGroup.vue
+++ /dev/null
@@ -1,229 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/.vitepress/theme/components/Testimonials.vue b/.vitepress/theme/components/Testimonials.vue
deleted file mode 100644
index ececc3fb..00000000
--- a/.vitepress/theme/components/Testimonials.vue
+++ /dev/null
@@ -1,209 +0,0 @@
-
-
-
-
-
-
Loved by thousands of product people like you.
-
-
-
-
-
- {{ activeCard === index && showAll ? testimonial.description : showOnly(135, testimonial.description) }}
-
-
-
-
-
-
-
{{ testimonial?.name }}
- @{{ testimonial?.username }}
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/.vitepress/theme/components/VideoDocs.vue b/.vitepress/theme/components/VideoDocs.vue
deleted file mode 100644
index 3dbadb78..00000000
--- a/.vitepress/theme/components/VideoDocs.vue
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
{{ title ?? 'Video Docs' }}
-
{{ description }}
-
-
-
-
-
-
-
-
-
-
diff --git a/.vitepress/theme/components/VueJobs.vue b/.vitepress/theme/components/VueJobs.vue
deleted file mode 100644
index 96568d27..00000000
--- a/.vitepress/theme/components/VueJobs.vue
+++ /dev/null
@@ -1,106 +0,0 @@
-
-
-
-
-
-
-
-
-
diff --git a/.vitepress/theme/components/VueMasteryModal.vue b/.vitepress/theme/components/VueMasteryModal.vue
deleted file mode 100644
index 5e5dfd0a..00000000
--- a/.vitepress/theme/components/VueMasteryModal.vue
+++ /dev/null
@@ -1,158 +0,0 @@
-
-
-
-
-
- Play icon
-
-
-
- Intro to Leaf
-
-
-
-
-
-
-
diff --git a/.vitepress/theme/components/VueSchoolLink.vue b/.vitepress/theme/components/VueSchoolLink.vue
deleted file mode 100644
index fe6bdf7b..00000000
--- a/.vitepress/theme/components/VueSchoolLink.vue
+++ /dev/null
@@ -1,59 +0,0 @@
-
-
-
-
-
diff --git a/.vitepress/theme/components/preferences.ts b/.vitepress/theme/components/preferences.ts
deleted file mode 100644
index eb3e4b32..00000000
--- a/.vitepress/theme/components/preferences.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import { Header } from 'vitepress'
-import { ref } from 'vue'
-
-const hasStorage = typeof localStorage !== 'undefined'
-const get = (key: string, defaultValue = false): boolean =>
- hasStorage
- ? JSON.parse(localStorage.getItem(key) || String(defaultValue))
- : defaultValue
-
-export const preferFunctionalKey = 'vue-docs-prefer-functional'
-export const preferFunctional = ref(get(preferFunctionalKey))
-
-export const preferSFCKey = 'vue-docs-prefer-sfc'
-export const preferSFC = ref(get(preferSFCKey, true))
-
-export function filterHeadersByPreference(h: Header) {
- return preferFunctional.value ? !h.optionsOnly : !h.compositionOnly
-}
diff --git a/.vitepress/theme/components/shared/Banner.vue b/.vitepress/theme/components/shared/Banner.vue
new file mode 100644
index 00000000..822d027c
--- /dev/null
+++ b/.vitepress/theme/components/shared/Banner.vue
@@ -0,0 +1,101 @@
+
+
+
+
+
+ WARNING You're browsing the documentation for an upcoming version of Leaf. The documentation and features of this release are subject to change.
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.vitepress/theme/components/shared/Button.vue b/.vitepress/theme/components/shared/Button.vue
new file mode 100644
index 00000000..233de9f5
--- /dev/null
+++ b/.vitepress/theme/components/shared/Button.vue
@@ -0,0 +1,49 @@
+
+
+
+
+
+
+
diff --git a/.vitepress/theme/components/shared/Card.vue b/.vitepress/theme/components/shared/Card.vue
new file mode 100644
index 00000000..9754a6be
--- /dev/null
+++ b/.vitepress/theme/components/shared/Card.vue
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
diff --git a/.vitepress/theme/components/shared/DataCard.vue b/.vitepress/theme/components/shared/DataCard.vue
new file mode 100644
index 00000000..5eb8f56e
--- /dev/null
+++ b/.vitepress/theme/components/shared/DataCard.vue
@@ -0,0 +1,42 @@
+
+
+
+
+
+
+
+ {{ icon }}
+
+
{{ title }}
+
{{ description }}
+
+
+
diff --git a/.vitepress/theme/components/shared/Select.vue b/.vitepress/theme/components/shared/Select.vue
new file mode 100644
index 00000000..382278a4
--- /dev/null
+++ b/.vitepress/theme/components/shared/Select.vue
@@ -0,0 +1,56 @@
+
+
+
+
+
+
+
+ {{ selectedItem.text }} ({{ currentStepIndex }}/{{ totalSteps }})
+
+
+
+
+
+ {{ item.text }}
+
+
+
+
+
+
+
+
+
diff --git a/.vitepress/theme/components/shared/SponsorCard.vue b/.vitepress/theme/components/shared/SponsorCard.vue
new file mode 100644
index 00000000..73833624
--- /dev/null
+++ b/.vitepress/theme/components/shared/SponsorCard.vue
@@ -0,0 +1,25 @@
+
+
+
+
+
+ {{ name }}
+
+
diff --git a/.vitepress/theme/components/shared/SponsorGroup.vue b/.vitepress/theme/components/shared/SponsorGroup.vue
new file mode 100644
index 00000000..d2f81b56
--- /dev/null
+++ b/.vitepress/theme/components/shared/SponsorGroup.vue
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
diff --git a/.vitepress/theme/components/shared/TypingAnimation.vue b/.vitepress/theme/components/shared/TypingAnimation.vue
new file mode 100644
index 00000000..690df86d
--- /dev/null
+++ b/.vitepress/theme/components/shared/TypingAnimation.vue
@@ -0,0 +1,51 @@
+
+
+
+
+ {{ displayedText ? displayedText : props.text }}
+
+
diff --git a/.vitepress/theme/components/shared/VideoModal.vue b/.vitepress/theme/components/shared/VideoModal.vue
new file mode 100644
index 00000000..804ba173
--- /dev/null
+++ b/.vitepress/theme/components/shared/VideoModal.vue
@@ -0,0 +1,79 @@
+
+
+
+
+
+ Play icon
+
+
+
+
+ {{ buttonText }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.vitepress/theme/index.ts b/.vitepress/theme/index.ts
index 5387e634..70f86b94 100644
--- a/.vitepress/theme/index.ts
+++ b/.vitepress/theme/index.ts
@@ -1,32 +1,22 @@
-import './styles/index.css'
-import { h, App } from 'vue'
-import { VPTheme } from '@leafphp/docs-theme'
-import PreferenceSwitch from './components/PreferenceSwitch.vue'
-import {
- preferFunctional,
- preferSFC,
- filterHeadersByPreference
-} from './components/preferences'
-import SponsorsAside from './components/SponsorsAside.vue'
-import VueSchoolLink from './components/VueSchoolLink.vue'
-// import VueJobs from './components/VueJobs.vue'
-// import Banner from './components/Banner.vue'
+import DefaultTheme from 'vitepress/theme';
+import { VueWriter } from 'vue-writer';
+import { MotionPlugin } from '@vueuse/motion';
-export default Object.assign({}, VPTheme, {
- Layout: () => {
- return h(VPTheme.Layout, null, {
- // banner: () => h('div', {}, [
- // h(Banner),
- // ]),
- 'sidebar-top': () => h(PreferenceSwitch),
- 'aside-mid': () => h(SponsorsAside),
- // 'aside-bottom': () => h(VueJobs)
- })
+import 'virtual:group-icons.css';
+import './styles/index.css';
+import { defineAsyncComponent, h } from 'vue';
+
+/** @type {import('vitepress').Theme} */
+export default {
+ extends: DefaultTheme,
+ enhanceApp({ app }: any) {
+ app.use(MotionPlugin);
+ app.component('vue-writer', VueWriter);
+ },
+ Layout() {
+ return h(DefaultTheme.Layout, null, {
+ // 'layout-top': () =>
+ // h(defineAsyncComponent(() => import('./components/shared/Banner.vue'))),
+ });
},
- enhanceApp({ app }: { app: App }) {
- app.provide('prefer-functional', preferFunctional)
- app.provide('prefer-sfc', preferSFC)
- app.provide('filter-headers', filterHeadersByPreference)
- app.component('VueSchoolLink', VueSchoolLink)
- }
-})
+};
diff --git a/.vitepress/theme/lib/utils.ts b/.vitepress/theme/lib/utils.ts
new file mode 100644
index 00000000..9ad0df42
--- /dev/null
+++ b/.vitepress/theme/lib/utils.ts
@@ -0,0 +1,6 @@
+import { type ClassValue, clsx } from 'clsx';
+import { twMerge } from 'tailwind-merge';
+
+export function cn(...inputs: ClassValue[]) {
+ return twMerge(clsx(inputs));
+}
diff --git a/.vitepress/theme/styles/badges.css b/.vitepress/theme/styles/badges.css
deleted file mode 100644
index df66ff63..00000000
--- a/.vitepress/theme/styles/badges.css
+++ /dev/null
@@ -1,28 +0,0 @@
-.vt-badge.wip:before {
- content: 'WIP';
-}
-
-.vt-badge.ts {
- background-color: #3178c6;
-}
-.vt-badge.ts:before {
- content: 'TS';
-}
-
-.vt-badge.dev-only,
-.vt-badge.experimental {
- color: var(--vt-c-text-light-1);
- background-color: var(--vt-c-yellow);
-}
-
-.vt-badge.dev-only:before {
- content: 'Dev only';
-}
-
-.vt-badge.experimental:before {
- content: 'Experimental';
-}
-
-.vt-badge[data-text]:before {
- content: attr(data-text);
-}
diff --git a/.vitepress/theme/styles/index.css b/.vitepress/theme/styles/index.css
index 26324134..8641c93a 100644
--- a/.vitepress/theme/styles/index.css
+++ b/.vitepress/theme/styles/index.css
@@ -1,6 +1,148 @@
-@import "./pages.css";
-@import "./badges.css";
-@import "./options-boxes.css";
-@import "./inline-demo.css";
-@import "./utilities.css";
-@import "./style-guide.css";
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+
+:root {
+ --vp-home-hero-image-filter: blur(94px);
+ --vp-home-hero-name-color: transparent;
+ --vp-home-hero-image-background-image: linear-gradient(
+ -45deg,
+ #3077c6,
+ #3eaf7c
+ );
+ --vp-c-banner: var(--vp-c-brand-1);
+ --vp-home-hero-name-background: #3eaf7c;
+ --vp-c-brand-1: #3eaf7c;
+ --vp-c-brand-2: #07c16b;
+ --vp-button-brand-bg: #3eaf7c;
+ --vp-button-brand-hover-bg: #b07b29;
+ --vp-code-color: #3077c6;
+ --vp-button-brand-alt-bg: #919191;
+ --vp-c-ghost: #476582;
+
+ /* --vp-local-search-bg: var(--vp-c-bg);
+ --vp-local-search-result-bg: var(--vp-c-bg);
+ --vp-local-search-result-border: var(--vp-c-divider);
+ --vp-local-search-result-selected-bg: var(--vp-c-bg);
+ --vp-local-search-result-selected-border: var(--vp-c-brand-1);
+ --vp-local-search-highlight-bg: var(--vp-c-brand-1);
+ --vp-local-search-highlight-text: var(--vp-c-neutral-inverse); */
+
+ --vp-c-border-alt: #eaeaea;
+ --vp-c-border-alt-hovered: #8a8a8a;
+
+ --vp-c-card-bg: #fefefe;
+ --vp-c-card-text-2: #333333;
+}
+
+html.dark {
+ --vp-c-banner: #0e5f3c;
+ --vp-code-color: #3eaf7c;
+ --vp-c-bg: #001e26;
+ --vp-c-bg-alt: #001318;
+ --vp-button-brand-alt-bg: #f1f1f1;
+ --vp-c-ghost: #87a5b2;
+ --vp-c-bg-soft: #002f3b;
+ --vp-c-divider: #2b4a52;
+ --vp-c-bg-elv: var(--vp-c-bg);
+
+ --vp-c-border-alt: #0b2a32;
+ --vp-c-border-alt-hovered: #2b4a52;
+
+ --vp-c-card-bg: #0b2a32;
+ --vp-c-card-text-2: #bebebe;
+}
+
+/* .is-typed {
+ font-family: 'Monaco';
+} */
+
+/* .is-typed span.typed {
+ color: black;
+} */
+
+.is-typed span.cursor {
+ display: inline-block;
+ width: 3px;
+ background-color: black;
+ animation: blink 1s infinite;
+}
+
+.is-typed span.underscore {
+ display: inline-flex;
+ width: 10px;
+ height: 1px;
+ align-items: flex-end;
+ background-color: black;
+ animation: blink 1s infinite;
+}
+
+.is-typed span.cursor.typing {
+ animation: none;
+}
+
+.docs-section-card {
+ @apply !cursor-auto !bg-[var(--vp-c-card-bg)];
+}
+
+.docs-section-card h3 {
+ margin-top: 0 !important;
+}
+
+.docs-section-card ul {
+ @apply rounded-lg list-none pl-0;
+}
+
+.docs-section-card ul li {
+ @apply flex items-start;
+}
+
+.docs-section-card ul li::before {
+ content: url('/images/icons/tiny-arrow.svg');
+ /* fill: var(--vp-c-card-text-2) !important; */
+}
+
+.docs-section-card ul li::before svg {
+ fill: var(--vp-c-card-text-2) !important;
+}
+
+.docs-section-card ul li a {
+ @apply !text-[var(--vp-c-card-text-2)];
+ text-decoration: none;
+}
+
+.VPDocAsideOutline > div {
+ @apply !border-none;
+}
+
+.outline-marker {
+ @apply !rounded !w-1 !left-0;
+}
+
+@keyframes blink {
+ 49% {
+ background-color: black;
+ }
+ 50% {
+ background-color: transparent;
+ }
+ 99% {
+ background-color: transparent;
+ }
+}
+
+.VPContent.is-home + .VPFooter {
+ background-color: var(--vp-c-bg-alt);
+}
+
+.VPSidebar .group, .VPNavBarTitle.has-sidebar a {
+ @apply !border-none;
+}
+
+.VPNavBarTitle.has-sidebar a {
+ @apply !text-lg;
+}
+
+.VPNavBarTitle.has-sidebar img {
+ @apply !w-8 !h-8;
+}
diff --git a/.vitepress/theme/styles/inline-demo.css b/.vitepress/theme/styles/inline-demo.css
deleted file mode 100644
index 02bded84..00000000
--- a/.vitepress/theme/styles/inline-demo.css
+++ /dev/null
@@ -1,90 +0,0 @@
-.vt-doc a[href^="https://sfc.vuejs.org"]:before
-{
- content: '▶';
- width: 20px;
- height: 20px;
- display: inline-block;
- border-radius: 10px;
- vertical-align: middle;
- position: relative;
- top: -2px;
- color: var(--vt-c-green);
- border: 2px solid var(--vt-c-green);
- margin-right: 8px;
- margin-left: 4px;
- line-height: 15px;
- padding-left: 4.5px;
- font-size: 11px;
-}
-
-.demo {
- padding: 22px 24px;
- border-radius: 8px;
- box-shadow: var(--vt-shadow-2);
- margin-bottom: 1.2em;
- transition: background-color 0.5s ease;
-}
-
-.dark .demo {
- background-color: var(--vt-c-bg-soft);
-}
-
-.demo p {
- margin: 0;
-}
-
-.demo button {
- background-color: var(--vt-c-bg-mute);
- transition: background-color 0.5s;
- padding: 5px 12px;
- border: 1px solid var(--vt-c-divider);
- border-radius: 8px;
- font-size: 0.9em;
- font-weight: 600;
-}
-
-.demo button + button {
- margin-left: 1em;
-}
-
-.demo input,
-.demo textarea,
-.demo select {
- border: 1px solid var(--vt-c-divider);
- border-radius: 4px;
- padding: 0.2em 0.6em;
- margin-top: 10px;
- background: transparent;
- transition: background-color 0.5s;
-}
-
-.dark .demo select {
- background: var(--vt-c-bg-soft);
-}
-
-.dark .demo select option {
- background: transparent;
-}
-
-.demo input:not([type]):focus,
-.demo textarea:focus,
-.demo select:focus {
- outline: 1px solid blue;
-}
-
-.demo select {
- /* this was set by normalize.css */
- -webkit-appearance: listbox;
-}
-
-.demo label {
- margin: 0 1em 0 0.4em;
-}
-
-.demo select[multiple] {
- width: 100px;
-}
-
-.demo h1 {
- margin: 10px 0 0;
-}
diff --git a/.vitepress/theme/styles/options-boxes.css b/.vitepress/theme/styles/options-boxes.css
deleted file mode 100644
index 69e62965..00000000
--- a/.vitepress/theme/styles/options-boxes.css
+++ /dev/null
@@ -1,27 +0,0 @@
-.next-steps {
- margin-top: 3rem;
-}
-
-.next-steps .vt-box {
- border: 1px solid var(--vt-c-bg-soft);
-}
-
-.next-steps .vt-box:hover {
- border-color: var(--vt-c-green-light);
- transition: border-color 0.3s cubic-bezier(0.25, 0.8, 0.25, 1);
-}
-
-.vt-doc .next-steps-link {
- font-size: 20px;
- line-height: 1.4;
- letter-spacing: -0.02em;
- margin-bottom: 0.75em;
- display: block;
- color: var(--vt-c-green);
-}
-
-.vt-doc .next-steps-caption {
- margin-bottom: 0;
- color: var(--vt-c-text-2);
- transition: color 0.5s;
-}
diff --git a/.vitepress/theme/styles/pages.css b/.vitepress/theme/styles/pages.css
deleted file mode 100644
index 2d807ec7..00000000
--- a/.vitepress/theme/styles/pages.css
+++ /dev/null
@@ -1,34 +0,0 @@
-/* always show anchors on /api/ and /style-guide/ pages */
-.vt-doc.api h2 .header-anchor,
-.vt-doc.style-guide h2 .header-anchor {
- opacity: 1;
-}
-
-.vt-doc.sponsor h3 {
- text-align: center;
- padding-bottom: 1em;
- border-bottom: 1px solid var(--vt-c-divider-light);
-}
-
-.vt-doc.sponsor h3 .header-anchor {
- display: none;
-}
-
-.vt-grid-list {
- display: grid;
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
- grid-gap: 1rem;
-}
-
-.dark .custom-block [class*='language-'] pre {
- background-color: var(--vt-c-theme-plain);
-}
-
-.dark .custom-block .custom-block {
- background-color: var(--vt-c-theme-plain) !important;
- border-left: none !important;
-}
-
-.details.custom-block::before {
- content: none !important;
-}
diff --git a/.vitepress/theme/styles/style-guide.css b/.vitepress/theme/styles/style-guide.css
deleted file mode 100644
index 0d249c87..00000000
--- a/.vitepress/theme/styles/style-guide.css
+++ /dev/null
@@ -1,65 +0,0 @@
-.style-example {
- border-radius: 8px 8px 12px 12px;
- margin: 1.6em 0;
- padding: 1.6em 1.6em 0.1px;
- position: relative;
- border: 1px solid transparent;
- transition: background-color 0.25s ease, border-color 0.25s ease;
-}
-
-.vt-doc .style-example h3 {
- margin: 0;
- font-size: 1.1em;
-}
-
-.style-example-bad {
- background: #f7e8e8;
-}
-.dark .style-example-bad {
- background: transparent;
- border-color: var(--vt-c-red);
-}
-
-.style-example-bad h3 {
- color: var(--vt-c-red);
-}
-
-.style-example-good {
- background: #ecfaf7;
-}
-.dark .style-example-good {
- background: transparent;
- border-color: var(--vt-c-green);
-}
-
-.style-example-good h3 {
- color: var(--vt-c-green);
-}
-
-.details summary {
- font-weight: bold !important;
-}
-
-.style-verb {
- font-size: 0.6em;
- display: inline-block;
- border-radius: 6px;
- font-size: 0.65em;
- line-height: 1;
- font-weight: 600;
- padding: 0.35em 0.4em 0.3em;
- position: relative;
- top: -0.15em;
- margin-right: 0.5em;
- color: var(--vt-c-bg);
- transition: color 0.5s;
- background-color: var(--vt-c-brand);
-}
-
-.style-verb.avoid {
- background-color: var(--vt-c-red);
-}
-
-div[class~=language-php] .token.variable {
- color: #fff !important;
-}
diff --git a/.vitepress/theme/styles/utilities.css b/.vitepress/theme/styles/utilities.css
deleted file mode 100644
index f9e054b3..00000000
--- a/.vitepress/theme/styles/utilities.css
+++ /dev/null
@@ -1,14 +0,0 @@
-.nowrap {
- white-space: nowrap;
-}
-
-.sr-only {
- position: absolute;
- width: 1px;
- height: 1px;
- padding: 0;
- margin: -1px;
- overflow: hidden;
- clip: rect(0, 0, 0, 0);
- border: 0;
-}
diff --git a/.vitepress/theme/styles/vue-mastery.css b/.vitepress/theme/styles/vue-mastery.css
deleted file mode 100644
index 34f2bd6e..00000000
--- a/.vitepress/theme/styles/vue-mastery.css
+++ /dev/null
@@ -1,65 +0,0 @@
-.vue-mastery-link {
- background-color: var(--vt-c-bg-soft);
- border-radius: 8px;
- padding: 8px 16px 8px 8px;
- transition: color 0.5s, background-color 0.5s;
-}
-
-.vue-mastery-link a {
- display: flex;
- align-items: center;
-}
-
-.vue-mastery-link .banner {
- background-color: var(--vt-c-white-soft);
- border-radius: 4px;
- width:96px;
- height:56px;
- object-fit: cover;
-}
-
-.vue-mastery-link .description {
- flex: 1;
- font-weight: 500;
- font-size: 14px;
- line-height: 20px;
- color: var(--vt-c-text-1);
- margin: 0 0 0 16px;
- transition: color 0.5s;
-}
-
-.vue-mastery-link .description span {
- color: var(--vt-c-brand);
-}
-
-.vue-mastery-link .logo-wrapper {
- position: relative;
- width: 48px;
- height: 48px;
- border-radius: 50%;
- background-color: var(--vt-c-white);
- display: flex;
- justify-content: center;
- align-items: center;
-}
-
-.vue-mastery-link .logo-wrapper img {
- width: 25px;
- object-fit: contain;
-}
-
-@media (max-width: 576px) {
- .vue-mastery-link .banner {
- width:56px;
- }
-
- .vue-mastery-link .description {
- font-size: 12px;
- line-height: 18px;
- }
- .vue-mastery-link .logo-wrapper {
- position: relative;
- width: 32px;
- height: 32px;
- }
-}
diff --git a/LICENSE b/LICENSE
index 55b818a7..26539151 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,6 +1,6 @@
MIT License
-Copyright (c) 2023 Michael Darko-Duodu
+Copyright (c) 2024 Michael Darko-Duodu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -19,11 +19,3 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
-
---------------------------------------------------------------------------------
-Third party licenses are below
---------------------------------------------------------------------------------
-
-Parts of this project's code was based on code from the below repositories:
-
-- LICENSE.VUEJS https://github.com/vuejs/docs
diff --git a/LICENSE.VUEJS b/LICENSE.VUEJS
deleted file mode 100644
index 8944fd0b..00000000
--- a/LICENSE.VUEJS
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2019 vuejs
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/README.md b/README.md
index e35957f6..b0b0c07b 100644
--- a/README.md
+++ b/README.md
@@ -1,20 +1,13 @@
-# Leaf 3
+# Leaf PHP Documentation
-## Contributing
-
-This site is built with [VitePress](https://github.com/vuejs/vitepress) and depends on [@leafphp/docs-theme](https://github.com/leafsphp/leaf-docs-theme). Site content is written in Markdown format located in `src`. For simple edits, you can directly edit the file on GitHub and generate a Pull Request.
+Welcome to the official documentation for Leaf PHP, a PHP framework that helps you build simple yet powerful web applications and APIs. You can find the online version of this documentation at [leafphp.dev](https://beta.leafphp.dev).
-For local development, [pnpm](https://pnpm.io/) is preferred as package manager:
-
-```bash
-pnpm i
-pnpm run dev
-```
+## Contributing
-This project requires Node.js to be `v14.0.0` or higher, because we use new JavaScript features in our code, such as optional chaining.
+If you find any issues with the documentation or have any suggestions, feel free to open an issue or a pull request here. This documentation is built using [VitePress](https://vitepress.dev/), a Vue-powered static site generator. The actual documentation content is written in Markdown and can be found in the `src/` directory.
-## Working on the content
+Be sure to read our [contribution guidelines](https://leafphp.dev/community/contributing/writing-guide.html) before contributing.
-- See VitePress docs on supported [Markdown Extensions](https://vitepress.vuejs.org/guide/markdown.html) and the ability to [use Vue syntax inside markdown](https://vitepress.vuejs.org/guide/using-vue.html).
+## Sponsoring Leaf
-- See the [Writing Guide](http://localhost:3000/community/contributing/writing-guide.html) for our rules and recommendations on writing and maintaining documentation content.
+If you find Leaf useful, consider sponsoring the project on GitHub or [Open Collective](https://opencollective.com/leaf). Your sponsorship helps keep the project alive and maintained and goes a long way in supporting the development of the framework.
diff --git a/components.json b/components.json
new file mode 100644
index 00000000..44fa06b8
--- /dev/null
+++ b/components.json
@@ -0,0 +1,17 @@
+{
+ "$schema": "https://shadcn-vue.com/schema.json",
+ "style": "default",
+ "typescript": true,
+ "tsConfigPath": "./tsconfig.json",
+ "tailwind": {
+ "config": "tailwind.config.ts",
+ "css": ".vitepress/theme/styles/global.css",
+ "baseColor": "slate",
+ "cssVariables": true
+ },
+ "framework": "vite",
+ "aliases": {
+ "components": "./.vitepress/theme/components",
+ "utils": "./.vitepress/theme/lib/utils"
+ }
+}
diff --git a/env.d.ts b/env.d.ts
deleted file mode 100644
index 615c8517..00000000
--- a/env.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-///
-///
-
-declare module '@leafphp/docs-theme/config' {
- import { UserConfig } from 'vitepress'
- const config: () => Promise
- export default config
-}
-
-declare module '@leafphp/docs-theme/highlight' {
- const createHighlighter: () => Promise<(input: string) => string>
- export default createHighlighter
-}
diff --git a/netlify.toml b/netlify.toml
deleted file mode 100644
index 8690fdfe..00000000
--- a/netlify.toml
+++ /dev/null
@@ -1,11 +0,0 @@
-[[redirects]]
- from = "/aloe-cli/"
- to = "/docs/mvc/console"
-
-[build.environment]
- NODE_VERSION = "16"
- NPM_FLAGS = "--version" # prevent Netlify npm install
-
-[build]
- publish = ".vitepress/dist"
- command = "npx pnpm i --store=node_modules/.pnpm-store && npm run build"
diff --git a/package.json b/package.json
index f17a9fb7..a7cebcc9 100644
--- a/package.json
+++ b/package.json
@@ -1,37 +1,39 @@
{
- "engines": {
- "node": ">=14.0.0"
- },
+ "name": "docs",
+ "private": true,
+ "version": "1.0.0",
+ "description": "Documentation for Leaf PHP",
"scripts": {
- "dev": "vitepress",
+ "dev": "vitepress dev",
"build": "vitepress build",
- "serve": "vitepress serve",
+ "preview": "vitepress preview",
"preinstall": "npx only-allow pnpm"
},
"dependencies": {
- "449.css": "^1.3.0",
- "@codemirror/lang-php": "^6.0.0",
- "@leafphp/docs-theme": "0.1.2",
- "@vue/repl": "^1.2.4",
- "axios": "^0.27.2",
- "dynamics.js": "^1.1.5",
- "gsap": "^3.9.0",
- "vitepress": "^0.22.4",
- "vue": "3.2.37"
+ "@headlessui/tailwindcss": "^0.2.1",
+ "@headlessui/vue": "^1.7.22",
+ "@vueuse/core": "^11.1.0",
+ "@vueuse/motion": "^2.2.6",
+ "axios": "^1.7.7",
+ "class-variance-authority": "^0.7.0",
+ "clsx": "^2.1.1",
+ "lucide-vue-next": "^0.438.0",
+ "markdown-it": "^14.1.0",
+ "radix-vue": "^1.9.5",
+ "tailwind-merge": "^2.5.2",
+ "tailwindcss-animate": "^1.0.7",
+ "vitepress": "^1.3.4",
+ "vitepress-plugin-group-icons": "^1.2.4",
+ "vue": "^3.4.38",
+ "vue-writer": "^2.0.2"
},
"devDependencies": {
- "@types/markdown-it": "^12.2.3",
- "@types/node": "^16.9.1"
- },
- "pnpm": {
- "peerDependencyRules": {
- "ignoreMissing": [
- "@algolia/client-search",
- "react",
- "react-dom",
- "@types/react",
- "search-insights"
- ]
- }
+ "@shikijs/markdown-it": "^1.16.1",
+ "@types/markdown-it": "^14.1.2",
+ "@types/node": "^22.5.3",
+ "autoprefixer": "^10.4.20",
+ "postcss": "^8.4.41",
+ "shiki": "^1.16.1",
+ "tailwindcss": "^3.4.10"
}
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 00000000..90248681
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,3598 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@headlessui/tailwindcss':
+ specifier: ^0.2.1
+ version: 0.2.1(tailwindcss@3.4.10)
+ '@headlessui/vue':
+ specifier: ^1.7.22
+ version: 1.7.22(vue@3.5.2)
+ '@vueuse/core':
+ specifier: ^11.1.0
+ version: 11.1.0(vue@3.5.2)
+ '@vueuse/motion':
+ specifier: ^2.2.6
+ version: 2.2.6(rollup@4.21.2)(vue@3.5.2)
+ axios:
+ specifier: ^1.7.7
+ version: 1.7.7
+ class-variance-authority:
+ specifier: ^0.7.0
+ version: 0.7.0
+ clsx:
+ specifier: ^2.1.1
+ version: 2.1.1
+ lucide-vue-next:
+ specifier: ^0.438.0
+ version: 0.438.0(vue@3.5.2)
+ markdown-it:
+ specifier: ^14.1.0
+ version: 14.1.0
+ radix-vue:
+ specifier: ^1.9.5
+ version: 1.9.5(vue@3.5.2)
+ tailwind-merge:
+ specifier: ^2.5.2
+ version: 2.5.2
+ tailwindcss-animate:
+ specifier: ^1.0.7
+ version: 1.0.7(tailwindcss@3.4.10)
+ vitepress:
+ specifier: ^1.3.4
+ version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.4)(axios@1.7.7)(postcss@8.4.45)(search-insights@2.17.1)
+ vitepress-plugin-group-icons:
+ specifier: ^1.2.4
+ version: 1.2.4
+ vue:
+ specifier: ^3.4.38
+ version: 3.5.2
+ vue-writer:
+ specifier: ^2.0.2
+ version: 2.0.2(vue@3.5.2)
+ devDependencies:
+ '@shikijs/markdown-it':
+ specifier: ^1.16.1
+ version: 1.16.2
+ '@types/markdown-it':
+ specifier: ^14.1.2
+ version: 14.1.2
+ '@types/node':
+ specifier: ^22.5.3
+ version: 22.5.4
+ autoprefixer:
+ specifier: ^10.4.20
+ version: 10.4.20(postcss@8.4.45)
+ postcss:
+ specifier: ^8.4.41
+ version: 8.4.45
+ shiki:
+ specifier: ^1.16.1
+ version: 1.16.2
+ tailwindcss:
+ specifier: ^3.4.10
+ version: 3.4.10
+
+packages:
+
+ '@algolia/autocomplete-core@1.9.3':
+ resolution: {integrity: sha512-009HdfugtGCdC4JdXUbVJClA0q0zh24yyePn+KUGk3rP7j8FEe/m5Yo/z65gn6nP/cM39PxpzqKrL7A6fP6PPw==}
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.9.3':
+ resolution: {integrity: sha512-a/yTUkcO/Vyy+JffmAnTWbr4/90cLzw+CC3bRbhnULr/EM0fGNvM13oQQ14f2moLMcVDyAx/leczLlAOovhSZg==}
+ peerDependencies:
+ search-insights: '>= 1 < 3'
+
+ '@algolia/autocomplete-preset-algolia@1.9.3':
+ resolution: {integrity: sha512-d4qlt6YmrLMYy95n5TB52wtNDr6EgAIPH81dvvvW8UmuWRgxEtY0NJiPwl/h95JtG2vmRM804M0DSwMCNZlzRA==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+
+ '@algolia/autocomplete-shared@1.9.3':
+ resolution: {integrity: sha512-Wnm9E4Ye6Rl6sTTqjoymD+l8DjSTHsHboVRYrKgEt8Q7UHm9nYbqhN/i0fhUYA3OAEH7WA8x3jfpnmJm3rKvaQ==}
+ peerDependencies:
+ '@algolia/client-search': '>= 4.9.1 < 6'
+ algoliasearch: '>= 4.9.1 < 6'
+
+ '@algolia/cache-browser-local-storage@4.24.0':
+ resolution: {integrity: sha512-t63W9BnoXVrGy9iYHBgObNXqYXM3tYXCjDSHeNwnsc324r4o5UiVKUiAB4THQ5z9U5hTj6qUvwg/Ez43ZD85ww==}
+
+ '@algolia/cache-common@4.24.0':
+ resolution: {integrity: sha512-emi+v+DmVLpMGhp0V9q9h5CdkURsNmFC+cOS6uK9ndeJm9J4TiqSvPYVu+THUP8P/S08rxf5x2P+p3CfID0Y4g==}
+
+ '@algolia/cache-in-memory@4.24.0':
+ resolution: {integrity: sha512-gDrt2so19jW26jY3/MkFg5mEypFIPbPoXsQGQWAi6TrCPsNOSEYepBMPlucqWigsmEy/prp5ug2jy/N3PVG/8w==}
+
+ '@algolia/client-account@4.24.0':
+ resolution: {integrity: sha512-adcvyJ3KjPZFDybxlqnf+5KgxJtBjwTPTeyG2aOyoJvx0Y8dUQAEOEVOJ/GBxX0WWNbmaSrhDURMhc+QeevDsA==}
+
+ '@algolia/client-analytics@4.24.0':
+ resolution: {integrity: sha512-y8jOZt1OjwWU4N2qr8G4AxXAzaa8DBvyHTWlHzX/7Me1LX8OayfgHexqrsL4vSBcoMmVw2XnVW9MhL+Y2ZDJXg==}
+
+ '@algolia/client-common@4.24.0':
+ resolution: {integrity: sha512-bc2ROsNL6w6rqpl5jj/UywlIYC21TwSSoFHKl01lYirGMW+9Eek6r02Tocg4gZ8HAw3iBvu6XQiM3BEbmEMoiA==}
+
+ '@algolia/client-personalization@4.24.0':
+ resolution: {integrity: sha512-l5FRFm/yngztweU0HdUzz1rC4yoWCFo3IF+dVIVTfEPg906eZg5BOd1k0K6rZx5JzyyoP4LdmOikfkfGsKVE9w==}
+
+ '@algolia/client-search@4.24.0':
+ resolution: {integrity: sha512-uRW6EpNapmLAD0mW47OXqTP8eiIx5F6qN9/x/7HHO6owL3N1IXqydGwW5nhDFBrV+ldouro2W1VX3XlcUXEFCA==}
+
+ '@algolia/logger-common@4.24.0':
+ resolution: {integrity: sha512-LLUNjkahj9KtKYrQhFKCzMx0BY3RnNP4FEtO+sBybCjJ73E8jNdaKJ/Dd8A/VA4imVHP5tADZ8pn5B8Ga/wTMA==}
+
+ '@algolia/logger-console@4.24.0':
+ resolution: {integrity: sha512-X4C8IoHgHfiUROfoRCV+lzSy+LHMgkoEEU1BbKcsfnV0i0S20zyy0NLww9dwVHUWNfPPxdMU+/wKmLGYf96yTg==}
+
+ '@algolia/recommend@4.24.0':
+ resolution: {integrity: sha512-P9kcgerfVBpfYHDfVZDvvdJv0lEoCvzNlOy2nykyt5bK8TyieYyiD0lguIJdRZZYGre03WIAFf14pgE+V+IBlw==}
+
+ '@algolia/requester-browser-xhr@4.24.0':
+ resolution: {integrity: sha512-Z2NxZMb6+nVXSjF13YpjYTdvV3032YTBSGm2vnYvYPA6mMxzM3v5rsCiSspndn9rzIW4Qp1lPHBvuoKJV6jnAA==}
+
+ '@algolia/requester-common@4.24.0':
+ resolution: {integrity: sha512-k3CXJ2OVnvgE3HMwcojpvY6d9kgKMPRxs/kVohrwF5WMr2fnqojnycZkxPoEg+bXm8fi5BBfFmOqgYztRtHsQA==}
+
+ '@algolia/requester-node-http@4.24.0':
+ resolution: {integrity: sha512-JF18yTjNOVYvU/L3UosRcvbPMGT9B+/GQWNWnenIImglzNVGpyzChkXLnrSf6uxwVNO6ESGu6oN8MqcGQcjQJw==}
+
+ '@algolia/transporter@4.24.0':
+ resolution: {integrity: sha512-86nI7w6NzWxd1Zp9q3413dRshDqAzSbsQjhcDhPIatEFiZrL1/TjnHL8S7jVKFePlIMzDsZWXAXwXzcok9c5oA==}
+
+ '@alloc/quick-lru@5.2.0':
+ resolution: {integrity: sha512-UrcABB+4bUrFABwbluTIBErXwvbsU/V7TZWfmbgJfbkwiBuziS9gxdODUyuiecfdGQ85jglMW6juS3+z5TsKLw==}
+ engines: {node: '>=10'}
+
+ '@ampproject/remapping@2.3.0':
+ resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+ engines: {node: '>=6.0.0'}
+
+ '@antfu/install-pkg@0.4.1':
+ resolution: {integrity: sha512-T7yB5QNG29afhWVkVq7XeIMBa5U/vs9mX69YqayXypPRmYzUmzwnYltplHmPtZ4HPCn+sQKeXW8I47wCbuBOjw==}
+
+ '@antfu/utils@0.7.10':
+ resolution: {integrity: sha512-+562v9k4aI80m1+VuMHehNJWLOFjBnXn3tdOitzD0il5b7smkSBal4+a3oKiQTbrwMmN/TBUMDvbdoWDehgOww==}
+
+ '@babel/code-frame@7.26.0':
+ resolution: {integrity: sha512-INCKxTtbXtcNbUZ3YXutwMpEleqttcswhAdee7dhuoVrD2cnuc3PqtERBtxkX5nziX9vnBL8WXmSGwv8CuPV6g==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.26.0':
+ resolution: {integrity: sha512-qETICbZSLe7uXv9VE8T/RWOdIE5qqyTucOt4zLYMafj2MRO271VGgLd4RACJMeBO37UPWhXiKMBk7YlJ0fOzQA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.26.0':
+ resolution: {integrity: sha512-i1SLeK+DzNnQ3LL/CswPCa/E5u4lh1k6IAEphON8F+cXt0t9euTshDru0q7/IqMa1PMPz5RnHuHscF8/ZJsStg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.26.0':
+ resolution: {integrity: sha512-/AIkAmInnWwgEAJGQr9vY0c66Mj6kjkE2ZPB1PurTRaRAh3U+J45sAQMjQDJdh4WbR3l0x5xkimXBKyBXXAu2w==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.25.9':
+ resolution: {integrity: sha512-j9Db8Suy6yV/VHa4qzrj9yZfZxhLWQdVnRlXxmKLYlhWUVB1sB2G5sxuWYXk/whHD9iW76PmNzxZ4UCnTQTVEQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.25.9':
+ resolution: {integrity: sha512-tnUA4RsrmflIM6W6RFTLFSXITtl0wKjgpnLgXyowocVPrbYrLUXSBXDgTs8BlbmIzIdlBySRQjINYs2BAkiLtw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.26.0':
+ resolution: {integrity: sha512-xO+xu6B5K2czEnQye6BHA7DolFFmS3LB7stHZFaOLb1pAwO1HWLS8fXA+eh0A2yIvltPVmx3eNNDBJA2SLHXFw==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-string-parser@7.24.8':
+ resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.25.9':
+ resolution: {integrity: sha512-4A/SCr/2KLd5jrtOMFzaKjVtAei3+2r/NChoBNoZ3EyP/+GlhoaEGoWOZUmFmoITP7zOJyHIMm+DYRd8o3PvHA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.24.7':
+ resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.25.9':
+ resolution: {integrity: sha512-Ed61U6XJc3CVRfkERJWDz4dJwKe7iLmmJsbOGu9wSloNSFttHV0I8g6UAgb7qnK5ly5bGLPd4oXZlxCdANBOWQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.25.9':
+ resolution: {integrity: sha512-e/zv1co8pp55dNdEcCynfj9X7nyUKUXoUEwfXqaZt0omVOmDe9oOTdKStH4GmAw6zxMFs50ZayuMfHDKlO7Tfw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.26.0':
+ resolution: {integrity: sha512-tbhNuIxNcVb21pInl3ZSjksLCvgdZy9KwJ8brv993QtIVKJBBkYXz4q4ZbAv31GdnC+R90np23L5FbEBlthAEw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.25.6':
+ resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/parser@7.26.1':
+ resolution: {integrity: sha512-reoQYNiAJreZNsJzyrDNzFQ+IQ5JFiIzAHJg9bn94S3l+4++J7RsIhNMoB+lgP/9tpmiAQqspv+xfdxTSzREOw==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/standalone@7.26.1':
+ resolution: {integrity: sha512-DAC3Vv62IA9VcMMAsTm5UzuEmsVjYkR5A9BX9zJrrrPHCQYJIp38jMHHx17RC4KwruwiIAb5hLFZLmE+wZgiyQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/template@7.25.9':
+ resolution: {integrity: sha512-9DGttpmPvIxBb/2uwpVo3dqJ+O6RooAFOS+lB+xDqoE2PVCE8nfoHMdZLpfCQRLwvohzXISPZcgxt80xLfsuwg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.25.9':
+ resolution: {integrity: sha512-ZCuvfwOwlz/bawvAuvcj8rrithP2/N55Tzz342AkTvq4qaWbGfmCk/tKhNaV2cthijKrPAA8SRJV5WWe7IBMJw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.25.6':
+ resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.26.0':
+ resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==}
+ engines: {node: '>=6.9.0'}
+
+ '@docsearch/css@3.6.1':
+ resolution: {integrity: sha512-VtVb5DS+0hRIprU2CO6ZQjK2Zg4QU5HrDM1+ix6rT0umsYvFvatMAnf97NHZlVWDaaLlx7GRfR/7FikANiM2Fg==}
+
+ '@docsearch/js@3.6.1':
+ resolution: {integrity: sha512-erI3RRZurDr1xES5hvYJ3Imp7jtrXj6f1xYIzDzxiS7nNBufYWPbJwrmMqWC5g9y165PmxEmN9pklGCdLi0Iqg==}
+
+ '@docsearch/react@3.6.1':
+ resolution: {integrity: sha512-qXZkEPvybVhSXj0K7U3bXc233tk5e8PfhoZ6MhPOiik/qUQxYC+Dn9DnoS7CxHQQhHfCvTiN0eY9M12oRghEXw==}
+ peerDependencies:
+ '@types/react': '>= 16.8.0 < 19.0.0'
+ react: '>= 16.8.0 < 19.0.0'
+ react-dom: '>= 16.8.0 < 19.0.0'
+ search-insights: '>= 1 < 3'
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ react:
+ optional: true
+ react-dom:
+ optional: true
+ search-insights:
+ optional: true
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@floating-ui/core@1.6.7':
+ resolution: {integrity: sha512-yDzVT/Lm101nQ5TCVeK65LtdN7Tj4Qpr9RTXJ2vPFLqtLxwOrpoxAHAJI8J3yYWUc40J0BDBheaitK5SJmno2g==}
+
+ '@floating-ui/dom@1.6.10':
+ resolution: {integrity: sha512-fskgCFv8J8OamCmyun8MfjB1Olfn+uZKjOKZ0vhYF3gRmEUXcGOjxWL8bBr7i4kIuPZ2KD2S3EUIOxnjC8kl2A==}
+
+ '@floating-ui/utils@0.2.7':
+ resolution: {integrity: sha512-X8R8Oj771YRl/w+c1HqAC1szL8zWQRwFvgDwT129k9ACdBoud/+/rX9V0qiMl6LWUdP9voC2nDVZYPMQQsb6eA==}
+
+ '@floating-ui/vue@1.1.4':
+ resolution: {integrity: sha512-ammH7T3vyCx7pmm9OF19Wc42zrGnUw0QvLoidgypWsCLJMtGXEwY7paYIHO+K+oLC3mbWpzIHzeTVienYenlNg==}
+
+ '@headlessui/tailwindcss@0.2.1':
+ resolution: {integrity: sha512-2+5+NZ+RzMyrVeCZOxdbvkUSssSxGvcUxphkIfSVLpRiKsj+/63T2TOL9dBYMXVfj/CGr6hMxSRInzXv6YY7sA==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ tailwindcss: ^3.0
+
+ '@headlessui/vue@1.7.22':
+ resolution: {integrity: sha512-Hoffjoolq1rY+LOfJ+B/OvkhuBXXBFgd8oBlN+l1TApma2dB0En0ucFZrwQtb33SmcCqd32EQd0y07oziXWNYg==}
+ engines: {node: '>=10'}
+ peerDependencies:
+ vue: ^3.2.0
+
+ '@iconify-json/logos@1.2.3':
+ resolution: {integrity: sha512-JLHS5hgZP1b55EONAWNeqBUuriRfRNKWXK4cqYx0PpVaJfIIMiiMxFfvoQiX/bkE9XgkLhcKmDUqL3LXPdXPwQ==}
+
+ '@iconify-json/vscode-icons@1.2.2':
+ resolution: {integrity: sha512-bTpT0HJDRqGkxQv8oiETNHLEnBZpnA1QaRD35CQyO7M7qgWVLx2xwn/lK6e4waojmlPC3ckMBx3WFIUUn0/Jdg==}
+
+ '@iconify/types@2.0.0':
+ resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
+
+ '@iconify/utils@2.1.33':
+ resolution: {integrity: sha512-jP9h6v/g0BIZx0p7XGJJVtkVnydtbgTgt9mVNcGDYwaa7UhdHdI9dvoq+gKj9sijMSJKxUPEG2JyjsgXjxL7Kw==}
+
+ '@internationalized/date@3.5.5':
+ resolution: {integrity: sha512-H+CfYvOZ0LTJeeLOqm19E3uj/4YjrmOFtBufDHPfvtI80hFAMqtrp7oCACpe4Cil5l8S0Qu/9dYfZc/5lY8WQQ==}
+
+ '@internationalized/number@3.5.3':
+ resolution: {integrity: sha512-rd1wA3ebzlp0Mehj5YTuTI50AQEx80gWFyHcQu+u91/5NgdwBecO8BH6ipPfE+lmQ9d63vpB3H9SHoIUiupllw==}
+
+ '@isaacs/cliui@8.0.2':
+ resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==}
+ engines: {node: '>=12'}
+
+ '@jridgewell/gen-mapping@0.3.5':
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@nuxt/kit@3.13.2':
+ resolution: {integrity: sha512-KvRw21zU//wdz25IeE1E5m/aFSzhJloBRAQtv+evcFeZvuroIxpIQuUqhbzuwznaUwpiWbmwlcsp5uOWmi4vwA==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ '@nuxt/schema@3.13.2':
+ resolution: {integrity: sha512-CCZgpm+MkqtOMDEgF9SWgGPBXlQ01hV/6+2reDEpJuqFPGzV8HYKPBcIFvn7/z5ahtgutHLzjP71Na+hYcqSpw==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ '@pkgjs/parseargs@0.11.0':
+ resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
+ engines: {node: '>=14'}
+
+ '@rollup/pluginutils@5.1.3':
+ resolution: {integrity: sha512-Pnsb6f32CD2W3uCaLZIzDmeFyQ2b8UWMFI7xtwUezpcGBDVDW6y9XgAWIlARiGAo6eNF5FK5aQTr0LFyNyqq5A==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.21.2':
+ resolution: {integrity: sha512-fSuPrt0ZO8uXeS+xP3b+yYTCBUd05MoSp2N/MFOgjhhUhMmchXlpTQrTpI8T+YAwAQuK7MafsCOxW7VrPMrJcg==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.21.2':
+ resolution: {integrity: sha512-xGU5ZQmPlsjQS6tzTTGwMsnKUtu0WVbl0hYpTPauvbRAnmIvpInhJtgjj3mcuJpEiuUw4v1s4BimkdfDWlh7gA==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.21.2':
+ resolution: {integrity: sha512-99AhQ3/ZMxU7jw34Sq8brzXqWH/bMnf7ZVhvLk9QU2cOepbQSVTns6qoErJmSiAvU3InRqC2RRZ5ovh1KN0d0Q==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.21.2':
+ resolution: {integrity: sha512-ZbRaUvw2iN/y37x6dY50D8m2BnDbBjlnMPotDi/qITMJ4sIxNY33HArjikDyakhSv0+ybdUxhWxE6kTI4oX26w==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.21.2':
+ resolution: {integrity: sha512-ztRJJMiE8nnU1YFcdbd9BcH6bGWG1z+jP+IPW2oDUAPxPjo9dverIOyXz76m6IPA6udEL12reYeLojzW2cYL7w==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.21.2':
+ resolution: {integrity: sha512-flOcGHDZajGKYpLV0JNc0VFH361M7rnV1ee+NTeC/BQQ1/0pllYcFmxpagltANYt8FYf9+kL6RSk80Ziwyhr7w==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.21.2':
+ resolution: {integrity: sha512-69CF19Kp3TdMopyteO/LJbWufOzqqXzkrv4L2sP8kfMaAQ6iwky7NoXTp7bD6/irKgknDKM0P9E/1l5XxVQAhw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.21.2':
+ resolution: {integrity: sha512-48pD/fJkTiHAZTnZwR0VzHrao70/4MlzJrq0ZsILjLW/Ab/1XlVUStYyGt7tdyIiVSlGZbnliqmult/QGA2O2w==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.21.2':
+ resolution: {integrity: sha512-cZdyuInj0ofc7mAQpKcPR2a2iu4YM4FQfuUzCVA2u4HI95lCwzjoPtdWjdpDKyHxI0UO82bLDoOaLfpZ/wviyQ==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.21.2':
+ resolution: {integrity: sha512-RL56JMT6NwQ0lXIQmMIWr1SW28z4E4pOhRRNqwWZeXpRlykRIlEpSWdsgNWJbYBEWD84eocjSGDu/XxbYeCmwg==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.21.2':
+ resolution: {integrity: sha512-PMxkrWS9z38bCr3rWvDFVGD6sFeZJw4iQlhrup7ReGmfn7Oukrr/zweLhYX6v2/8J6Cep9IEA/SmjXjCmSbrMQ==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.21.2':
+ resolution: {integrity: sha512-B90tYAUoLhU22olrafY3JQCFLnT3NglazdwkHyxNDYF/zAxJt5fJUB/yBoWFoIQ7SQj+KLe3iL4BhOMa9fzgpw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.21.2':
+ resolution: {integrity: sha512-7twFizNXudESmC9oneLGIUmoHiiLppz/Xs5uJQ4ShvE6234K0VB1/aJYU3f/4g7PhssLGKBVCC37uRkkOi8wjg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.21.2':
+ resolution: {integrity: sha512-9rRero0E7qTeYf6+rFh3AErTNU1VCQg2mn7CQcI44vNUWM9Ze7MSRS/9RFuSsox+vstRt97+x3sOhEey024FRQ==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.21.2':
+ resolution: {integrity: sha512-5rA4vjlqgrpbFVVHX3qkrCo/fZTj1q0Xxpg+Z7yIo3J2AilW7t2+n6Q8Jrx+4MrYpAnjttTYF8rr7bP46BPzRw==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.21.2':
+ resolution: {integrity: sha512-6UUxd0+SKomjdzuAcp+HAmxw1FlGBnl1v2yEPSabtx4lBfdXHDVsW7+lQkgz9cNFJGY3AWR7+V8P5BqkD9L9nA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@shikijs/core@1.16.2':
+ resolution: {integrity: sha512-XSVH5OZCvE4WLMgdoBqfPMYmGHGmCC3OgZhw0S7KcSi2XKZ+5oHGe71GFnTljgdOxvxx5WrRks6QoTLKrl1eAA==}
+
+ '@shikijs/markdown-it@1.16.2':
+ resolution: {integrity: sha512-GSddEuOaVMHOmfWc3MYyf59WS7VTXwTfsDYmM2iVBe8N4yhA9bCBUkGXYKfod7hclFI2kLiz7BqaGTzsDEXUEw==}
+
+ '@shikijs/transformers@1.16.2':
+ resolution: {integrity: sha512-AR6ANiKwi1dJr5g/W0L+Su4PoHurkHLgtNmesbOFOPGKNQC2BeGU/Z2Ghkl+cUF5PfE+UeLkxUwzpE6H37hTSg==}
+
+ '@shikijs/vscode-textmate@9.2.0':
+ resolution: {integrity: sha512-5FinaOp6Vdh/dl4/yaOTh0ZeKch+rYS8DUb38V3GMKYVkdqzxw53lViRKUYkVILRiVQT7dcPC7VvAKOR73zVtQ==}
+
+ '@sindresorhus/merge-streams@2.3.0':
+ resolution: {integrity: sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==}
+ engines: {node: '>=18'}
+
+ '@swc/helpers@0.5.13':
+ resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==}
+
+ '@tanstack/virtual-core@3.10.7':
+ resolution: {integrity: sha512-ND5dfsU0n9F4gROzwNNDJmg6y8n9pI8YWxtgbfJ5UcNn7Hx+MxEXtXcQ189tS7sh8pmCObgz2qSiyRKTZxT4dg==}
+
+ '@tanstack/vue-virtual@3.10.7':
+ resolution: {integrity: sha512-OSK1fkvz4GaBhF80KVmBsJZoMI9ncVaUU//pI8OqTdBnepw467zcuF2Y+Ia1VC0CPYfUEALyS8n4Ar0RI/7ASg==}
+ peerDependencies:
+ vue: ^2.7.0 || ^3.0.0
+
+ '@types/estree@1.0.5':
+ resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/linkify-it@5.0.0':
+ resolution: {integrity: sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==}
+
+ '@types/markdown-it@14.1.2':
+ resolution: {integrity: sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==}
+
+ '@types/mdurl@2.0.0':
+ resolution: {integrity: sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==}
+
+ '@types/node@22.5.4':
+ resolution: {integrity: sha512-FDuKUJQm/ju9fT/SeX/6+gBzoPzlVCzfzmGkwKvRHQVxi4BntVbyIwf6a4Xn62mrvndLiml6z/UBXIdEVjQLXg==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@types/web-bluetooth@0.0.20':
+ resolution: {integrity: sha512-g9gZnnXVq7gM7v3tJCWV/qw7w+KeOlSHAhgF9RytFyifW6AF61hdT2ucrYhPq9hLs5JIryeupHV3qGk95dH9ow==}
+
+ '@vitejs/plugin-vue@5.1.3':
+ resolution: {integrity: sha512-3xbWsKEKXYlmX82aOHufFQVnkbMC/v8fLpWwh6hWOUrK5fbbtBh9Q/WWse27BFgSy2/e2c0fz5Scgya9h2GLhw==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ peerDependencies:
+ vite: ^5.0.0
+ vue: ^3.2.25
+
+ '@vue/compiler-core@3.5.2':
+ resolution: {integrity: sha512-1aP7FL2GkqfcskHWGg3lfWQpJnrmewKc+rNJ/hq9WNaAw4BEyJ5QbNChnqmbw+tJ409zdy1XWmUeXXMrCKJcQQ==}
+
+ '@vue/compiler-dom@3.5.2':
+ resolution: {integrity: sha512-QY4DpT8ZIUyu/ZA5gErpSEDocGNEbHmpkZIC/d5jbp/rUF0iOJNigAy3HCCKc0PMMhDlrcysO3ufQ6Ab4MpEcQ==}
+
+ '@vue/compiler-sfc@3.5.2':
+ resolution: {integrity: sha512-vErEtybSU290LbMW+ChYllI9tNJEdTW1oU+8cZWINZyjlWeTSa9YqDl4/pZJSnozOI+HmcaC1Vz2eFKmXNSXZA==}
+
+ '@vue/compiler-ssr@3.5.2':
+ resolution: {integrity: sha512-vMtA4tQK/AM3UAYJsmouQzQpgG+h9TKiD5BV+Zt+ZyAMdicxzSEEFGWf/CykRnDpqj9fMfIHPhOezJVNxiXe2A==}
+
+ '@vue/devtools-api@7.4.4':
+ resolution: {integrity: sha512-Iqqy9yBFWBbPb/jHlJzU/OrU+iHSJ/e9p/v5pZhm/L5pUCX26z32bvvjPa28vMXxRehbAZTgX8zovOeqBTnhdg==}
+
+ '@vue/devtools-kit@7.4.4':
+ resolution: {integrity: sha512-awK/4NfsUG0nQ7qnTM37m7ZkEUMREyPh8taFCX+uQYps/MTFEum0AD05VeGDRMXwWvMmGIcWX9xp8ZiBddY0jw==}
+
+ '@vue/devtools-shared@7.4.4':
+ resolution: {integrity: sha512-yeJULXFHOKIm8yL2JFO050a9ztTVqOCKTqN9JHFxGTJN0b+gjtfn6zC+FfyHUgjwCwf6E3hfKrlohtthcqoYqw==}
+
+ '@vue/reactivity@3.5.2':
+ resolution: {integrity: sha512-lJwWL5bNht+2vIwU/+lnGdH+FKFxzz6z8WkoIJityPLiasWU+HDUvEsC7gm3JFwbTf7Kk+Nr9kJMaPy0HXwwxQ==}
+
+ '@vue/runtime-core@3.5.2':
+ resolution: {integrity: sha512-oU+i9sJjGEMfEhlrJ7SZv7CdSIgUNyBHnWHa0SqU2RF48V3/ATajzpWq1/DkiVJ1mtx+cQFAMKs8s/3cB3YlLQ==}
+
+ '@vue/runtime-dom@3.5.2':
+ resolution: {integrity: sha512-2qvysn+oR0QnFKaWZxQ90iVpWAK/WPpYmODHCv24IDXjsBrdHbjLBj9s6YBdPaMuQhs0LNsmhsgZYZBkszLg6g==}
+
+ '@vue/server-renderer@3.5.2':
+ resolution: {integrity: sha512-3POhYCA8KfbmuDuUiNbMXnpdh9pwE4SvAqo7VvACjklLkf3AaMkY3TvV7APeEa/WQezrnL+E4X2ASpJsKeS4cQ==}
+ peerDependencies:
+ vue: 3.5.2
+
+ '@vue/shared@3.5.2':
+ resolution: {integrity: sha512-Ce89WNFBzcDca/AgFTxgX4/K4iAyF7oFIp8Z5aBbFBNbtpwnQr+5pZOoHndxnjE2h+YFcipVMzs9UL11XB6dwA==}
+
+ '@vueuse/core@10.11.1':
+ resolution: {integrity: sha512-guoy26JQktXPcz+0n3GukWIy/JDNKti9v6VEMu6kV2sYBsWuGiTU8OWdg+ADfUbHg3/3DlqySDe7JmdHrktiww==}
+
+ '@vueuse/core@11.0.3':
+ resolution: {integrity: sha512-RENlh64+SYA9XMExmmH1a3TPqeIuJBNNB/63GT35MZI+zpru3oMRUA6cEFr9HmGqEgUisurwGwnIieF6qu3aXw==}
+
+ '@vueuse/core@11.1.0':
+ resolution: {integrity: sha512-P6dk79QYA6sKQnghrUz/1tHi0n9mrb/iO1WTMk/ElLmTyNqgDeSZ3wcDf6fRBGzRJbeG1dxzEOvLENMjr+E3fg==}
+
+ '@vueuse/integrations@11.0.3':
+ resolution: {integrity: sha512-w6CDisaxs19S5Fd+NPPLFaA3GoX5gxuxrbTTBu0EYap7oH13w75L6C/+7e9mcoF9akhcR6GyYajwVMQEjdapJg==}
+ peerDependencies:
+ async-validator: ^4
+ axios: ^1
+ change-case: ^5
+ drauu: ^0.4
+ focus-trap: ^7
+ fuse.js: ^7
+ idb-keyval: ^6
+ jwt-decode: ^4
+ nprogress: ^0.2
+ qrcode: ^1.5
+ sortablejs: ^1
+ universal-cookie: ^7
+ peerDependenciesMeta:
+ async-validator:
+ optional: true
+ axios:
+ optional: true
+ change-case:
+ optional: true
+ drauu:
+ optional: true
+ focus-trap:
+ optional: true
+ fuse.js:
+ optional: true
+ idb-keyval:
+ optional: true
+ jwt-decode:
+ optional: true
+ nprogress:
+ optional: true
+ qrcode:
+ optional: true
+ sortablejs:
+ optional: true
+ universal-cookie:
+ optional: true
+
+ '@vueuse/metadata@10.11.1':
+ resolution: {integrity: sha512-IGa5FXd003Ug1qAZmyE8wF3sJ81xGLSqTqtQ6jaVfkeZ4i5kS2mwQF61yhVqojRnenVew5PldLyRgvdl4YYuSw==}
+
+ '@vueuse/metadata@11.0.3':
+ resolution: {integrity: sha512-+FtbO4SD5WpsOcQTcC0hAhNlOid6QNLzqedtquTtQ+CRNBoAt9GuV07c6KNHK1wCmlq8DFPwgiLF2rXwgSHX5Q==}
+
+ '@vueuse/metadata@11.1.0':
+ resolution: {integrity: sha512-l9Q502TBTaPYGanl1G+hPgd3QX5s4CGnpXriVBR5fEZ/goI6fvDaVmIl3Td8oKFurOxTmbXvBPSsgrd6eu6HYg==}
+
+ '@vueuse/motion@2.2.6':
+ resolution: {integrity: sha512-gKFktPtrdypSv44SaW1oBJKLBiP6kE5NcoQ6RsAU3InemESdiAutgQncfPe/rhLSLCtL4jTAhMmFfxoR6gm5LQ==}
+ peerDependencies:
+ vue: '>=3.0.0'
+
+ '@vueuse/shared@10.11.1':
+ resolution: {integrity: sha512-LHpC8711VFZlDaYUXEBbFBCQ7GS3dVU9mjOhhMhXP6txTV4EhYQg/KGnQuvt/sPAtoUKq7VVUnL6mVtFoL42sA==}
+
+ '@vueuse/shared@11.0.3':
+ resolution: {integrity: sha512-0rY2m6HS5t27n/Vp5cTDsKTlNnimCqsbh/fmT2LgE+aaU42EMfXo8+bNX91W9I7DDmxfuACXMmrd7d79JxkqWA==}
+
+ '@vueuse/shared@11.1.0':
+ resolution: {integrity: sha512-YUtIpY122q7osj+zsNMFAfMTubGz0sn5QzE5gPzAIiCmtt2ha3uQUY1+JPyL4gRCTsLPX82Y9brNbo/aqlA91w==}
+
+ acorn@8.12.1:
+ resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ acorn@8.14.0:
+ resolution: {integrity: sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ algoliasearch@4.24.0:
+ resolution: {integrity: sha512-bf0QV/9jVejssFBmz2HQLxUadxk574t4iwjCKp5E7NBzwKkrDEhKPISIIjAU/p6K5qDx3qoeh4+26zWN1jmw3g==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.0.1:
+ resolution: {integrity: sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==}
+ engines: {node: '>=12'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ any-promise@1.3.0:
+ resolution: {integrity: sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-hidden@1.2.4:
+ resolution: {integrity: sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A==}
+ engines: {node: '>=10'}
+
+ asynckit@0.4.0:
+ resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==}
+
+ autoprefixer@10.4.20:
+ resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==}
+ engines: {node: ^10 || ^12 || >=14}
+ hasBin: true
+ peerDependencies:
+ postcss: ^8.1.0
+
+ axios@1.7.7:
+ resolution: {integrity: sha512-S4kL7XrjgBmvdGut0sN3yJxqYzrDOnivkBiN0OFs6hLiUam3UPvswUo0kqGyhqUZGEOytHyumEdXsAkgCOUf3Q==}
+
+ balanced-match@1.0.2:
+ resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ birpc@0.2.17:
+ resolution: {integrity: sha512-+hkTxhot+dWsLpp3gia5AkVHIsKlZybNT5gIYiDlNzJrmYPcTM9k5/w2uaj3IPpd7LlEYpmCj4Jj1nC41VhDFg==}
+
+ brace-expansion@2.0.1:
+ resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.23.3:
+ resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ browserslist@4.24.2:
+ resolution: {integrity: sha512-ZIc+Q62revdMcqC6aChtW4jz3My3klmCO1fEmINZY/8J3EpBg5/A/D0AKmBveUh6pgoeycoMkVMko84tuYS+Gg==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ c12@1.11.2:
+ resolution: {integrity: sha512-oBs8a4uvSDO9dm8b7OCFW7+dgtVrwmwnrVXYzLm43ta7ep2jCn/0MhoUFygIWtxhyy6+/MG7/agvpY0U1Iemew==}
+ peerDependencies:
+ magicast: ^0.3.4
+ peerDependenciesMeta:
+ magicast:
+ optional: true
+
+ camelcase-css@2.0.1:
+ resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==}
+ engines: {node: '>= 6'}
+
+ caniuse-lite@1.0.30001657:
+ resolution: {integrity: sha512-DPbJAlP8/BAXy3IgiWmZKItubb3TYGP0WscQQlVGIfT4s/YlFYVuJgyOsQNP7rJRChx/qdMeLJQJP0Sgg2yjNA==}
+
+ caniuse-lite@1.0.30001674:
+ resolution: {integrity: sha512-jOsKlZVRnzfhLojb+Ykb+gyUSp9Xb57So+fAiFlLzzTKpqg8xxSav0e40c8/4F/v9N8QSvrRRaLeVzQbLqomYw==}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ chownr@2.0.0:
+ resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==}
+ engines: {node: '>=10'}
+
+ citty@0.1.6:
+ resolution: {integrity: sha512-tskPPKEs8D2KPafUypv2gxwJP8h/OaJmC82QQGGDQcHvXX43xF2VDACcJVmZ0EuSxkpO9Kc4MlrA3q0+FG58AQ==}
+
+ class-variance-authority@0.7.0:
+ resolution: {integrity: sha512-jFI8IQw4hczaL4ALINxqLEXQbWcNjoSkloa4IaufXCJr6QawJyw7tuRysRsrE8w2p/4gGaxKIt/hX3qz/IbD1A==}
+
+ clsx@2.0.0:
+ resolution: {integrity: sha512-rQ1+kcj+ttHG0MKVGBUXwayCCF1oh39BF5COIpRzuCEv8Mwjv0XucrI2ExNTOn9IlLifGClWQcU9BrZORvtw6Q==}
+ engines: {node: '>=6'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ combined-stream@1.0.8:
+ resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==}
+ engines: {node: '>= 0.8'}
+
+ commander@4.1.1:
+ resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==}
+ engines: {node: '>= 6'}
+
+ compatx@0.1.8:
+ resolution: {integrity: sha512-jcbsEAR81Bt5s1qOFymBufmCbXCXbk0Ql+K5ouj6gCyx2yHlu6AgmGIi9HxfKixpUDO5bCFJUHQ5uM6ecbTebw==}
+
+ confbox@0.1.8:
+ resolution: {integrity: sha512-RMtmw0iFkeR4YV+fUOSucriAQNb9g8zFR52MWCtl+cCZOFRNL6zeB395vPzFhEjjn4fMxXudmELnl/KF/WrK6w==}
+
+ consola@3.2.3:
+ resolution: {integrity: sha512-I5qxpzLv+sJhTVEoLYNcTW+bThDCPsit0vLNKShZx6rLtpilNpmmeTPaeqJb9ZE9dV3DGaeby6Vuhrw38WjeyQ==}
+ engines: {node: ^14.18.0 || >=16.10.0}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ copy-anything@3.0.5:
+ resolution: {integrity: sha512-yCEafptTtb4bk7GLEQoM8KVJpxAfdBJYaXyzQEgQQQgYrZiDp8SJmGKlYza6CYjEDNstAdNdKA3UuoULlEbS6w==}
+ engines: {node: '>=12.13'}
+
+ cross-spawn@7.0.3:
+ resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
+ engines: {node: '>= 8'}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ csstype@3.1.3:
+ resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==}
+
+ debug@4.3.7:
+ resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ defu@6.1.4:
+ resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==}
+
+ delayed-stream@1.0.0:
+ resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==}
+ engines: {node: '>=0.4.0'}
+
+ destr@2.0.3:
+ resolution: {integrity: sha512-2N3BOUU4gYMpTP24s5rF5iP7BDr7uNTCs4ozw3kf/eKfvWSIu93GEBi5m427YoyJoeOzQ5smuu4nNAPGb8idSQ==}
+
+ didyoumean@1.2.2:
+ resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==}
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ dotenv@16.4.5:
+ resolution: {integrity: sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==}
+ engines: {node: '>=12'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ electron-to-chromium@1.5.15:
+ resolution: {integrity: sha512-Z4rIDoImwEJW+YYKnPul4DzqsWVqYetYVN3XqDmRpgV0mjz0hYTaeeh+8/9CL1bk3AHYmF4freW/NTiVoXA2gA==}
+
+ electron-to-chromium@1.5.49:
+ resolution: {integrity: sha512-ZXfs1Of8fDb6z7WEYZjXpgIRF6MEu8JdeGA0A40aZq6OQbS+eJpnnV49epZRna2DU/YsEjSQuGtQPPtvt6J65A==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ execa@8.0.1:
+ resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==}
+ engines: {node: '>=16.17'}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ focus-trap@7.5.4:
+ resolution: {integrity: sha512-N7kHdlgsO/v+iD/dMoJKtsSqs5Dz/dXZVebRgJw23LDk+jMi/974zyiOYDziY2JPp8xivq9BmUGwIJMiuSBi7w==}
+
+ follow-redirects@1.15.8:
+ resolution: {integrity: sha512-xgrmBhBToVKay1q2Tao5LI26B83UhrB/vM1avwVSDzt8rx3rO6AizBAaF46EgksTVr+rFTQaqZZ9MVBfUe4nig==}
+ engines: {node: '>=4.0'}
+ peerDependencies:
+ debug: '*'
+ peerDependenciesMeta:
+ debug:
+ optional: true
+
+ foreground-child@3.3.0:
+ resolution: {integrity: sha512-Ld2g8rrAyMYFXBhEqMz8ZAHBi4J4uS1i/CxGMDnjyFWddMXLVcDp051DZfu+t7+ab7Wv6SMqpWmyFIj5UbfFvg==}
+ engines: {node: '>=14'}
+
+ form-data@4.0.0:
+ resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==}
+ engines: {node: '>= 6'}
+
+ fraction.js@4.3.7:
+ resolution: {integrity: sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==}
+
+ framesync@6.1.2:
+ resolution: {integrity: sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==}
+
+ fs-minipass@2.1.0:
+ resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==}
+ engines: {node: '>= 8'}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ function-bind@1.1.2:
+ resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==}
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-stream@8.0.1:
+ resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==}
+ engines: {node: '>=16'}
+
+ giget@1.2.3:
+ resolution: {integrity: sha512-8EHPljDvs7qKykr6uw8b+lqLiUc/vUg+KVTI0uND4s63TdsZM2Xus3mflvF0DDG9SiM4RlCkFGL+7aAjRmV7KA==}
+ hasBin: true
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ glob-parent@6.0.2:
+ resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==}
+ engines: {node: '>=10.13.0'}
+
+ glob@10.4.5:
+ resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==}
+ hasBin: true
+
+ globals@11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+
+ globby@14.0.2:
+ resolution: {integrity: sha512-s3Fq41ZVh7vbbe2PN3nrW7yC7U7MFVc5c98/iTl9c2GawNMKx/J648KQRW6WKkuU8GIbbh2IXfIRQjOZnXcTnw==}
+ engines: {node: '>=18'}
+
+ hash-sum@2.0.0:
+ resolution: {integrity: sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg==}
+
+ hasown@2.0.2:
+ resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
+ engines: {node: '>= 0.4'}
+
+ hey-listen@1.0.8:
+ resolution: {integrity: sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q==}
+
+ hookable@5.5.3:
+ resolution: {integrity: sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==}
+
+ human-signals@5.0.0:
+ resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
+ engines: {node: '>=16.17.0'}
+
+ ignore@5.3.2:
+ resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
+ engines: {node: '>= 4'}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-core-module@2.15.1:
+ resolution: {integrity: sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ==}
+ engines: {node: '>= 0.4'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-stream@3.0.0:
+ resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ is-what@4.1.16:
+ resolution: {integrity: sha512-ZhMwEosbFJkA0YhFnNDgTM4ZxDRsS6HqTo7qsZM08fehyRYIYa0yHu5R6mgo1n/8MgaPBXiPimPD77baVFYg+A==}
+ engines: {node: '>=12.13'}
+
+ isexe@2.0.0:
+ resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==}
+
+ jackspeak@3.4.3:
+ resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==}
+
+ jiti@1.21.6:
+ resolution: {integrity: sha512-2yTgeWTWzMWkHu6Jp9NKgePDaYHbntiwvYuuJLbbN9vl7DC9DvXKOB2BC3ZZ92D3cvV/aflH0osDfwpHepQ53w==}
+ hasBin: true
+
+ jiti@2.3.3:
+ resolution: {integrity: sha512-EX4oNDwcXSivPrw2qKH2LB5PoFxEvgtv2JgwW0bU858HoLQ+kutSvjLMUqBd0PeJYEinLWhoI9Ol0eYMqj/wNQ==}
+ hasBin: true
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-tokens@9.0.0:
+ resolution: {integrity: sha512-WriZw1luRMlmV3LGJaR6QOJjWwgLUTf89OwT2lUOyjX2dJGBwgmIkbcz+7WFZjrZM635JOIR517++e/67CP9dQ==}
+
+ jsesc@3.0.2:
+ resolution: {integrity: sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ klona@2.0.6:
+ resolution: {integrity: sha512-dhG34DXATL5hSxJbIexCft8FChFXtmskoZYnoPWjXQuebWYCNkVeV3KkGegCK9CP1oswI/vQibS2GY7Em/sJJA==}
+ engines: {node: '>= 8'}
+
+ knitwork@1.1.0:
+ resolution: {integrity: sha512-oHnmiBUVHz1V+URE77PNot2lv3QiYU2zQf1JjOVkMt3YDKGbu8NAFr+c4mcNOhdsGrB/VpVbRwPwhiXrPhxQbw==}
+
+ kolorist@1.8.0:
+ resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==}
+
+ lilconfig@2.1.0:
+ resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==}
+ engines: {node: '>=10'}
+
+ lilconfig@3.1.2:
+ resolution: {integrity: sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==}
+ engines: {node: '>=14'}
+
+ lines-and-columns@1.2.4:
+ resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
+
+ linkify-it@5.0.0:
+ resolution: {integrity: sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==}
+
+ local-pkg@0.5.0:
+ resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==}
+ engines: {node: '>=14'}
+
+ lru-cache@10.4.3:
+ resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==}
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ lucide-vue-next@0.438.0:
+ resolution: {integrity: sha512-xlPIeYbhfI0gDJwolST7cjc6KAi1oWN9HEWGuK+5gMmoi+a6bJ3mI062+7tqzOdjSE07l7jyBH4mladQVLIQRA==}
+ peerDependencies:
+ vue: '>=3.0.1'
+
+ magic-string@0.30.11:
+ resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
+
+ mark.js@8.11.1:
+ resolution: {integrity: sha512-1I+1qpDt4idfgLQG+BNWmrqku+7/2bi5nLf4YwF8y8zXvmfiTBY3PV3ZibfrjBueCByROpuBjLLFCajqkgYoLQ==}
+
+ markdown-it@14.1.0:
+ resolution: {integrity: sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==}
+ hasBin: true
+
+ mdurl@2.0.0:
+ resolution: {integrity: sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==}
+
+ merge-stream@2.0.0:
+ resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mime-db@1.52.0:
+ resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==}
+ engines: {node: '>= 0.6'}
+
+ mime-types@2.1.35:
+ resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==}
+ engines: {node: '>= 0.6'}
+
+ mimic-fn@4.0.0:
+ resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==}
+ engines: {node: '>=12'}
+
+ minimatch@9.0.5:
+ resolution: {integrity: sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minipass@3.3.6:
+ resolution: {integrity: sha512-DxiNidxSEK+tHG6zOIklvNOwm3hvCrbUrdtzY74U6HKTJxvIDfOUL5W5P2Ghd3DTkhhKPYGqeNUIh5qcM4YBfw==}
+ engines: {node: '>=8'}
+
+ minipass@5.0.0:
+ resolution: {integrity: sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ==}
+ engines: {node: '>=8'}
+
+ minipass@7.1.2:
+ resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
+ engines: {node: '>=16 || 14 >=14.17'}
+
+ minisearch@7.1.0:
+ resolution: {integrity: sha512-tv7c/uefWdEhcu6hvrfTihflgeEi2tN6VV7HJnCjK6VxM75QQJh4t9FwJCsA2EsRS8LCnu3W87CuGPWMocOLCA==}
+
+ minizlib@2.1.2:
+ resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==}
+ engines: {node: '>= 8'}
+
+ mitt@3.0.1:
+ resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
+
+ mkdirp@1.0.4:
+ resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ mlly@1.7.2:
+ resolution: {integrity: sha512-tN3dvVHYVz4DhSXinXIk7u9syPYaJvio118uomkovAtWBT+RdbP6Lfh/5Lvo519YMmwBafwlh20IPTXIStscpA==}
+
+ mri@1.2.0:
+ resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==}
+ engines: {node: '>=4'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ mz@2.7.0:
+ resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==}
+
+ nanoid@3.3.7:
+ resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ nanoid@5.0.7:
+ resolution: {integrity: sha512-oLxFY2gd2IqnjcYyOXD8XGCftpGtZP2AbHbOkthDkvRywH5ayNtPVy9YlOPcHckXzbLTCHpkb7FB+yuxKV13pQ==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+
+ node-fetch-native@1.6.4:
+ resolution: {integrity: sha512-IhOigYzAKHd244OC0JIMIUrjzctirCmPkaIfhDeGcEETWof5zKYUW7e7MYvChGWh/4CJeXEgsRyGzuF334rOOQ==}
+
+ node-releases@2.0.18:
+ resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ normalize-range@0.1.2:
+ resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==}
+ engines: {node: '>=0.10.0'}
+
+ npm-run-path@5.3.0:
+ resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+
+ nypm@0.3.12:
+ resolution: {integrity: sha512-D3pzNDWIvgA+7IORhD/IuWzEk4uXv6GsgOxiid4UU3h9oq5IqV1KtPDi63n4sZJ/xcWlr88c0QM2RgN5VbOhFA==}
+ engines: {node: ^14.16.0 || >=16.10.0}
+ hasBin: true
+
+ object-assign@4.1.1:
+ resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
+ engines: {node: '>=0.10.0'}
+
+ object-hash@3.0.0:
+ resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==}
+ engines: {node: '>= 6'}
+
+ ohash@1.1.4:
+ resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==}
+
+ onetime@6.0.0:
+ resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==}
+ engines: {node: '>=12'}
+
+ package-json-from-dist@1.0.0:
+ resolution: {integrity: sha512-dATvCeZN/8wQsGywez1mzHtTlP22H8OEfPrVMLNr4/eGa+ijtLn/6M5f0dY8UKNrC2O9UCU6SSoG3qRKnt7STw==}
+
+ package-manager-detector@0.2.2:
+ resolution: {integrity: sha512-VgXbyrSNsml4eHWIvxxG/nTL4wgybMTXCV2Un/+yEc3aDKKU6nQBZjbeP3Pl3qm9Qg92X/1ng4ffvCeD/zwHgg==}
+
+ path-key@3.1.1:
+ resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==}
+ engines: {node: '>=8'}
+
+ path-key@4.0.0:
+ resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==}
+ engines: {node: '>=12'}
+
+ path-parse@1.0.7:
+ resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==}
+
+ path-scurry@1.11.1:
+ resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==}
+ engines: {node: '>=16 || 14 >=14.18'}
+
+ path-type@5.0.0:
+ resolution: {integrity: sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==}
+ engines: {node: '>=12'}
+
+ pathe@1.1.2:
+ resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+
+ perfect-debounce@1.0.0:
+ resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
+
+ picocolors@1.1.0:
+ resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ picomatch@4.0.2:
+ resolution: {integrity: sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==}
+ engines: {node: '>=12'}
+
+ pify@2.3.0:
+ resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==}
+ engines: {node: '>=0.10.0'}
+
+ pirates@4.0.6:
+ resolution: {integrity: sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==}
+ engines: {node: '>= 6'}
+
+ pkg-types@1.2.1:
+ resolution: {integrity: sha512-sQoqa8alT3nHjGuTjuKgOnvjo4cljkufdtLMnO2LBP/wRwuDlo1tkaEdMxCRhyGRPacv/ztlZgDPm2b7FAmEvw==}
+
+ popmotion@11.0.5:
+ resolution: {integrity: sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==}
+
+ postcss-import@15.1.0:
+ resolution: {integrity: sha512-hpr+J05B2FVYUAXHeK1YyI267J/dDDhMU6B6civm8hSY1jYJnBXxzKDKDswzJmtLHryrjhnDjqqp/49t8FALew==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ postcss: ^8.0.0
+
+ postcss-js@4.0.1:
+ resolution: {integrity: sha512-dDLF8pEO191hJMtlHFPRa8xsizHaM82MLfNkUHdUtVEV3tgTp5oj+8qbEqYM57SLfc74KSbw//4SeJma2LRVIw==}
+ engines: {node: ^12 || ^14 || >= 16}
+ peerDependencies:
+ postcss: ^8.4.21
+
+ postcss-load-config@4.0.2:
+ resolution: {integrity: sha512-bSVhyJGL00wMVoPUzAVAnbEoWyqRxkjv64tUl427SKnPrENtq6hJwUojroMz2VB+Q1edmi4IfrAPpami5VVgMQ==}
+ engines: {node: '>= 14'}
+ peerDependencies:
+ postcss: '>=8.0.9'
+ ts-node: '>=9.0.0'
+ peerDependenciesMeta:
+ postcss:
+ optional: true
+ ts-node:
+ optional: true
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss-value-parser@4.2.0:
+ resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==}
+
+ postcss@8.4.45:
+ resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ preact@10.23.2:
+ resolution: {integrity: sha512-kKYfePf9rzKnxOAKDpsWhg/ysrHPqT+yQ7UW4JjdnqjFIeNUnNcEJvhuA8fDenxAGWzUqtd51DfVg7xp/8T9NA==}
+
+ proxy-from-env@1.1.0:
+ resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==}
+
+ punycode.js@2.3.1:
+ resolution: {integrity: sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==}
+ engines: {node: '>=6'}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ radix-vue@1.9.5:
+ resolution: {integrity: sha512-vtCq+WDAZj5BQtJiChGf/oC7w3y7jaod3agcntgph7fD6aqdcghLZYcUWdgT/XNJs2bEsk+3cjK3ONPRNeFcuQ==}
+ peerDependencies:
+ vue: '>= 3.2.0'
+
+ rc9@2.1.2:
+ resolution: {integrity: sha512-btXCnMmRIBINM2LDZoEmOogIZU7Qe7zn4BpomSKZ/ykbLObuBdvG+mFq11DL6fjH1DRwHhrlgtYWG96bJiC7Cg==}
+
+ read-cache@1.0.0:
+ resolution: {integrity: sha512-Owdv/Ft7IjOgm/i0xvNDZ1LrRANRfew4b2prF3OWMQLxLfu3bS8FVhCsrSCMK4lR56Y9ya+AThoTpDCTxCmpRA==}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ resolve@1.22.8:
+ resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==}
+ hasBin: true
+
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rfdc@1.4.1:
+ resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==}
+
+ rollup@4.21.2:
+ resolution: {integrity: sha512-e3TapAgYf9xjdLvKQCkQTnbTKd4a6jwlpQSJJFokHGaX2IVjoEqkIIhiQfqsi0cdwlOD+tQGuOd5AJkc5RngBw==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ scule@1.3.0:
+ resolution: {integrity: sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==}
+
+ search-insights@2.17.1:
+ resolution: {integrity: sha512-HHFjYH/0AqXacETlIbe9EYc3UNlQYGNNTY0fZ/sWl6SweX+GDxq9NB5+RVoPLgEFuOtCz7M9dhYxqDnhbbF0eQ==}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ shebang-command@2.0.0:
+ resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==}
+ engines: {node: '>=8'}
+
+ shebang-regex@3.0.0:
+ resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==}
+ engines: {node: '>=8'}
+
+ shiki@1.16.2:
+ resolution: {integrity: sha512-gSym0hZf5a1U0iDPsdoOAZbvoi+e0c6c3NKAi03FoSLTm7oG20tum29+gk0wzzivOasn3loxfGUPT+jZXIUbWg==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ slash@5.1.0:
+ resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==}
+ engines: {node: '>=14.16'}
+
+ source-map-js@1.2.0:
+ resolution: {integrity: sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==}
+ engines: {node: '>=0.10.0'}
+
+ speakingurl@14.0.1:
+ resolution: {integrity: sha512-1POYv7uv2gXoyGFpBCmpDVSNV74IfsWlDW216UPjbWufNf+bSU6GdbDsxdcxtfwb4xlI3yxzOTKClUosxARYrQ==}
+ engines: {node: '>=0.10.0'}
+
+ std-env@3.7.0:
+ resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ strip-final-newline@3.0.0:
+ resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==}
+ engines: {node: '>=12'}
+
+ strip-literal@2.1.0:
+ resolution: {integrity: sha512-Op+UycaUt/8FbN/Z2TWPBLge3jWrP3xj10f3fnYxf052bKuS3EKs1ZQcVGjnEMdsNVAM+plXRdmjrZ/KgG3Skw==}
+
+ style-value-types@5.1.2:
+ resolution: {integrity: sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==}
+
+ sucrase@3.35.0:
+ resolution: {integrity: sha512-8EbVDiu9iN/nESwxeSxDKe0dunta1GOlHufmSSXxMD2z2/tMZpDMpvXQGsc+ajGo8y2uYUmixaSRUc/QPoQ0GA==}
+ engines: {node: '>=16 || 14 >=14.17'}
+ hasBin: true
+
+ superjson@2.2.1:
+ resolution: {integrity: sha512-8iGv75BYOa0xRJHK5vRLEjE2H/i4lulTjzpUXic3Eg8akftYjkmQDa8JARQ42rlczXyFR3IeRoeFCc7RxHsYZA==}
+ engines: {node: '>=16'}
+
+ supports-preserve-symlinks-flag@1.0.0:
+ resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
+ engines: {node: '>= 0.4'}
+
+ tabbable@6.2.0:
+ resolution: {integrity: sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==}
+
+ tailwind-merge@2.5.2:
+ resolution: {integrity: sha512-kjEBm+pvD+6eAwzJL2Bi+02/9LFLal1Gs61+QB7HvTfQQ0aXwC5LGT8PEt1gS0CWKktKe6ysPTAy3cBC5MeiIg==}
+
+ tailwindcss-animate@1.0.7:
+ resolution: {integrity: sha512-bl6mpH3T7I3UFxuvDEXLxy/VuFxBk5bbzplh7tXI68mwMokNYd1t9qPBHlnyTwfa4JGC4zP516I1hYYtQ/vspA==}
+ peerDependencies:
+ tailwindcss: '>=3.0.0 || insiders'
+
+ tailwindcss@3.4.10:
+ resolution: {integrity: sha512-KWZkVPm7yJRhdu4SRSl9d4AK2wM3a50UsvgHZO7xY77NQr2V+fIrEuoDGQcbvswWvFGbS2f6e+jC/6WJm1Dl0w==}
+ engines: {node: '>=14.0.0'}
+ hasBin: true
+
+ tar@6.2.1:
+ resolution: {integrity: sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==}
+ engines: {node: '>=10'}
+
+ thenify-all@1.6.0:
+ resolution: {integrity: sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==}
+ engines: {node: '>=0.8'}
+
+ thenify@3.3.1:
+ resolution: {integrity: sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==}
+
+ tinyexec@0.3.0:
+ resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==}
+
+ to-fast-properties@2.0.0:
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+ engines: {node: '>=4'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ ts-interface-checker@0.1.13:
+ resolution: {integrity: sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA==}
+
+ tslib@2.4.0:
+ resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
+
+ tslib@2.7.0:
+ resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
+
+ uc.micro@2.1.0:
+ resolution: {integrity: sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==}
+
+ ufo@1.5.4:
+ resolution: {integrity: sha512-UsUk3byDzKd04EyoZ7U4DOlxQaD14JUKQl6/P7wiX4FNvUfm3XL246n9W5AmqwW5RSFJ27NAuM0iLscAOYUiGQ==}
+
+ uncrypto@0.1.3:
+ resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==}
+
+ unctx@2.3.1:
+ resolution: {integrity: sha512-PhKke8ZYauiqh3FEMVNm7ljvzQiph0Mt3GBRve03IJm7ukfaON2OBK795tLwhbyfzknuRRkW0+Ze+CQUmzOZ+A==}
+
+ undici-types@6.19.8:
+ resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==}
+
+ unicorn-magic@0.1.0:
+ resolution: {integrity: sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==}
+ engines: {node: '>=18'}
+
+ unimport@3.13.1:
+ resolution: {integrity: sha512-nNrVzcs93yrZQOW77qnyOVHtb68LegvhYFwxFMfuuWScmwQmyVCG/NBuN8tYsaGzgQUVYv34E/af+Cc9u4og4A==}
+
+ unplugin@1.15.0:
+ resolution: {integrity: sha512-jTPIs63W+DUEDW207ztbaoO7cQ4p5aVaB823LSlxpsFEU3Mykwxf3ZGC/wzxFJeZlASZYgVrWeo7LgOrqJZ8RA==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ webpack-sources: ^3
+ peerDependenciesMeta:
+ webpack-sources:
+ optional: true
+
+ untyped@1.5.1:
+ resolution: {integrity: sha512-reBOnkJBFfBZ8pCKaeHgfZLcehXtM6UTxc+vqs1JvCps0c4amLNp3fhdGBZwYp+VLyoY9n3X5KOP7lCyWBUX9A==}
+ hasBin: true
+
+ update-browserslist-db@1.1.0:
+ resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ update-browserslist-db@1.1.1:
+ resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ vite@5.4.3:
+ resolution: {integrity: sha512-IH+nl64eq9lJjFqU+/yrRnrHPVTlgy42/+IzbOdaFDVlyLgI/wDlf+FCobXLX1cT0X5+7LMyH1mIy2xJdLfo8Q==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vitepress-plugin-group-icons@1.2.4:
+ resolution: {integrity: sha512-pxYzphvRy0Jhpgl3lHszH9Z8Qaj83v4bVr0b8Oi4zSIOQW/uuqGAZ8SaYwkZ1f/8a6ckIeIwZiLfLHA6ySCScQ==}
+
+ vitepress@1.3.4:
+ resolution: {integrity: sha512-I1/F6OW1xl3kW4PaIMC6snxjWgf3qfziq2aqsDoFc/Gt41WbcRv++z8zjw8qGRIJ+I4bUW7ZcKFDHHN/jkH9DQ==}
+ hasBin: true
+ peerDependencies:
+ markdown-it-mathjax3: ^4
+ postcss: ^8
+ peerDependenciesMeta:
+ markdown-it-mathjax3:
+ optional: true
+ postcss:
+ optional: true
+
+ vue-demi@0.14.10:
+ resolution: {integrity: sha512-nMZBOwuzabUO0nLgIcc6rycZEebF6eeUfaiQx9+WSk8e29IbLvPU9feI6tqW4kTo3hvoYAJkMh8n8D0fuISphg==}
+ engines: {node: '>=12'}
+ hasBin: true
+ peerDependencies:
+ '@vue/composition-api': ^1.0.0-rc.1
+ vue: ^3.0.0-0 || ^2.6.0
+ peerDependenciesMeta:
+ '@vue/composition-api':
+ optional: true
+
+ vue-writer@2.0.2:
+ resolution: {integrity: sha512-k3Zos5f86REHoY6XRGjEHArUsd7EjUAUu0ehpPWnkHzbc9nPmzboZfw3PmPe9thN8L/QAJve69rHcUU+llFM/g==}
+ engines: {node: '>=20'}
+ peerDependencies:
+ vue: ^3.4.21
+
+ vue@3.5.2:
+ resolution: {integrity: sha512-w1YB4lAwC9ByH6AnFY0JvZF+y70Usul9jDfKIKtM5xA97q/JPS5R7mqq0fhA6D2PQxYPZdgb5jzFKLyOga5pnw==}
+ peerDependencies:
+ typescript: '*'
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ webpack-virtual-modules@0.6.2:
+ resolution: {integrity: sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ==}
+
+ which@2.0.2:
+ resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
+ engines: {node: '>= 8'}
+ hasBin: true
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yallist@4.0.0:
+ resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==}
+
+ yaml@2.5.1:
+ resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+snapshots:
+
+ '@algolia/autocomplete-core@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.1)':
+ dependencies:
+ '@algolia/autocomplete-plugin-algolia-insights': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.1)
+ '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+ - search-insights
+
+ '@algolia/autocomplete-plugin-algolia-insights@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.1)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)
+ search-insights: 2.17.1
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - algoliasearch
+
+ '@algolia/autocomplete-preset-algolia@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)':
+ dependencies:
+ '@algolia/autocomplete-shared': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)
+ '@algolia/client-search': 4.24.0
+ algoliasearch: 4.24.0
+
+ '@algolia/autocomplete-shared@1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)':
+ dependencies:
+ '@algolia/client-search': 4.24.0
+ algoliasearch: 4.24.0
+
+ '@algolia/cache-browser-local-storage@4.24.0':
+ dependencies:
+ '@algolia/cache-common': 4.24.0
+
+ '@algolia/cache-common@4.24.0': {}
+
+ '@algolia/cache-in-memory@4.24.0':
+ dependencies:
+ '@algolia/cache-common': 4.24.0
+
+ '@algolia/client-account@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-analytics@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-common@4.24.0':
+ dependencies:
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-personalization@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/client-search@4.24.0':
+ dependencies:
+ '@algolia/client-common': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/logger-common@4.24.0': {}
+
+ '@algolia/logger-console@4.24.0':
+ dependencies:
+ '@algolia/logger-common': 4.24.0
+
+ '@algolia/recommend@4.24.0':
+ dependencies:
+ '@algolia/cache-browser-local-storage': 4.24.0
+ '@algolia/cache-common': 4.24.0
+ '@algolia/cache-in-memory': 4.24.0
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/logger-common': 4.24.0
+ '@algolia/logger-console': 4.24.0
+ '@algolia/requester-browser-xhr': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/requester-node-http': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ '@algolia/requester-browser-xhr@4.24.0':
+ dependencies:
+ '@algolia/requester-common': 4.24.0
+
+ '@algolia/requester-common@4.24.0': {}
+
+ '@algolia/requester-node-http@4.24.0':
+ dependencies:
+ '@algolia/requester-common': 4.24.0
+
+ '@algolia/transporter@4.24.0':
+ dependencies:
+ '@algolia/cache-common': 4.24.0
+ '@algolia/logger-common': 4.24.0
+ '@algolia/requester-common': 4.24.0
+
+ '@alloc/quick-lru@5.2.0': {}
+
+ '@ampproject/remapping@2.3.0':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+ optional: true
+
+ '@antfu/install-pkg@0.4.1':
+ dependencies:
+ package-manager-detector: 0.2.2
+ tinyexec: 0.3.0
+
+ '@antfu/utils@0.7.10': {}
+
+ '@babel/code-frame@7.26.0':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.25.9
+ js-tokens: 4.0.0
+ picocolors: 1.1.0
+ optional: true
+
+ '@babel/compat-data@7.26.0':
+ optional: true
+
+ '@babel/core@7.26.0':
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@babel/code-frame': 7.26.0
+ '@babel/generator': 7.26.0
+ '@babel/helper-compilation-targets': 7.25.9
+ '@babel/helper-module-transforms': 7.26.0(@babel/core@7.26.0)
+ '@babel/helpers': 7.26.0
+ '@babel/parser': 7.26.1
+ '@babel/template': 7.25.9
+ '@babel/traverse': 7.25.9
+ '@babel/types': 7.26.0
+ convert-source-map: 2.0.0
+ debug: 4.3.7
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ '@babel/generator@7.26.0':
+ dependencies:
+ '@babel/parser': 7.26.1
+ '@babel/types': 7.26.0
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+ jsesc: 3.0.2
+ optional: true
+
+ '@babel/helper-compilation-targets@7.25.9':
+ dependencies:
+ '@babel/compat-data': 7.26.0
+ '@babel/helper-validator-option': 7.25.9
+ browserslist: 4.24.2
+ lru-cache: 5.1.1
+ semver: 6.3.1
+ optional: true
+
+ '@babel/helper-module-imports@7.25.9':
+ dependencies:
+ '@babel/traverse': 7.25.9
+ '@babel/types': 7.26.0
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ '@babel/helper-module-transforms@7.26.0(@babel/core@7.26.0)':
+ dependencies:
+ '@babel/core': 7.26.0
+ '@babel/helper-module-imports': 7.25.9
+ '@babel/helper-validator-identifier': 7.25.9
+ '@babel/traverse': 7.25.9
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ '@babel/helper-string-parser@7.24.8': {}
+
+ '@babel/helper-string-parser@7.25.9':
+ optional: true
+
+ '@babel/helper-validator-identifier@7.24.7': {}
+
+ '@babel/helper-validator-identifier@7.25.9':
+ optional: true
+
+ '@babel/helper-validator-option@7.25.9':
+ optional: true
+
+ '@babel/helpers@7.26.0':
+ dependencies:
+ '@babel/template': 7.25.9
+ '@babel/types': 7.26.0
+ optional: true
+
+ '@babel/parser@7.25.6':
+ dependencies:
+ '@babel/types': 7.25.6
+
+ '@babel/parser@7.26.1':
+ dependencies:
+ '@babel/types': 7.26.0
+ optional: true
+
+ '@babel/standalone@7.26.1':
+ optional: true
+
+ '@babel/template@7.25.9':
+ dependencies:
+ '@babel/code-frame': 7.26.0
+ '@babel/parser': 7.26.1
+ '@babel/types': 7.26.0
+ optional: true
+
+ '@babel/traverse@7.25.9':
+ dependencies:
+ '@babel/code-frame': 7.26.0
+ '@babel/generator': 7.26.0
+ '@babel/parser': 7.26.1
+ '@babel/template': 7.25.9
+ '@babel/types': 7.26.0
+ debug: 4.3.7
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ '@babel/types@7.25.6':
+ dependencies:
+ '@babel/helper-string-parser': 7.24.8
+ '@babel/helper-validator-identifier': 7.24.7
+ to-fast-properties: 2.0.0
+
+ '@babel/types@7.26.0':
+ dependencies:
+ '@babel/helper-string-parser': 7.25.9
+ '@babel/helper-validator-identifier': 7.25.9
+ optional: true
+
+ '@docsearch/css@3.6.1': {}
+
+ '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.1)':
+ dependencies:
+ '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.1)
+ preact: 10.23.2
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/react'
+ - react
+ - react-dom
+ - search-insights
+
+ '@docsearch/react@3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.1)':
+ dependencies:
+ '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.1)
+ '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)
+ '@docsearch/css': 3.6.1
+ algoliasearch: 4.24.0
+ optionalDependencies:
+ search-insights: 2.17.1
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@floating-ui/core@1.6.7':
+ dependencies:
+ '@floating-ui/utils': 0.2.7
+
+ '@floating-ui/dom@1.6.10':
+ dependencies:
+ '@floating-ui/core': 1.6.7
+ '@floating-ui/utils': 0.2.7
+
+ '@floating-ui/utils@0.2.7': {}
+
+ '@floating-ui/vue@1.1.4(vue@3.5.2)':
+ dependencies:
+ '@floating-ui/dom': 1.6.10
+ '@floating-ui/utils': 0.2.7
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@headlessui/tailwindcss@0.2.1(tailwindcss@3.4.10)':
+ dependencies:
+ tailwindcss: 3.4.10
+
+ '@headlessui/vue@1.7.22(vue@3.5.2)':
+ dependencies:
+ '@tanstack/vue-virtual': 3.10.7(vue@3.5.2)
+ vue: 3.5.2
+
+ '@iconify-json/logos@1.2.3':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify-json/vscode-icons@1.2.2':
+ dependencies:
+ '@iconify/types': 2.0.0
+
+ '@iconify/types@2.0.0': {}
+
+ '@iconify/utils@2.1.33':
+ dependencies:
+ '@antfu/install-pkg': 0.4.1
+ '@antfu/utils': 0.7.10
+ '@iconify/types': 2.0.0
+ debug: 4.3.7
+ kolorist: 1.8.0
+ local-pkg: 0.5.0
+ mlly: 1.7.2
+ transitivePeerDependencies:
+ - supports-color
+
+ '@internationalized/date@3.5.5':
+ dependencies:
+ '@swc/helpers': 0.5.13
+
+ '@internationalized/number@3.5.3':
+ dependencies:
+ '@swc/helpers': 0.5.13
+
+ '@isaacs/cliui@8.0.2':
+ dependencies:
+ string-width: 5.1.2
+ string-width-cjs: string-width@4.2.3
+ strip-ansi: 7.1.0
+ strip-ansi-cjs: strip-ansi@6.0.1
+ wrap-ansi: 8.1.0
+ wrap-ansi-cjs: wrap-ansi@7.0.0
+
+ '@jridgewell/gen-mapping@0.3.5':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
+ '@nuxt/kit@3.13.2(rollup@4.21.2)':
+ dependencies:
+ '@nuxt/schema': 3.13.2(rollup@4.21.2)
+ c12: 1.11.2
+ consola: 3.2.3
+ defu: 6.1.4
+ destr: 2.0.3
+ globby: 14.0.2
+ hash-sum: 2.0.0
+ ignore: 5.3.2
+ jiti: 1.21.6
+ klona: 2.0.6
+ knitwork: 1.1.0
+ mlly: 1.7.2
+ pathe: 1.1.2
+ pkg-types: 1.2.1
+ scule: 1.3.0
+ semver: 7.6.3
+ ufo: 1.5.4
+ unctx: 2.3.1
+ unimport: 3.13.1(rollup@4.21.2)
+ untyped: 1.5.1
+ transitivePeerDependencies:
+ - magicast
+ - rollup
+ - supports-color
+ - webpack-sources
+ optional: true
+
+ '@nuxt/schema@3.13.2(rollup@4.21.2)':
+ dependencies:
+ compatx: 0.1.8
+ consola: 3.2.3
+ defu: 6.1.4
+ hookable: 5.5.3
+ pathe: 1.1.2
+ pkg-types: 1.2.1
+ scule: 1.3.0
+ std-env: 3.7.0
+ ufo: 1.5.4
+ uncrypto: 0.1.3
+ unimport: 3.13.1(rollup@4.21.2)
+ untyped: 1.5.1
+ transitivePeerDependencies:
+ - rollup
+ - supports-color
+ - webpack-sources
+ optional: true
+
+ '@pkgjs/parseargs@0.11.0':
+ optional: true
+
+ '@rollup/pluginutils@5.1.3(rollup@4.21.2)':
+ dependencies:
+ '@types/estree': 1.0.5
+ estree-walker: 2.0.2
+ picomatch: 4.0.2
+ optionalDependencies:
+ rollup: 4.21.2
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.21.2':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.21.2':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.21.2':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.21.2':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.21.2':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.21.2':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.21.2':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.21.2':
+ optional: true
+
+ '@shikijs/core@1.16.2':
+ dependencies:
+ '@shikijs/vscode-textmate': 9.2.0
+ '@types/hast': 3.0.4
+
+ '@shikijs/markdown-it@1.16.2':
+ dependencies:
+ '@shikijs/transformers': 1.16.2
+ markdown-it: 14.1.0
+ shiki: 1.16.2
+
+ '@shikijs/transformers@1.16.2':
+ dependencies:
+ shiki: 1.16.2
+
+ '@shikijs/vscode-textmate@9.2.0': {}
+
+ '@sindresorhus/merge-streams@2.3.0':
+ optional: true
+
+ '@swc/helpers@0.5.13':
+ dependencies:
+ tslib: 2.7.0
+
+ '@tanstack/virtual-core@3.10.7': {}
+
+ '@tanstack/vue-virtual@3.10.7(vue@3.5.2)':
+ dependencies:
+ '@tanstack/virtual-core': 3.10.7
+ vue: 3.5.2
+
+ '@types/estree@1.0.5': {}
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/linkify-it@5.0.0': {}
+
+ '@types/markdown-it@14.1.2':
+ dependencies:
+ '@types/linkify-it': 5.0.0
+ '@types/mdurl': 2.0.0
+
+ '@types/mdurl@2.0.0': {}
+
+ '@types/node@22.5.4':
+ dependencies:
+ undici-types: 6.19.8
+
+ '@types/unist@3.0.3': {}
+
+ '@types/web-bluetooth@0.0.20': {}
+
+ '@vitejs/plugin-vue@5.1.3(vite@5.4.3(@types/node@22.5.4))(vue@3.5.2)':
+ dependencies:
+ vite: 5.4.3(@types/node@22.5.4)
+ vue: 3.5.2
+
+ '@vue/compiler-core@3.5.2':
+ dependencies:
+ '@babel/parser': 7.25.6
+ '@vue/shared': 3.5.2
+ entities: 4.5.0
+ estree-walker: 2.0.2
+ source-map-js: 1.2.0
+
+ '@vue/compiler-dom@3.5.2':
+ dependencies:
+ '@vue/compiler-core': 3.5.2
+ '@vue/shared': 3.5.2
+
+ '@vue/compiler-sfc@3.5.2':
+ dependencies:
+ '@babel/parser': 7.25.6
+ '@vue/compiler-core': 3.5.2
+ '@vue/compiler-dom': 3.5.2
+ '@vue/compiler-ssr': 3.5.2
+ '@vue/shared': 3.5.2
+ estree-walker: 2.0.2
+ magic-string: 0.30.11
+ postcss: 8.4.45
+ source-map-js: 1.2.0
+
+ '@vue/compiler-ssr@3.5.2':
+ dependencies:
+ '@vue/compiler-dom': 3.5.2
+ '@vue/shared': 3.5.2
+
+ '@vue/devtools-api@7.4.4':
+ dependencies:
+ '@vue/devtools-kit': 7.4.4
+
+ '@vue/devtools-kit@7.4.4':
+ dependencies:
+ '@vue/devtools-shared': 7.4.4
+ birpc: 0.2.17
+ hookable: 5.5.3
+ mitt: 3.0.1
+ perfect-debounce: 1.0.0
+ speakingurl: 14.0.1
+ superjson: 2.2.1
+
+ '@vue/devtools-shared@7.4.4':
+ dependencies:
+ rfdc: 1.4.1
+
+ '@vue/reactivity@3.5.2':
+ dependencies:
+ '@vue/shared': 3.5.2
+
+ '@vue/runtime-core@3.5.2':
+ dependencies:
+ '@vue/reactivity': 3.5.2
+ '@vue/shared': 3.5.2
+
+ '@vue/runtime-dom@3.5.2':
+ dependencies:
+ '@vue/reactivity': 3.5.2
+ '@vue/runtime-core': 3.5.2
+ '@vue/shared': 3.5.2
+ csstype: 3.1.3
+
+ '@vue/server-renderer@3.5.2(vue@3.5.2)':
+ dependencies:
+ '@vue/compiler-ssr': 3.5.2
+ '@vue/shared': 3.5.2
+ vue: 3.5.2
+
+ '@vue/shared@3.5.2': {}
+
+ '@vueuse/core@10.11.1(vue@3.5.2)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 10.11.1
+ '@vueuse/shared': 10.11.1(vue@3.5.2)
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/core@11.0.3(vue@3.5.2)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 11.0.3
+ '@vueuse/shared': 11.0.3(vue@3.5.2)
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/core@11.1.0(vue@3.5.2)':
+ dependencies:
+ '@types/web-bluetooth': 0.0.20
+ '@vueuse/metadata': 11.1.0
+ '@vueuse/shared': 11.1.0(vue@3.5.2)
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/integrations@11.0.3(axios@1.7.7)(focus-trap@7.5.4)(vue@3.5.2)':
+ dependencies:
+ '@vueuse/core': 11.0.3(vue@3.5.2)
+ '@vueuse/shared': 11.0.3(vue@3.5.2)
+ vue-demi: 0.14.10(vue@3.5.2)
+ optionalDependencies:
+ axios: 1.7.7
+ focus-trap: 7.5.4
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/metadata@10.11.1': {}
+
+ '@vueuse/metadata@11.0.3': {}
+
+ '@vueuse/metadata@11.1.0': {}
+
+ '@vueuse/motion@2.2.6(rollup@4.21.2)(vue@3.5.2)':
+ dependencies:
+ '@vueuse/core': 10.11.1(vue@3.5.2)
+ '@vueuse/shared': 10.11.1(vue@3.5.2)
+ csstype: 3.1.3
+ framesync: 6.1.2
+ popmotion: 11.0.5
+ style-value-types: 5.1.2
+ vue: 3.5.2
+ optionalDependencies:
+ '@nuxt/kit': 3.13.2(rollup@4.21.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - magicast
+ - rollup
+ - supports-color
+ - webpack-sources
+
+ '@vueuse/shared@10.11.1(vue@3.5.2)':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/shared@11.0.3(vue@3.5.2)':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ '@vueuse/shared@11.1.0(vue@3.5.2)':
+ dependencies:
+ vue-demi: 0.14.10(vue@3.5.2)
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+ - vue
+
+ acorn@8.12.1: {}
+
+ acorn@8.14.0:
+ optional: true
+
+ algoliasearch@4.24.0:
+ dependencies:
+ '@algolia/cache-browser-local-storage': 4.24.0
+ '@algolia/cache-common': 4.24.0
+ '@algolia/cache-in-memory': 4.24.0
+ '@algolia/client-account': 4.24.0
+ '@algolia/client-analytics': 4.24.0
+ '@algolia/client-common': 4.24.0
+ '@algolia/client-personalization': 4.24.0
+ '@algolia/client-search': 4.24.0
+ '@algolia/logger-common': 4.24.0
+ '@algolia/logger-console': 4.24.0
+ '@algolia/recommend': 4.24.0
+ '@algolia/requester-browser-xhr': 4.24.0
+ '@algolia/requester-common': 4.24.0
+ '@algolia/requester-node-http': 4.24.0
+ '@algolia/transporter': 4.24.0
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.0.1: {}
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@6.2.1: {}
+
+ any-promise@1.3.0: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ arg@5.0.2: {}
+
+ argparse@2.0.1: {}
+
+ aria-hidden@1.2.4:
+ dependencies:
+ tslib: 2.7.0
+
+ asynckit@0.4.0: {}
+
+ autoprefixer@10.4.20(postcss@8.4.45):
+ dependencies:
+ browserslist: 4.23.3
+ caniuse-lite: 1.0.30001657
+ fraction.js: 4.3.7
+ normalize-range: 0.1.2
+ picocolors: 1.1.0
+ postcss: 8.4.45
+ postcss-value-parser: 4.2.0
+
+ axios@1.7.7:
+ dependencies:
+ follow-redirects: 1.15.8
+ form-data: 4.0.0
+ proxy-from-env: 1.1.0
+ transitivePeerDependencies:
+ - debug
+
+ balanced-match@1.0.2: {}
+
+ binary-extensions@2.3.0: {}
+
+ birpc@0.2.17: {}
+
+ brace-expansion@2.0.1:
+ dependencies:
+ balanced-match: 1.0.2
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.23.3:
+ dependencies:
+ caniuse-lite: 1.0.30001657
+ electron-to-chromium: 1.5.15
+ node-releases: 2.0.18
+ update-browserslist-db: 1.1.0(browserslist@4.23.3)
+
+ browserslist@4.24.2:
+ dependencies:
+ caniuse-lite: 1.0.30001674
+ electron-to-chromium: 1.5.49
+ node-releases: 2.0.18
+ update-browserslist-db: 1.1.1(browserslist@4.24.2)
+ optional: true
+
+ c12@1.11.2:
+ dependencies:
+ chokidar: 3.6.0
+ confbox: 0.1.8
+ defu: 6.1.4
+ dotenv: 16.4.5
+ giget: 1.2.3
+ jiti: 1.21.6
+ mlly: 1.7.2
+ ohash: 1.1.4
+ pathe: 1.1.2
+ perfect-debounce: 1.0.0
+ pkg-types: 1.2.1
+ rc9: 2.1.2
+ optional: true
+
+ camelcase-css@2.0.1: {}
+
+ caniuse-lite@1.0.30001657: {}
+
+ caniuse-lite@1.0.30001674:
+ optional: true
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ chownr@2.0.0:
+ optional: true
+
+ citty@0.1.6:
+ dependencies:
+ consola: 3.2.3
+ optional: true
+
+ class-variance-authority@0.7.0:
+ dependencies:
+ clsx: 2.0.0
+
+ clsx@2.0.0: {}
+
+ clsx@2.1.1: {}
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.4: {}
+
+ combined-stream@1.0.8:
+ dependencies:
+ delayed-stream: 1.0.0
+
+ commander@4.1.1: {}
+
+ compatx@0.1.8:
+ optional: true
+
+ confbox@0.1.8: {}
+
+ consola@3.2.3:
+ optional: true
+
+ convert-source-map@2.0.0:
+ optional: true
+
+ copy-anything@3.0.5:
+ dependencies:
+ is-what: 4.1.16
+
+ cross-spawn@7.0.3:
+ dependencies:
+ path-key: 3.1.1
+ shebang-command: 2.0.0
+ which: 2.0.2
+
+ cssesc@3.0.0: {}
+
+ csstype@3.1.3: {}
+
+ debug@4.3.7:
+ dependencies:
+ ms: 2.1.3
+
+ defu@6.1.4: {}
+
+ delayed-stream@1.0.0: {}
+
+ destr@2.0.3:
+ optional: true
+
+ didyoumean@1.2.2: {}
+
+ dlv@1.1.3: {}
+
+ dotenv@16.4.5:
+ optional: true
+
+ eastasianwidth@0.2.0: {}
+
+ electron-to-chromium@1.5.15: {}
+
+ electron-to-chromium@1.5.49:
+ optional: true
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ entities@4.5.0: {}
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@5.0.0:
+ optional: true
+
+ estree-walker@2.0.2: {}
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.5
+ optional: true
+
+ execa@8.0.1:
+ dependencies:
+ cross-spawn: 7.0.3
+ get-stream: 8.0.1
+ human-signals: 5.0.0
+ is-stream: 3.0.0
+ merge-stream: 2.0.0
+ npm-run-path: 5.3.0
+ onetime: 6.0.0
+ signal-exit: 4.1.0
+ strip-final-newline: 3.0.0
+ optional: true
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-glob@3.3.2:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ focus-trap@7.5.4:
+ dependencies:
+ tabbable: 6.2.0
+
+ follow-redirects@1.15.8: {}
+
+ foreground-child@3.3.0:
+ dependencies:
+ cross-spawn: 7.0.3
+ signal-exit: 4.1.0
+
+ form-data@4.0.0:
+ dependencies:
+ asynckit: 0.4.0
+ combined-stream: 1.0.8
+ mime-types: 2.1.35
+
+ fraction.js@4.3.7: {}
+
+ framesync@6.1.2:
+ dependencies:
+ tslib: 2.4.0
+
+ fs-minipass@2.1.0:
+ dependencies:
+ minipass: 3.3.6
+ optional: true
+
+ fsevents@2.3.3:
+ optional: true
+
+ function-bind@1.1.2: {}
+
+ gensync@1.0.0-beta.2:
+ optional: true
+
+ get-stream@8.0.1:
+ optional: true
+
+ giget@1.2.3:
+ dependencies:
+ citty: 0.1.6
+ consola: 3.2.3
+ defu: 6.1.4
+ node-fetch-native: 1.6.4
+ nypm: 0.3.12
+ ohash: 1.1.4
+ pathe: 1.1.2
+ tar: 6.2.1
+ optional: true
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob-parent@6.0.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ glob@10.4.5:
+ dependencies:
+ foreground-child: 3.3.0
+ jackspeak: 3.4.3
+ minimatch: 9.0.5
+ minipass: 7.1.2
+ package-json-from-dist: 1.0.0
+ path-scurry: 1.11.1
+
+ globals@11.12.0:
+ optional: true
+
+ globby@14.0.2:
+ dependencies:
+ '@sindresorhus/merge-streams': 2.3.0
+ fast-glob: 3.3.2
+ ignore: 5.3.2
+ path-type: 5.0.0
+ slash: 5.1.0
+ unicorn-magic: 0.1.0
+ optional: true
+
+ hash-sum@2.0.0:
+ optional: true
+
+ hasown@2.0.2:
+ dependencies:
+ function-bind: 1.1.2
+
+ hey-listen@1.0.8: {}
+
+ hookable@5.5.3: {}
+
+ human-signals@5.0.0:
+ optional: true
+
+ ignore@5.3.2:
+ optional: true
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-core-module@2.15.1:
+ dependencies:
+ hasown: 2.0.2
+
+ is-extglob@2.1.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-number@7.0.0: {}
+
+ is-stream@3.0.0:
+ optional: true
+
+ is-what@4.1.16: {}
+
+ isexe@2.0.0: {}
+
+ jackspeak@3.4.3:
+ dependencies:
+ '@isaacs/cliui': 8.0.2
+ optionalDependencies:
+ '@pkgjs/parseargs': 0.11.0
+
+ jiti@1.21.6: {}
+
+ jiti@2.3.3:
+ optional: true
+
+ js-tokens@4.0.0:
+ optional: true
+
+ js-tokens@9.0.0:
+ optional: true
+
+ jsesc@3.0.2:
+ optional: true
+
+ json5@2.2.3:
+ optional: true
+
+ klona@2.0.6:
+ optional: true
+
+ knitwork@1.1.0:
+ optional: true
+
+ kolorist@1.8.0: {}
+
+ lilconfig@2.1.0: {}
+
+ lilconfig@3.1.2: {}
+
+ lines-and-columns@1.2.4: {}
+
+ linkify-it@5.0.0:
+ dependencies:
+ uc.micro: 2.1.0
+
+ local-pkg@0.5.0:
+ dependencies:
+ mlly: 1.7.2
+ pkg-types: 1.2.1
+
+ lru-cache@10.4.3: {}
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+ optional: true
+
+ lucide-vue-next@0.438.0(vue@3.5.2):
+ dependencies:
+ vue: 3.5.2
+
+ magic-string@0.30.11:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ mark.js@8.11.1: {}
+
+ markdown-it@14.1.0:
+ dependencies:
+ argparse: 2.0.1
+ entities: 4.5.0
+ linkify-it: 5.0.0
+ mdurl: 2.0.0
+ punycode.js: 2.3.1
+ uc.micro: 2.1.0
+
+ mdurl@2.0.0: {}
+
+ merge-stream@2.0.0:
+ optional: true
+
+ merge2@1.4.1: {}
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ mime-db@1.52.0: {}
+
+ mime-types@2.1.35:
+ dependencies:
+ mime-db: 1.52.0
+
+ mimic-fn@4.0.0:
+ optional: true
+
+ minimatch@9.0.5:
+ dependencies:
+ brace-expansion: 2.0.1
+
+ minipass@3.3.6:
+ dependencies:
+ yallist: 4.0.0
+ optional: true
+
+ minipass@5.0.0:
+ optional: true
+
+ minipass@7.1.2: {}
+
+ minisearch@7.1.0: {}
+
+ minizlib@2.1.2:
+ dependencies:
+ minipass: 3.3.6
+ yallist: 4.0.0
+ optional: true
+
+ mitt@3.0.1: {}
+
+ mkdirp@1.0.4:
+ optional: true
+
+ mlly@1.7.2:
+ dependencies:
+ acorn: 8.12.1
+ pathe: 1.1.2
+ pkg-types: 1.2.1
+ ufo: 1.5.4
+
+ mri@1.2.0:
+ optional: true
+
+ ms@2.1.3: {}
+
+ mz@2.7.0:
+ dependencies:
+ any-promise: 1.3.0
+ object-assign: 4.1.1
+ thenify-all: 1.6.0
+
+ nanoid@3.3.7: {}
+
+ nanoid@5.0.7: {}
+
+ node-fetch-native@1.6.4:
+ optional: true
+
+ node-releases@2.0.18: {}
+
+ normalize-path@3.0.0: {}
+
+ normalize-range@0.1.2: {}
+
+ npm-run-path@5.3.0:
+ dependencies:
+ path-key: 4.0.0
+ optional: true
+
+ nypm@0.3.12:
+ dependencies:
+ citty: 0.1.6
+ consola: 3.2.3
+ execa: 8.0.1
+ pathe: 1.1.2
+ pkg-types: 1.2.1
+ ufo: 1.5.4
+ optional: true
+
+ object-assign@4.1.1: {}
+
+ object-hash@3.0.0: {}
+
+ ohash@1.1.4:
+ optional: true
+
+ onetime@6.0.0:
+ dependencies:
+ mimic-fn: 4.0.0
+ optional: true
+
+ package-json-from-dist@1.0.0: {}
+
+ package-manager-detector@0.2.2: {}
+
+ path-key@3.1.1: {}
+
+ path-key@4.0.0:
+ optional: true
+
+ path-parse@1.0.7: {}
+
+ path-scurry@1.11.1:
+ dependencies:
+ lru-cache: 10.4.3
+ minipass: 7.1.2
+
+ path-type@5.0.0:
+ optional: true
+
+ pathe@1.1.2: {}
+
+ perfect-debounce@1.0.0: {}
+
+ picocolors@1.1.0: {}
+
+ picomatch@2.3.1: {}
+
+ picomatch@4.0.2:
+ optional: true
+
+ pify@2.3.0: {}
+
+ pirates@4.0.6: {}
+
+ pkg-types@1.2.1:
+ dependencies:
+ confbox: 0.1.8
+ mlly: 1.7.2
+ pathe: 1.1.2
+
+ popmotion@11.0.5:
+ dependencies:
+ framesync: 6.1.2
+ hey-listen: 1.0.8
+ style-value-types: 5.1.2
+ tslib: 2.4.0
+
+ postcss-import@15.1.0(postcss@8.4.45):
+ dependencies:
+ postcss: 8.4.45
+ postcss-value-parser: 4.2.0
+ read-cache: 1.0.0
+ resolve: 1.22.8
+
+ postcss-js@4.0.1(postcss@8.4.45):
+ dependencies:
+ camelcase-css: 2.0.1
+ postcss: 8.4.45
+
+ postcss-load-config@4.0.2(postcss@8.4.45):
+ dependencies:
+ lilconfig: 3.1.2
+ yaml: 2.5.1
+ optionalDependencies:
+ postcss: 8.4.45
+
+ postcss-nested@6.2.0(postcss@8.4.45):
+ dependencies:
+ postcss: 8.4.45
+ postcss-selector-parser: 6.1.2
+
+ postcss-selector-parser@6.1.2:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss-value-parser@4.2.0: {}
+
+ postcss@8.4.45:
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.1.0
+ source-map-js: 1.2.0
+
+ preact@10.23.2: {}
+
+ proxy-from-env@1.1.0: {}
+
+ punycode.js@2.3.1: {}
+
+ queue-microtask@1.2.3: {}
+
+ radix-vue@1.9.5(vue@3.5.2):
+ dependencies:
+ '@floating-ui/dom': 1.6.10
+ '@floating-ui/vue': 1.1.4(vue@3.5.2)
+ '@internationalized/date': 3.5.5
+ '@internationalized/number': 3.5.3
+ '@tanstack/vue-virtual': 3.10.7(vue@3.5.2)
+ '@vueuse/core': 10.11.1(vue@3.5.2)
+ '@vueuse/shared': 10.11.1(vue@3.5.2)
+ aria-hidden: 1.2.4
+ defu: 6.1.4
+ fast-deep-equal: 3.1.3
+ nanoid: 5.0.7
+ vue: 3.5.2
+ transitivePeerDependencies:
+ - '@vue/composition-api'
+
+ rc9@2.1.2:
+ dependencies:
+ defu: 6.1.4
+ destr: 2.0.3
+ optional: true
+
+ read-cache@1.0.0:
+ dependencies:
+ pify: 2.3.0
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
+ resolve@1.22.8:
+ dependencies:
+ is-core-module: 2.15.1
+ path-parse: 1.0.7
+ supports-preserve-symlinks-flag: 1.0.0
+
+ reusify@1.0.4: {}
+
+ rfdc@1.4.1: {}
+
+ rollup@4.21.2:
+ dependencies:
+ '@types/estree': 1.0.5
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.21.2
+ '@rollup/rollup-android-arm64': 4.21.2
+ '@rollup/rollup-darwin-arm64': 4.21.2
+ '@rollup/rollup-darwin-x64': 4.21.2
+ '@rollup/rollup-linux-arm-gnueabihf': 4.21.2
+ '@rollup/rollup-linux-arm-musleabihf': 4.21.2
+ '@rollup/rollup-linux-arm64-gnu': 4.21.2
+ '@rollup/rollup-linux-arm64-musl': 4.21.2
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.21.2
+ '@rollup/rollup-linux-riscv64-gnu': 4.21.2
+ '@rollup/rollup-linux-s390x-gnu': 4.21.2
+ '@rollup/rollup-linux-x64-gnu': 4.21.2
+ '@rollup/rollup-linux-x64-musl': 4.21.2
+ '@rollup/rollup-win32-arm64-msvc': 4.21.2
+ '@rollup/rollup-win32-ia32-msvc': 4.21.2
+ '@rollup/rollup-win32-x64-msvc': 4.21.2
+ fsevents: 2.3.3
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ scule@1.3.0:
+ optional: true
+
+ search-insights@2.17.1: {}
+
+ semver@6.3.1:
+ optional: true
+
+ semver@7.6.3:
+ optional: true
+
+ shebang-command@2.0.0:
+ dependencies:
+ shebang-regex: 3.0.0
+
+ shebang-regex@3.0.0: {}
+
+ shiki@1.16.2:
+ dependencies:
+ '@shikijs/core': 1.16.2
+ '@shikijs/vscode-textmate': 9.2.0
+ '@types/hast': 3.0.4
+
+ signal-exit@4.1.0: {}
+
+ slash@5.1.0:
+ optional: true
+
+ source-map-js@1.2.0: {}
+
+ speakingurl@14.0.1: {}
+
+ std-env@3.7.0:
+ optional: true
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.0.1
+
+ strip-final-newline@3.0.0:
+ optional: true
+
+ strip-literal@2.1.0:
+ dependencies:
+ js-tokens: 9.0.0
+ optional: true
+
+ style-value-types@5.1.2:
+ dependencies:
+ hey-listen: 1.0.8
+ tslib: 2.4.0
+
+ sucrase@3.35.0:
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ commander: 4.1.1
+ glob: 10.4.5
+ lines-and-columns: 1.2.4
+ mz: 2.7.0
+ pirates: 4.0.6
+ ts-interface-checker: 0.1.13
+
+ superjson@2.2.1:
+ dependencies:
+ copy-anything: 3.0.5
+
+ supports-preserve-symlinks-flag@1.0.0: {}
+
+ tabbable@6.2.0: {}
+
+ tailwind-merge@2.5.2: {}
+
+ tailwindcss-animate@1.0.7(tailwindcss@3.4.10):
+ dependencies:
+ tailwindcss: 3.4.10
+
+ tailwindcss@3.4.10:
+ dependencies:
+ '@alloc/quick-lru': 5.2.0
+ arg: 5.0.2
+ chokidar: 3.6.0
+ didyoumean: 1.2.2
+ dlv: 1.1.3
+ fast-glob: 3.3.2
+ glob-parent: 6.0.2
+ is-glob: 4.0.3
+ jiti: 1.21.6
+ lilconfig: 2.1.0
+ micromatch: 4.0.8
+ normalize-path: 3.0.0
+ object-hash: 3.0.0
+ picocolors: 1.1.0
+ postcss: 8.4.45
+ postcss-import: 15.1.0(postcss@8.4.45)
+ postcss-js: 4.0.1(postcss@8.4.45)
+ postcss-load-config: 4.0.2(postcss@8.4.45)
+ postcss-nested: 6.2.0(postcss@8.4.45)
+ postcss-selector-parser: 6.1.2
+ resolve: 1.22.8
+ sucrase: 3.35.0
+ transitivePeerDependencies:
+ - ts-node
+
+ tar@6.2.1:
+ dependencies:
+ chownr: 2.0.0
+ fs-minipass: 2.1.0
+ minipass: 5.0.0
+ minizlib: 2.1.2
+ mkdirp: 1.0.4
+ yallist: 4.0.0
+ optional: true
+
+ thenify-all@1.6.0:
+ dependencies:
+ thenify: 3.3.1
+
+ thenify@3.3.1:
+ dependencies:
+ any-promise: 1.3.0
+
+ tinyexec@0.3.0: {}
+
+ to-fast-properties@2.0.0: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ ts-interface-checker@0.1.13: {}
+
+ tslib@2.4.0: {}
+
+ tslib@2.7.0: {}
+
+ uc.micro@2.1.0: {}
+
+ ufo@1.5.4: {}
+
+ uncrypto@0.1.3:
+ optional: true
+
+ unctx@2.3.1:
+ dependencies:
+ acorn: 8.12.1
+ estree-walker: 3.0.3
+ magic-string: 0.30.11
+ unplugin: 1.15.0
+ transitivePeerDependencies:
+ - webpack-sources
+ optional: true
+
+ undici-types@6.19.8: {}
+
+ unicorn-magic@0.1.0:
+ optional: true
+
+ unimport@3.13.1(rollup@4.21.2):
+ dependencies:
+ '@rollup/pluginutils': 5.1.3(rollup@4.21.2)
+ acorn: 8.12.1
+ escape-string-regexp: 5.0.0
+ estree-walker: 3.0.3
+ fast-glob: 3.3.2
+ local-pkg: 0.5.0
+ magic-string: 0.30.11
+ mlly: 1.7.2
+ pathe: 1.1.2
+ pkg-types: 1.2.1
+ scule: 1.3.0
+ strip-literal: 2.1.0
+ unplugin: 1.15.0
+ transitivePeerDependencies:
+ - rollup
+ - webpack-sources
+ optional: true
+
+ unplugin@1.15.0:
+ dependencies:
+ acorn: 8.14.0
+ webpack-virtual-modules: 0.6.2
+ optional: true
+
+ untyped@1.5.1:
+ dependencies:
+ '@babel/core': 7.26.0
+ '@babel/standalone': 7.26.1
+ '@babel/types': 7.26.0
+ defu: 6.1.4
+ jiti: 2.3.3
+ mri: 1.2.0
+ scule: 1.3.0
+ transitivePeerDependencies:
+ - supports-color
+ optional: true
+
+ update-browserslist-db@1.1.0(browserslist@4.23.3):
+ dependencies:
+ browserslist: 4.23.3
+ escalade: 3.2.0
+ picocolors: 1.1.0
+
+ update-browserslist-db@1.1.1(browserslist@4.24.2):
+ dependencies:
+ browserslist: 4.24.2
+ escalade: 3.2.0
+ picocolors: 1.1.0
+ optional: true
+
+ util-deprecate@1.0.2: {}
+
+ vite@5.4.3(@types/node@22.5.4):
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.4.45
+ rollup: 4.21.2
+ optionalDependencies:
+ '@types/node': 22.5.4
+ fsevents: 2.3.3
+
+ vitepress-plugin-group-icons@1.2.4:
+ dependencies:
+ '@iconify-json/logos': 1.2.3
+ '@iconify-json/vscode-icons': 1.2.2
+ '@iconify/utils': 2.1.33
+ transitivePeerDependencies:
+ - supports-color
+
+ vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.4)(axios@1.7.7)(postcss@8.4.45)(search-insights@2.17.1):
+ dependencies:
+ '@docsearch/css': 3.6.1
+ '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(search-insights@2.17.1)
+ '@shikijs/core': 1.16.2
+ '@shikijs/transformers': 1.16.2
+ '@types/markdown-it': 14.1.2
+ '@vitejs/plugin-vue': 5.1.3(vite@5.4.3(@types/node@22.5.4))(vue@3.5.2)
+ '@vue/devtools-api': 7.4.4
+ '@vue/shared': 3.5.2
+ '@vueuse/core': 11.1.0(vue@3.5.2)
+ '@vueuse/integrations': 11.0.3(axios@1.7.7)(focus-trap@7.5.4)(vue@3.5.2)
+ focus-trap: 7.5.4
+ mark.js: 8.11.1
+ minisearch: 7.1.0
+ shiki: 1.16.2
+ vite: 5.4.3(@types/node@22.5.4)
+ vue: 3.5.2
+ optionalDependencies:
+ postcss: 8.4.45
+ transitivePeerDependencies:
+ - '@algolia/client-search'
+ - '@types/node'
+ - '@types/react'
+ - '@vue/composition-api'
+ - async-validator
+ - axios
+ - change-case
+ - drauu
+ - fuse.js
+ - idb-keyval
+ - jwt-decode
+ - less
+ - lightningcss
+ - nprogress
+ - qrcode
+ - react
+ - react-dom
+ - sass
+ - sass-embedded
+ - search-insights
+ - sortablejs
+ - stylus
+ - sugarss
+ - terser
+ - typescript
+ - universal-cookie
+
+ vue-demi@0.14.10(vue@3.5.2):
+ dependencies:
+ vue: 3.5.2
+
+ vue-writer@2.0.2(vue@3.5.2):
+ dependencies:
+ vue: 3.5.2
+
+ vue@3.5.2:
+ dependencies:
+ '@vue/compiler-dom': 3.5.2
+ '@vue/compiler-sfc': 3.5.2
+ '@vue/runtime-dom': 3.5.2
+ '@vue/server-renderer': 3.5.2(vue@3.5.2)
+ '@vue/shared': 3.5.2
+
+ webpack-virtual-modules@0.6.2:
+ optional: true
+
+ which@2.0.2:
+ dependencies:
+ isexe: 2.0.0
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ yallist@3.1.1:
+ optional: true
+
+ yallist@4.0.0:
+ optional: true
+
+ yaml@2.5.1: {}
diff --git a/postcss.config.js b/postcss.config.js
new file mode 100644
index 00000000..33ad091d
--- /dev/null
+++ b/postcss.config.js
@@ -0,0 +1,6 @@
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
diff --git a/src/aloe-cli/index.md b/src/aloe-cli/index.md
deleted file mode 100755
index d9eb856a..00000000
--- a/src/aloe-cli/index.md
+++ /dev/null
@@ -1,60 +0,0 @@
-# Aloe CLI
-
-Aloe is a simple but powerful console service that makes building your leaf apps just a simple walk in the park. Aloe CLI ships with the default Leaf console tool in the newer versions of Leaf API, Leaf MVC and Skeleton.
-
-Aloe comes with a predefined set of commands which provide project scaffolding, database and app management right from the console. It also introduces a much simpler and cleaner way to write your commands.
-
-## Aloe List
-
-```bash
-ALOE
-
-Usage:
- command [options] [arguments]
-
-Options:
- -h, --help Display this help message
- -q, --quiet Do not output any message
- -V, --version Display this application version
- --ansi Force ANSI output
- --no-ansi Disable ANSI output
- -n, --no-interaction Do not ask any interactive question
- -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
-
-Available commands:
- example example command's description
- help Displays help for a command
- interact Interact with your application
- list Lists commands
- serve Start the leaf development server
- aloe
- aloe:config Install aloe config
- app
- app:down Place app in maintenance mode
- app:up Remove app from maintenance mode
- d
- d:command Delete a console command
- d:controller Delete a controller
- d:factory Delete a model factory
- d:migration Delete a migration
- d:model Delete a model
- d:seed Delete a model seeder
- db
- db:install Create new database from .env variables
- db:migrate Run the database migrations
- db:rollback Rollback all database migrations
- db:seed Seed the database with records
- env
- env:generate Generate .env file
- g
- g:command Create a new console command
- g:controller Create a new controller class
- g:factory Create a new model factory
- g:helper Create a new helper class
- g:migration Create a new migration file
- g:model Create a new model class
- g:seed Create a new seed file
- g:template Create a new view file
- scaffold
- scaffold:auth Scaffold basic app authentication
-```
diff --git a/src/aloe-cli/v/1.2.3/commands/custom.md b/src/aloe-cli/v/1.2.3/commands/custom.md
deleted file mode 100755
index 14c45a3a..00000000
--- a/src/aloe-cli/v/1.2.3/commands/custom.md
+++ /dev/null
@@ -1,107 +0,0 @@
-# Aloe CLI: Custom Commands
-
-This section talks about creating custom commands using Aloe CLI. These commands would be called through the CLI.
-
-To get started, aloe CLI provides `g:command` which scaffolds a basic command for you and even registers it, so you can go straight into working on the command's logic. The new command will be created in the default commands directory.
-
-The default directory for commands for Leaf API and Leaf MVC is `App\Console`, with skeleton, you're free to decide where to place your commands.
-
-```bash
-php leaf g:command SendMail
-```
-
-Aloe can also generate namespaced commands directly for you. You don't have to manually set namespaces as done with other CLI tools.
-
-```bash
-php leaf g:command mail:send
-```
-
-If you want to, you can even generate the command by it's name instead of it's class. Aloe is smart enough to differentiate them.
-
-```bash
-php leaf g:command shutdown
-```
-
-## Command Structure
-
-After generating your command, you should start writing what to execute once the command is called. Aloe smartly generates a command name for you, even if you create the command using the class name, however, if it doesn't match what you need, you can always change it.
-
-With the `mail:send` example above, Aloe wil generate `App\Console\MailSendCommand`, in this file, we'll have something that looks like this:
-
-```php
-comment("mail:send command's output");
- }
-}
-```
-
-We can add an argument to find the user to send the email to, and output a message while sending the email.
-These can be done in the `config` and `handle` methods respectively. [Read more](/aloe-cli/v/1.2.3/commands/io) here.
-
-```php
-public function config()
-{
- $this->setArgument("user", "required");
-}
-
-public function handle()
-{
- $user = $this->argument('user');
-
- $this->comment("Sending email to $user");
-
- $success = CustomEmailHandler::send($user);
-
- if ($success) {
- $this->info("Email sent successfully");
- } else {
- $this->error("Couldn't send email, pls try again");
- }
-}
-```
-
-## Registering Commands
-
-By default, aloe cli registers all commands generated, however, if you have a command you want to register manually, or commands from a package which need to use Aloe, you can also add them pretty easily.
-
-Simply locate the `leaf` file in the root directory of your project, open it up and find a commented section talking about custom commands.
-
-```php
-/*
-|--------------------------------------------------------------------------
-| Add custom command
-|--------------------------------------------------------------------------
-|
-| If you have a new command to add to Leaf
-|
-*/
-$console->register(\App\Console\ExampleCommand::class);
-```
-
-An example command has already been registered, so you can follow this example. Simply call the `register` method. You can also pass in an array of commands to register, as such, a custom package with a couple of commands to register can simply return an array of all those commands.
-
-```php
-$console->register([
- \App\Console\AppCommand::class,
- CustomPackage::commands(),
-]);
-```
-
-## Next Steps
-
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [libraries](/aloe-cli/v/1.2.3/libraries)
-- [G Commands](/aloe-cli/v/1.2.3/commands/g-commands)
-- [DB commands](/aloe-cli/v/1.2.3/commands/db-commands)
diff --git a/src/aloe-cli/v/1.2.3/commands/d-commands.md b/src/aloe-cli/v/1.2.3/commands/d-commands.md
deleted file mode 100755
index 251169df..00000000
--- a/src/aloe-cli/v/1.2.3/commands/d-commands.md
+++ /dev/null
@@ -1,90 +0,0 @@
-# Aloe CLI: d commands
-
-d technically stands for delete. Aloe CLI d commands technically delete some sort of file or class.
-
-## d:command
-
-This command is used to delete and unregister a custom command
-
-```bash
-Description:
- Delete a console command
-
-Usage:
- d:command
-
-Arguments:
- file The name of the console file
-```
-
-## d:controller
-
-```bash
-Description:
- Delete a controller
-
-Usage:
- d:controller
-
-Arguments:
- controller controller name
-```
-
-## d:factory
-
-```bash
-Description:
- Delete a model factory
-
-Usage:
- d:factory
-
-Arguments:
- factory factory name
-```
-
-## d:migration
-
-```bash
-Description:
- Delete a migration
-
-Usage:
- d:migration
-
-Arguments:
- file File to delete
-```
-
-## d:model
-
-```bash
-Description:
- Delete a model
-
-Usage:
- d:model
-
-Arguments:
- model model name
-```
-
-## d:seed
-
-```bash
-Description:
- Delete a model seeder
-
-Usage:
- d:seed
-
-Arguments:
- seed seeder name
-```
-
-## Next Steps
-
-- [DB Commands](/aloe-cli/v/1.2.3/commands/db-commands)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [Creating Libraries](/aloe-cli/v/1.2.3/libraries)
diff --git a/src/aloe-cli/v/1.2.3/commands/db-commands.md b/src/aloe-cli/v/1.2.3/commands/db-commands.md
deleted file mode 100755
index f5852a9c..00000000
--- a/src/aloe-cli/v/1.2.3/commands/db-commands.md
+++ /dev/null
@@ -1,61 +0,0 @@
-# Aloe CLI: DB Commands
-
-These commands help you manage and interact with your database.
-
-## db:install
-
-Create the database in your .env variables if it doesn't already exist.
-
-```bash
-Description:
- Create new database from .env variables
-
-Usage:
- db:install
-```
-
-## db:migrate
-
-```bash
-Description:
- Run the database migrations
-
-Usage:
- db:migrate [options]
-
-Options:
- -f, --file[=FILE] Rollback a particular file
- -s, --seed Run seeds after migration
-```
-
-## db:rollback
-
-```bash
-Description:
- Rollback database migrations
-
-Usage:
- db:rollback [options]
-
-Options:
- -s, --step[=STEP] The batch to rollback [default: "all"]
- -f, --file[=FILE] Rollback a particular file
-```
-
-Dont use -f and -s together
-
-## db:seed
-
-```bash
-Description:
- Seed the database with records
-
-Usage:
- db:seed
-```
-
-## Next Steps
-
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [Creating Libraries](/aloe-cli/v/1.2.3/libraries)
diff --git a/src/aloe-cli/v/1.2.3/commands/g-commands.md b/src/aloe-cli/v/1.2.3/commands/g-commands.md
deleted file mode 100755
index 6466a0b4..00000000
--- a/src/aloe-cli/v/1.2.3/commands/g-commands.md
+++ /dev/null
@@ -1,117 +0,0 @@
-# Aloe CLI: g commands
-
-These commands generate something.
-
-## g:command
-
-```bash
-Description:
- Create a new console command
-
-Usage:
- g:command
-
-Arguments:
- consoleCommand command name
-```
-
-## g:controller
-
-```bash
-Description:
- Create a new controller class
-
-Usage:
- g:controller [options] [--]
-
-Arguments:
- controller controller name
-
-Options:
- -a, --all Create a model and migration for controller
- -m, --model Create a model for controller
- -r, --resource Create a resource controller
- -w, --web Create a web(ordinary) controller
- --api Create a web(ordinary) controller
- -ar, --api-resource Create an API resource controller
- -wr, --web-resource Create a web resource controller
-```
-
-## g:factory
-
-```bash
-Description:
- Create a new model factory
-
-Usage:
- g:factory
-
-Arguments:
- factory factory name
-```
-
-## g:helper
-
-```bash
-Description:
- Create a new helper class
-
-Usage:
- g:helper
-
-Arguments:
- helper helper name
-```
-
-## g:migration
-
-```bash
-Description:
- Create a new migration file
-
-Usage:
- g:migration
-
-Arguments:
- migration migration file name
-```
-
-## g:model
-
-```bash
-Description:
- Create a new model class
-
-Usage:
- g:model [options] [--]
-
-Arguments:
- model model file name
-
-Options:
- -m, --migration Create a migration for model
-```
-
-## g:seed
-
-```bash
-Description:
- Create a new seed file
-
-Usage:
- g:seed [options] [--] []
-
-Arguments:
- model model name (optional)
- name seed name
-
-Options:
- -f, --factory Create a factory for seeder
-```
-
-## Next Steps
-
-- [d Commands](/aloe-cli/v/1.2.3/commands/d-commands)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [Creating Libraries](/aloe-cli/v/1.2.3/libraries)
diff --git a/src/aloe-cli/v/1.2.3/commands/io.md b/src/aloe-cli/v/1.2.3/commands/io.md
deleted file mode 100755
index d4259927..00000000
--- a/src/aloe-cli/v/1.2.3/commands/io.md
+++ /dev/null
@@ -1,328 +0,0 @@
-# Aloe CLI: Command IO
-
-Command IO deals with how info flows in and out of your command. Aloe provides very simple ways to deal with both input and output from your commands.
-
-## Command Input
-
-Aloe provides a bunch of methods that allow users to make some form of input into the command. Just like the rest of Leaf, aloe prioritizes simplicity, and so, you can do almost anything you need in 1 line of code. All of these methods are already available once you extend the Aloe Command class and will be accessible on `$this`. Let's look at these methods.
-
-### input
-
-This method can return an input argument or the whole symfony console input object.
-
-```php
-public function handle()
-{
- // returns the name argument
- $name = $this->input("name");
-
- // returns the whole whole input object
- $input = $this->input();
-
- // so you can do this
- $name = $input->getArgument("name");
-}
-```
-
-### setArgument
-
-This method tells Aloe that your command is expecting an argument, it's typically used inside the `config` method.
-
-It typically follows the same convention as symfony console's `addArgument` except that instead of passing in `InputArgument::state`, you just pass in the state as a string.
-
-Instead of `InputArgument::REQUIRED`, you just pass in `"required"`, any case is supported.
-
-```php
-public function config()
-{
- $this->setArgument("name", "required");
-}
-```
-
-### argument
-
-This method returns the value for a given argument passed into the command.
-
-```php
-$name = $this->argument("name");
-```
-
-### arguments
-
-This method returns all the given arguments merged with the default values.
-
-```php
-$name = $this->arguments("name");
-```
-
-### setOption
-
-This method tells Aloe that your command is expecting an inoput option, it's typically used inside the `config` method.
-
-It typically follows the same convention as symfony console's `addOption` except that instead of passing in `InputOption::state`, you just pass in the state as a string.
-
-Instead of `InputOption::VALUE_REQUIRED`, you just pass in `"required"`, any case is supported.
-
-```php
-public function config()
-{
- $this->setOption("name", "n", "required");
-}
-```
-
-### option
-
-This method returns the value for a given option passed into the command.
-
-```php
-$name = $this->option("name");
-```
-
-### options
-
-This method returns all the given options merged with the default values.
-
-```php
-$name = $this->options("name");
-```
-
-### ask
-
-This method displays some output and returns a value from the expected input, in short, it asks a question and returns the users answer.
-
-```php
-// default value yes
-$shouldDelete = $this->ask("Delete file?", "yes");
-
-if ($shouldDelete === "yes") {
- // delete file
-}
-```
-
-### askRaw
-
-This method displays some output and returns a value from the expected input as is, in short, it asks a question and returns the exact unformatted answer.
-
-```php
-// default value yes
-$shouldDelete = $this->ask("Delete file?", "yes");
-
-if ($shouldDelete === "yes") {
- // delete file
-}
-```
-
-### autoComplete
-
-Ask a question but provide auto completion for possible answers.
-
-```php
-// possible answers are an array of
-// auto complete values
-$answers = [
- "answer 1",
- "answer 2"
-];
-$answer = $this->autoComplete($question, $answers, $default);
-
-// example
-$job = $this->autoComplete("what's your job?", [
- "lawyer",
- "doctor"
-]);
-```
-
-### choice
-
-Ask a question where 1 answer must be selected from a bunch of possible answers.
-
-```php
-$answers = [
- "answer 1",
- "answer 2"
-];
-$answer = $this->choice($question, $answers, $errorMessage, $default);
-
-// example
-$answer = $this->choice("What fruit do you like?", [
- "fruit 1",
- "fruit 2"
-]);
-```
-
-### multiChoice
-
-Ask a question where multiple answers can be selected from a bunch of possible answers.
-
-```php
-$answers = [
- "answer 1",
- "answer 2"
-];
-$answer = $this->multiChoice($question, $answers, $errorMessage, $default);
-
-// example
-$answer = $this->multiChoice("What fruit do you like?", [
- "fruit 1",
- "fruit 2"
-]);
-```
-
-### secret
-
-This method prompts a user for input, but hides the keystrokes
-
-```php
-$password = $this->secret("Confirm your password");
-```
-
-### confirm
-
-Prompts the user for confirmation (y/n)
-
-```php
-if ($this->confirm("Send cash?")) {
- // send money
-} else {
- // cancel
-}
-```
-
-## Command Output
-
-Just like input methods, there are a bunch of output methods and helpers that help you output information from your command. Let's look at these methods.
-
-### output
-
-This method can output some info or return the whole symfony console output object.
-
-```php
-public function handle()
-{
- // outputs some data
- $this->output("This is output");
-
- // returns the whole whole output object
- $output = $this->output();
-
- // so you can do this
- $name = $output->writeln("This is output");
-}
-```
-
-### write
-
-Writes a message to the output.
-
-```php
-$this->write("This is some output");
-```
-
-### writeln
-
-Writes a message to the output and adds a newline at the end.
-
-```php
-$this->writeln("This is some output");
-```
-
-### comment
-
-Writes a comment styled message to the output and adds a newline at the end.
-
-```php
-$this->comment("This is some output");
-```
-
-### info
-
-Writes a info styled message to the output and adds a newline at the end.
-
-```php
-$this->info("This is some output");
-```
-
-### error
-
-Writes a error styled message to the output and adds a newline at the end.
-
-```php
-$this->error("This is some output");
-```
-
-### question
-
-Writes a question styled message to the output and adds a newline at the end.
-
-```php
-$this->question("This is some output");
-```
-
-### link
-
-Writes a link to the output and adds a newline at the end.
-
-```php
-$this->link("https://mychi.netlify.app", "Mychi");
-```
-
-## IO Helper Methods
-
-These are helper methods that can be called inside your commands anywhere. These methods typically give option to your input or output.
-
-### asQuestion
-
-asQuestion does pretty much the same thing as `question` above, except that `asQuestion` simply returns the `question` styles for text.
-
-```php
-$this->writeln("Question: " . asQuestion(" ...?"));
-```
-
-This allows you to use the question output style for only a section of your output.
-
-### asComment
-
-asComment does pretty much the same thing as `comment` above, except that `asComment` simply returns the `comment` styles for text.
-
-```php
-$this->writeln("Comment: " . asComment(" ..."));
-```
-
-This allows you to use the comment output style for only a section of your output.
-
-### asInfo
-
-asInfo does pretty much the same thing as `info` above, except that `asInfo` simply returns the `info` styles for text.
-
-```php
-$this->writeln("Info: " . asInfo(" ..."));
-```
-
-This allows you to use the info output style for only a section of your output.
-
-### asError
-
-asError does pretty much the same thing as `error` above, except that `asError` simply returns the `error` styles for text.
-
-```php
-$this->writeln("Error: " . asError(" ..."));
-```
-
-This allows you to use the error output style for only a section of your output.
-
-### asLink
-
-asLink does pretty much the same thing as `link` above, except that `asLink` simply returns the `link` option for text.
-
-```php
-$this->writeln("link: " . asLink("https://...", "display text"));
-```
-
-This allows you to display a link on only part of your output.
-
-## Next Steps
-
-- [G Commands](/aloe-cli/v/1.2.3/commands/g-commands)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [DB commands](/aloe-cli/v/1.2.3/commands/db-commands)
diff --git a/src/aloe-cli/v/1.2.3/commands/misc-commands.md b/src/aloe-cli/v/1.2.3/commands/misc-commands.md
deleted file mode 100755
index 581ba6c9..00000000
--- a/src/aloe-cli/v/1.2.3/commands/misc-commands.md
+++ /dev/null
@@ -1,50 +0,0 @@
-# Aloe CLI: Misc Commands
-
-## Serve command
-
-This command allows you to run your Leaf app using PHP's built in server.
-
-```bash
-Description:
- Start the leaf development server
-
-Usage:
- serve [options] [--] []
-
-Arguments:
- path Path to your app (in case you changed it)
-
-Options:
- -p, --port[=PORT] Port to run Leaf app on [default: 5500]
-```
-
-## Scaffolding
-
-Scaffolding is a feature that allows you to generate big blocks of code and full features without writing a single line of code. For now, auth scaffolding is the only type of scffolding available in Aloe CLI, however, it comes ready built for both APIs and web apps.
-
-### auth scaffolding
-
-This will generate views, controllers, routes and models required for authentication and provide your app with working authentication in only one command.
-
-```bash
-$ php leaf scaffold:auth
-
-Description:
- Scaffold basic app authentication
-
-Usage:
- scaffold:auth [options]
-
-Options:
- -s, --session Use session/session + JWT instead of just JWT
- -a, --api Use JWT for authentication
-```
-
-**Note that aloe will automatically use the session version on Leaf MVC and the api version on Leaf API.**
-
-## Next Steps
-
-- [DB Commands](/aloe-cli/v/1.2.3/commands/db-commands)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [Creating Libraries](/aloe-cli/v/1.2.3/libraries)
diff --git a/src/aloe-cli/v/1.2.3/getting-started/index.md b/src/aloe-cli/v/1.2.3/getting-started/index.md
deleted file mode 100755
index bcd7fe86..00000000
--- a/src/aloe-cli/v/1.2.3/getting-started/index.md
+++ /dev/null
@@ -1,171 +0,0 @@
-# Aloe CLI: Getting Started
-
-::: tip Note
-If you're using Leaf MVC or Leaf API, you can skip this page.
-:::
-
-Aloe CLI is a smart CLI that takes care of a lot of a whole lot of time consuming tasks during your development, allowing you to focus only on important stuff.
-
-**Aloe is based on the symfony console, with that, all symfony commands are also valid aloe commands and can be called through the aloe cli.**
-
-*Currently, Aloe is only fully supported by Leaf MVC and Leaf API, as some commands may not work on other setups.*
-
-For better support if you're not using Leaf MVC or Leaf API, you'll need to install Leaf MVC Core which contains all of Leaf's MVC utilities including a special autoloader and configuration...
-
-```bash
-leaf install mvc-core
-```
-
-Or with composer:
-
-```bash
-composer require leafs/mvc-core
-```
-
-## Installation
-
-After installing MVC Core, you can install Aloe with leaf CLI.
-
-```bash
-leaf install aloe
-```
-
-Or with composer:
-
-```bash
-composer require leafs/aloe
-```
-
-## Setup
-
-After installing aloe, you need to set it up so you can run commands like `php leaf ...`. To do this, simply create a file with the name you want to run in your console. eg: To run commands using `php console ...`, you'll need to create a file named `console`. With Leaf API and Leaf MVC, this file is named `leaf` which is the reason you run commmands with `php leaf ...`. We'll name this file `poison` which means we'll run commands like `php poison serve`
-
-In the `poison` file, we need to do a couple of things:
-
-- Bring in composer's autoloader
-- Bring in a custom autoloader to dynamically require your migrations, seeds and other files when they're directly initialized in the CLI.
-- Bring in our env variables
-- Finally, load up aloe and it's commands
-
-The setup used in Leaf MVC looks like this:
-
-```php
-#!/usr/bin/env php
- 'app/controllers',
- 'modelsPath' => 'app/models',
- 'migrationsPath' => 'app/database/migrations',
- 'seedsPath' => 'app/database/seeds',
- 'factoriesPath' => 'app/database/factories',
- 'helpersPath' => 'app/helpers',
- 'viewsPath' => 'app/views',
- 'configPath' => 'config',
- 'storagePath' => 'storage',
- 'commandsPath' => 'app/console',
- 'routesPath' => 'app/routes',
- 'libPath' => 'lib',
- 'publicPath' => 'public',
- 'databaseStoragePath' => 'storage/app/db'
-]);
-```
-
-This config tells aloe where to find everything it needs to get going. Under the hood, any work needed will be done for you. From here, it's simply a matter of adding our env, initializing our database and aloe.
-
-```php
-/*
-|--------------------------------------------------------------------------
-| Bring in (env)
-|--------------------------------------------------------------------------
-|
-| Quickly use our environment variables
-|
-*/
-try {
- \Dotenv\Dotenv::createUnsafeImmutable(__DIR__)->load();
-} catch (\Throwable $th) {
- trigger_error($th);
-}
-
-/*
-|--------------------------------------------------------------------------
-| Additional Leaf Database Config
-|--------------------------------------------------------------------------
-|
-| Load leaf database configuration
-|
-*/
-Leaf\Database::config(DatabaseConfig());
-Leaf\Database::connect();
-
-/*
-|--------------------------------------------------------------------------
-| Initialise Leaf CMD
-|--------------------------------------------------------------------------
-|
-| Initialise aloe CLI
-|
-*/
-$console = new \Aloe\Console("Leaf MVC", "v3.0");
-
-/*
-|--------------------------------------------------------------------------
-| Add commands
-|--------------------------------------------------------------------------
-|
-| Add custom commands
-|
-*/
-$console->register(\App\Console\ExampleCommand::class);
-
-/*
-|--------------------------------------------------------------------------
-| Run The console Application
-|--------------------------------------------------------------------------
-|
-| Transport water and dissolved substances to the rest of Leaf😂
-|
-*/
-$console->run();
-```
-
-Leaf API's config includes a little twist which lets Aloe run in API first mode. Which means aloe will run the API centered version of commands if available.
-
-```php
-\Aloe\Command\Config::$env = "API";
-```
-
-So depending on your use case, the API commands may be of more use.
-
-## Next Steps
-
-- [DB Commands](/aloe-cli/v/1.2.3/commands/db-commands)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [Creating Libraries](/aloe-cli/v/1.2.3/libraries)
diff --git a/src/aloe-cli/v/1.2.3/index.md b/src/aloe-cli/v/1.2.3/index.md
deleted file mode 100644
index b62439b0..00000000
--- a/src/aloe-cli/v/1.2.3/index.md
+++ /dev/null
@@ -1,113 +0,0 @@
-# Sunset Aloe (BETA)
-
-v1.1 beta is the secomd release of Aloe CLI which introduces full support for Leaf MVC, new features, better support for custom libraries and so much more. Sunset Aloe also introduces integrations with Leaf Auth, creating a scaffold option to make authentication available in your app with only 1 command.
-
-## What's new
-
-### Better Leaf MVC support
-
-Sunset Aloe is the first version of Aloe integrated out of the box with Leaf MVC. As such, it ships a tight integration with Leaf MVC and the already made integrations that come with Leaf API. So now, your Leaf MVC CLI is powered by aloe.
-
-### Auth Scaffolding
-
-Sunset also includes auth scaffolding which simply allows you to add basic session based auth (login, signup, update profile and guards) to your app by simply running one command.
-
-```bash
-php leaf scaffold:auth
-```
-
-### Updated Stubs
-
-These are basic templates generated when you run commands like `g:controller`. These templates have been updated to keep you up to date with both internal and external updates from Leaf API and Leaf MVC.
-
-### Aloe Installer Class
-
-Another major update to Aloe is the inclusion of Aloe Installer which basically takes the stress out of making libraries which need to install files/routes in the working directory.
-
-```php
-use Aloe\Installer;
-
-Installer::magicCopy($folderToInstall);
-Installer::installRoutes("$folderToInstall/routefiles/");
-```
-
-**Installer currently only supports Leaf MVC and Leaf API.**
-
-### Updated Packages
-
-All dependencies of Aloe have been updated. This includes security patches and a bunch of updates to keep aloe up to date. Also, the core library behind aloe, symfony console has been updated as well, however, we do our best to maintain Aloe CLI's syntax, structure and config, so despite all the updates and external changes, the Aloe you know never changes.
-
-### Protected command methods
-
-To match the symfony console, Aloe also uses protected command methods in this version.
-
-```php
-protected function config()
-{
- $this
- ->setArgument("argument", "optional", "argument description")
- ->setOption("option", "o", "required", "option description");
-}
-
-protected function handle()
-{
- $this->comment(
- "example command's output {$this->argument('argument')} {$this->option('option')}"
- );
-}
-```
-
-## Aloe List
-
-```bash
-Leaf MVC v2.0
-
-Usage:
- command [options] [arguments]
-
-Options:
- -h, --help Display help for the given command. When no command is given display help for the list command
- -q, --quiet Do not output any message
- -V, --version Display this application version
- --ansi Force ANSI output
- --no-ansi Disable ANSI output
- -n, --no-interaction Do not ask any interactive question
- -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
-
-Available commands:
- example example command's description
- help Displays help for a command
- interact Interact with your application
- list Lists commands
- serve Start the leaf development server
- aloe
- aloe:config Install aloe config
- app
- app:down Place app in maintenance mode
- app:up Remove app from maintenance mode
- d
- d:command Delete a console command
- d:controller Delete a controller
- d:factory Delete a model factory
- d:migration Delete a migration
- d:model Delete a model
- d:seed Delete a model seeder
- db
- db:install Create new database from .env variables
- db:migrate Run the database migrations
- db:rollback Rollback all database migrations
- db:seed Seed the database with records
- env
- env:generate Generate .env file
- g
- g:command Create a new console command
- g:controller Create a new controller class
- g:factory Create a new model factory
- g:helper Create a new helper class
- g:migration Create a new migration file
- g:model Create a new model class
- g:seed Create a new seed file
- g:template Create a new view file
- scaffold
- scaffold:auth Scaffold basic app authentication
-```
diff --git a/src/aloe-cli/v/1.2.3/installer.md b/src/aloe-cli/v/1.2.3/installer.md
deleted file mode 100644
index d2147d2b..00000000
--- a/src/aloe-cli/v/1.2.3/installer.md
+++ /dev/null
@@ -1,56 +0,0 @@
-# Aloe Installer
-
-Aloe installer allows you to quickly install files and routes from your library into the working directory. Aloe installer currently only suports Leaf MVC and Leaf API.
-
-To get started with Aloe installer, just import the package into your app or directly use the method you want to use directly.
-
-```php
-use Aloe\Installer;
-
-// or
-
-Aloe\Installer::method();
-```
-
-## Magic Copy
-
-This method allows you to auto-magically copy all files and folders from a specified folder into Leaf workspace.
-
-```php
-Aloe\Installer::magicCopy("package/to/install");
-```
-
-Consider the following directory structure:
-
-```bash
-C:.
-└───Auth
- ├───Controllers
- ├───Routes
- └───Views
-```
-
-To copy our controllers, routes and views, we simply need to point `magicCopy` to the auth directory.
-
-```php
-Aloe\Installer::magicCopy("package/Auth");
-```
-
-This will copy the sub directories in Auth to the `App` folder in the working directory.
-
-## Install Routes
-
-Similarly, you can also automatically install routes from your package routes in your app after you've copied them into the working routes directory.
-
-Installing routes involves referencing routes files in the main route file.
-
-```php
-Aloe\Installer::installRoutes("package/Auth/Routes");
-```
-
-## Next Steps
-
-- [g Commands](/aloe-cli/v/1.2.3/commands/g-commands)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [db commands](/aloe-cli/v/1.2.3/commands/db-commands)
diff --git a/src/aloe-cli/v/1.2.3/libraries.md b/src/aloe-cli/v/1.2.3/libraries.md
deleted file mode 100755
index bb11a863..00000000
--- a/src/aloe-cli/v/1.2.3/libraries.md
+++ /dev/null
@@ -1,22 +0,0 @@
-# Aloe CLI: Libraries
-
-This section talks about using and creating libraries for Aloe CLI, as well as some best practices in terms of custom libraries.
-
-## Plugging in libraries
-
-As seen in [registering commands](/aloe-cli/v/1.2.3/commands/custom?id=registering-commands), Aloe provides a neat `register` method which allows you to extend aloe's command range. Aloe libraries usually take advantage of this to return an array instead of manually returning commands one by one.
-
-```php
-$console->register(\Aloe\UI::commands());
-```
-
-## Creating your own libraries
-
-Aloe libraries simply serve a bunch of commands to the Aloe CLI. ALoe CLI has full support for Symfony console commands, so all symfony commands can also be run through Aloe CLI. After defining all your commands, you can simply return all their classes as an array to be registered.
-
-## Next Steps
-
-- [Installer](/aloe-cli/v/1.2.3/installer)
-- [Custom commands](/aloe-cli/v/1.2.3/commands/custom)
-- [Commands IO](/aloe-cli/v/1.2.3/commands/io)
-- [db commands](/aloe-cli/v/1.2.3/commands/db-commands)
diff --git a/src/changes.md b/src/changes.md
deleted file mode 100644
index e5f49edb..00000000
--- a/src/changes.md
+++ /dev/null
@@ -1,929 +0,0 @@
-
-# Changelog
-
-## v3.4.0 - 🥀 Hello Darkness - 19 May 2023
-
-### Added
-
-- Added support for library scripts
-- Added Eien config
-- Added support for named middleware
-
-### Changed
-
-- Moved ALL error handling responsibilities to `\Leaf\Exception`
-
-### Removed
-
-- Moved module initializers to scripts
-
-## v3.3.1 - 🌺 Midnight Wine '1' - 11 Mar 2023
-
-### Fixed
-
-- Patched up `app` config resetting after new values are added
-- Improved performance of application config setting on first instance
-
-## v3.3.0 - 🌺 Midnight Wine - 27 Feb 2023
-
-### Added
-
-- Added support for Eien websockets
-
-### Fixed
-
-- Hard set status on CSRF error
-- Fixed non-static methods error
-
-### Changed
-
-### Removed
-
-- Removed obsolete code
-
-
-
-## v3.2.2-beta - 🌺 Viola “Black Delight” [Eien Compat Build 2] - 25 Dec 2022
-
-### Added
-
-- Added support for Eien websockets
-
-### Fixed
-
-- Fixed non-static methods error
-- Fixed issue with CSRF error
-
-### Removed
-
-- Removed obsolete code
-
-## v3.2.0 - 🌺 Viola “Black Delight” - 3 Oct 2022
-
-### Added
-
-- Made leaf config reactive
-
-### Fixed
-
-- Fixed issue [`debug = false` not working as expected](https://github.com/leafsphp/leaf/issues/152)
-- Fixed issue with setRequestClass
-- Updated references to renamed methods
-
-### Changed
-
-- Updated leaf modules
-- Removed version constraints from modules
-- Updated tests
-
-### Removed
-
-- Removed obsolete methods
-
-## v3.1.1 - 🌷 Cantor Black '1' - 10 Sep 2022
-
-### Fixed
-
-- [Fix error: Cannot use Container as array](https://github.com/leafsphp/leaf/commit/9d51e6bfc8a246d688ad8848f17cdf7eddaaf8e5)
-
-### Changed
-
-- Updated Leaf Http
-
-## v3.1.0 - 🌷 Cantor Black - 11 Aug 2022
-
-### Added
-
-- Allow custom response object
-- Allow custom request object
-
-## v3.0 - 👸🏼 Queen Of The Night - 15 Apr, 2022
-
-### Added
-
-- Added support for global functions
-- Added unit tests
-- Added pestphp
-- Added more support for configuring with env variables.
-- Added `script` method on `app` to handle modes.
-- Added automatic loading for major modules.
-- Added CSRF handler.
-- Added autoloading for the CSRF module
-- Added CORS handler for `leafs/cors`
-- Updated error pages
-- Added `.env` precedence over local config
-- Added support for recursive config
-- Added support for nested config
-- Added support for custom setting groups
-- Switched to leaf exceptions
-
-### Fixed
-
-- Fixed PHP 7.3 unsupported types
-- Created a standard for functional mode
-- Revamped error pages
-- Fixed potential type errors
-- Fixed malformed JWT error on auth module
-- Added single state for container settings and leaf config
-- Fixed breaks in PHP 8+
-
-### Changed
-
-- You no longer need to initialize Leaf.
-- Moved `Leaf\Http` namespace to HTTP module
-- Moved base controller, model, database and to `mvc-core` module
-- Disabled logging by default
-- Moved bareui, fs, auth, form, cookies, session, db and date into modules
-- Moved `Leaf\Router` into installable modules.
-- Changed leaf router `add` to `use`
-- Tied leaf router directly to `Leaf\App`
-- Upgraded all dependencies
-- Added strict types
-
-### Removed
-
-- Removed unused dependencies
-- Removed experimental features
-- Removed unused initializers
-- Removed `evadeCors` method on leaf
-- Removed `Leaf\Router::getRequestMethod`
-- Removed unnecessary code to improve performance
-- Removed app instance on middleware
-- Removed unused helper functions
-- Removed leftover files from clean up
-
-## v3.0 (Release Candidate 2) - 👸🏼 Queen Of The Night (RC 2) - 27 Jan, 2022
-
-### Added
-
-- Added support for global functions
-- Added unit tests
-- Added pestphp
-- Added more support for configuring with env variables.
-- Added `script` method on app to handle modes.
-- Added automatic loading for major modules.
-- Added CSRF handler.
-- Added autoloading for CSRF module
-- Added CORS handler for `leafs/cors`
-- Updated error pages
-- Added `.env` precedence over local config
-- Added support for recursive config
-- Added support for nested config
-- Added support for custom setting groups
-- Switched to leaf exceptions
-
-### Fixed
-
-- Fixed PHP 7.3 unsupported types
-- Created a standard for functional mode
-- Revamped error pages
-- Fixed potential type errors
-- Fixed malformed JWT error on auth module
-- Added single state for container settings and leaf config
-- Fixed breaks in PHP 8+
-
-### Changed
-
-- You no longer need to initialize Leaf.
-- Moved `Leaf\Http` namespace to Http module
-- Moved base controller, model, database and to mvc-core module
-- Disabled logging by default
-- Moved bareui, fs, auth, form, cookies, session, db and date into modules
-- Moved `Leaf\Router` into installable module.
-- Changed leaf router `add` to `use`
-- Tied leaf router directly to `Leaf\App`
-- Upgraded all dependencies
-- Added strict types
-
-### Removed
-
-- Removed unused dependencies
-- Removed experimental features
-- Removed unused initializers
-- Removed `evadeCors` method on leaf
-- Removed `Leaf\Router::getRequestMethod`
-- Removed unnecessary code to improve performance
-- Removed app instance on middleware
-- Removed unused helper functions
-- Removed left over files from clean up
-
-## v3.0 (Beta) - 27 November
-
-### Added
-
-- Added support for global functions
-- Added more support for configuring with env variables.
-- Added `script` method on app to handle modes.
-- Added automatic loading for major modules.
-- Added CSRF handler.
-- Added autoloading for CSRF module
-- Added CORS handler for `leafs/cors`
-- Updated error pages
-- Added `.env` precedence over local config
-
-### Fixed
-
-- Fixed PHP 7.3 unsupported types
-- Created a standard for functional mode
-- Revamped error pages
-- Fixed potential type errors
-
-### Changed
-
-- You no longer need to initialize Leaf.
-- Moved `Leaf\Http` namespace to Http module
-- Moved base controller, model, database and to mvc-core module
-- Disabled logging by default
-- Moved bareui, fs, auth, form, cookies, session, db and date into modules
-- Moved `Leaf\Router` into installable module.
-- Changed leaf router `add` to `use`
-- Tied leaf router directly to `Leaf\App`
-- Upgraded all dependencies
-
-### Removed
-
-- Removed unused dependencies
-- Removed experimental features
-- Removed unused initializers
-- Removed `evadeCors` method on leaf
-- Removed `Leaf\Router::getRequestMethod`
-- Removed unnecessary code to improve performance
-- Removed app instance on middleware
-- Removed unused helper functions
-
-## v3.0 (Alpha) - 👸🏼 Queen Of The Night
-
-### Added
-
-- Added support for global functions
-- Added more support for configuring with env variables.
-- Added `script` method on app to handle modes.
-- Added automatic loading for major modules.
-- Added CSRF handler.
-- Added autoloading for CSRF module
-- Added CORS handler for `leafs/cors`
-- Updated error pages
-- Added `.env` precedence over local config
-
-### Fixed
-
-- Fixed PHP 7.3 unsupported types
-- Created a standard for functional mode
-- Revamped error pages
-- Fixed potential type errors
-
-### Changed
-
-- You no longer need to initialize Leaf.
-- Moved `Leaf\Http` namespace to Http module
-- Moved base controller, model, database and to mvc-core module
-- Disabled logging by default
-- Moved bareui, fs, auth, form, cookies, session, db and date into modules
-- Moved `Leaf\Router` into installable module.
-- Changed leaf router `add` to `use`
-- Tied leaf router directly to `Leaf\App`
-- Upgraded all dependencies
-
-### Removed
-
-- Removed unused dependencies
-- Removed experimental features
-- Removed unused initializers
-- Removed `evadeCors` method on leaf
-- Removed `Leaf\Router::getRequestMethod`
-- Removed unnecessary code to improve performance
-- Removed app instance on middleware
-- Removed unused helper functions
-
-## v2.6.0 - ⚰️ The Goodbye Flower - 20th September, 2021
-
-### Added
-
-- Added UUID support to Leaf Auth
-- Added support for custom id keys in Leaf Auth
-
-### Fixed
-
-- Fixed Request::getUrl
-- Fixed issue [#53](https://github.com/leafsphp/leaf/issues/53)
-- Fixed Database
-
-### Removed
-
-- Removed Leaf blade component
-
-## v2.5.1 - 💠 Lilac - 30th May, 2021
-
-### Fixed
-
-- Fixed PHP 7.3 unsupported types
-- Fixed server base path on router
-- Fixed bare UI config method
-- Fixed faker namespace
-
-### Changed
-
-- Removed BETA flag from Leaf password helper
-
-### Removed
-
-- Removed Leaf blade component
-
-## v2.5.0 - 💠 Gladiolus - 27th April, 2021
-
-### Added
-
-- Leaf debug now controls error reporting (you don't want nasty errors showing in production)
-- Added `Request::try`
-- Added `app.down` config
-- Added Leaf app instance on `Config`
-- Added grouped namespaces to router
-- Added single route namespaces
-- Added named routes to router
-- Added router `push` for switching between pages
-- Added more customizations on `Leaf\Database`
-- Added simple flash messaging with `Leaf\Flash`
-- Added `flash` method to session
-- Added HTTP caching on `Leaf\Http\Headers`
-
-### Fixed
-
-- Fixed inverted condition for showing default development/production error pages.
-- Fixed router hooks
-- Added proper types on `App` and `Router`
-- Added proper controller and missing method warnings
-- Fixed incorrect method labeling
-- Fixed HTTP caching issues
-- Fixed app logger and app log writer
-- Fixed app break after non-existent middlware call
-
-### Changed
-
-- Switched debugging controls from `mode` to `debug`
-- Default 404 page now automatically loaded
-- Router middleware `App` instance now automatically loaded
-- Added null response for unset session variables
-- Leaf error handler now loads on `App` init
-- Default error 500 handler now automatically loaded
-- Updated leaf container
-
-### Removed
-
-- Removed unnecessary code from `App`
-- Removed app name
-- Removed `view` method on app and router
-- Removed previous hook support on app
-- Removed unused router config
-- Removed Leaf environment class
-- Removed unused default middleware
-- `Leaf\Blade` no longer comes with Leaf by default.
-- Removed `status` and `contentType` on Leaf\App
-
-## v2.5.0-beta - 💠 Gladiolus (BETA) - 16th April, 2021
-
-### Added
-
-- Added `app.down` config
-- Added Leaf app instance on `Config`
-- Added grouped namespaces to router
-- Added named routes to router
-- Added router group prefixes
-- Added router `push` for switching between pages
-- Added more customizations on `Leaf\Database`
-- Added simple flash messaging with `Leaf\Flash`
-- Added `flash` method to session
-- Added HTTP caching on `Leaf\Http\Headers`
-
-### Fixed
-
-- Fixed router hooks
-- Added proper types on `App` and `Router`
-- Added proper controller and missing method warnings
-- Fixed incorrect method labeling
-- Fixed HTTP caching issues
-- Fixed app logger and app log writer
-- Fixed app break after non-existent middlware call
-
-### Changed
-
-- Default 404 page now automatically loaded
-- Router middleware `App` instance now automatically loaded
-- Added null response for unset session variables
-- Leaf error handler now loads on `App` init
-- Default error 500 handler now automatically loaded
-- Updated leaf container
-
-### Removed
-
-- Removed unnecessary code from `App`
-- Removed app name
-- Removed `view` method on app and router
-- Removed previous hook support on app
-- Removed unused router config
-- Removed Leaf environment class
-- Removed unused default middleware
-- `Leaf\Blade` no longer comes with Leaf by default.
-- Removed `status` and `contentType` on Leaf\App
-
-## v2.4.4 - 🎋 Common Reed - 23rd March 2021
-
-### Added
-
-- Added `Leaf\Config` for easier configuration
-- Added new leaf config options
-- Added `Leaf\View`
-- Added support for multiple template engines concurrently
-- Added BareUI templating engine
-
-### Fixed
-
-- Internal code improvements on App
-
-### Changed
-
-- No renames, restructures, ...
-
-### Removed
-
-- No removals
-
-## v2.4.3 - 🎋 Giant Cane Grass - 26th February 2021
-
-### Added
-
-- Updated `Leaf\Db` and `Leaf\Auth` to throw dev errors to Leaf's error handler for better error reporting
-
-### Fixed
-
-- Organized methods in `Leaf\FS`
-
-### Changed
-
-- Made `Leaf\Http\Response` static
-- Made `Leaf\Http\Request` static
-
-### Removed
-
-- No removals
-
-## v2.4.2 - 🥬 Desert Wishbone-bush - 3rd February 2021
-
-This version of Leaf continues the goal of making Leaf features more flexible and increasing usability.
-
-### Added
-
-- Added option to turn off experimental method warnings
-
-- Added `Form::rule` which allows you to create your own rules for form validation.
-
-```php
-Form::rule("max", function ($field, $value, $params) {
- if (strlen($value) > $params) {
- Form::addError($field, "$field can't be more than $params characters");
- return false;
- }
-});
-```
-
-- Added internal `Leaf\Form` feature which allows you to pass parameters to validation rules.
-
-```php
-$validation = Form::validate([
- // To pass a param to a rule, just use :
- "username" => "max:3",
-]);
-```
-
-- Added `Form::addError` which allows you to add errors to be returned in `Form::errors()`
-
-```php
-Form::addError($field, "$field can't be more than $params characters");
-```
-
-- Added max and min rules by default
-
-```php
-$validation = Form::validate([
- "username" => "max:1",
- "password" => "min:81",
-]);
-```
-
-- Guards can be used even in API mode. This will alert you if you're not eligible to view a particular page.
-
-### Fixed
-
-- Updated dependencies with security patches
-
-- Fixed multiple validation break from v2.4.2 beta.
-
-### Changed
-
-- Made `Leaf\Form` methods static. They can now be called from anywhere within your Leaf app.
-
-### Removed
-
-- No removals
-
-## v2.4.2 [BETA] - 🥬 Desert Wishbone-bush (Beta) - 20th January 2021
-
-This release mainly focuses on security patches for all Leaf based libraries. It contains updated dependencies and internal code patches to make your apps even more secure.
-
-### Added
-
-- No additions
-
-### Fixed
-
-- Updated dependencies with security patches
-
-### Changed
-
-- Made `Leaf\Auth` methods static. They can now be called from anywhere within your Leaf app.
-
-### Removed
-
-- No removals
-
-## v2.4.1 - 🍁 Marvel-of-peru - 12th January 2020
-
-v2.4.1 continues the usability reforms from the previous versions. It also contains fixes for all bugs discovered in previous versions as well as new features.
-
-**Please update from v2.4.0 to v2.4.1 to fix any issues you encountered with the system. Any inconveniences are deeply regretted🙏.**
-
-### Added
-
-- Added support for session based authenticatication instead of just JWT
-- Added `Route::view`
-
-### Fixed
-
-- Fixed all known bugs from previous versions
-
-### Changed
-
-- Separated Router module from app module
-- Made all `Leaf\Http\Session` methods static
-
-### Removed
-
-- Removed app down feature
-
-## v2.4.0 - Christmas Tree🎄 - 18th December 2020 ***DELETED***
-
-**Please update from v2.4.0 to v2.4.1 to fix any issues you encountered with this version. Any inconveniences are deeply regretted🙏. This release has officially been deleted.**
-
-Christmas tree follows up on the previous beta release, fixes up all bugs found during the beta testing phase and packs in newer extensions that make Leaf even more usable.
-
-### Added
-
-- Added base factory class for Leaf MVC, Leaf API and Skeleton
-- Added new auth setting options
-
-### Fixed
-
-- Fixed `Leaf\Db` callstack not clearing
-- Fixed `Auth::update` db errors
-- Fixed `Auth::update` including current user in uniques check
-- Fixed password verify method params
-
-### Changed
-
-- Switched default password encryption to `PASSWORD_DEFAULT` (bcrypt by default)
-- Auth now relies on Leaf password helper for everything password related
-- Standardized all `where` type methods on `Leaf\Db`
-- Seperated password encoding and password verifying settings in `Leaf\Auth`
-- Switched password helper methods to camelCase
-- Switched password `salt` with `spice` to add additional security to passwords
-
-### Removed
-
-- Removed unnecessary methods from password helper
-
-## v2.4.0 - BETA - 30th November, 2020
-
-Unlike previous versions, this version of Leaf is focusing on improving the use of existing features, rather than just pumping new magic into Leaf. It has a lot of bug fixes, standardization of method names and overall upgrades.
-
-### Added
-
-- Added `App::evadeCors`
-- Added `App::routes` to preview all routes
-- Added `Db::first()`
-- Leaf DB can now detect query type even when `query`
-- Added `orWhere`, `whereLike`, `orWhereLike` `like`, `orLike`, `orderBy`, `all` `limit` and LIKE helpers to Leaf Db
-- Added new format to `Date::now`
-- Added `Auth::update`
-- Added custom token lifetime support on `Auth`
-
-### Fixed
-
-- Fixed login bug with `Auth::currentUser`
-- Fixed Leaf DB same value bug
-- Minor fixes on `Auth::login` and `Auth::register`
-
-### Changed
-
-- Switched methods to camel case
-- Renamed `Auth::useToken` to `Auth::id`
-- Renamed `Auth::currentUser` to `Auth::user`
-- Made `Helpers\JWT` and `Helpers\Authentication` methods static
-
-### Removed
-
-- Removed `Form::isEmpty` and `Form::isNull`
-- Removed deprecated methods from `Response`
-- Removed deprecated methods from `Date`
-
-## v2.3.0 - Lucky Charm🍀 - Aug 15, 2020
-
-### Added
-
-- Added Leaf\Auth::useToken
-- Added Leaf\FS::upload_file
-- Added manual init to Leaf\Session
-- Added option for status code messages
-- Added callable utils
-- Added session encoding/decoding
-- Leaf\Http\Request now catches files passed into request
-- Added Leaf\Http\Request::typeIs
-- Leaf\Http\Request::get can now return multiple request data at once
-- Added Leaf\Http\Request::files
-- New Leaf\Http\Headers package
-- More untracked additions
-
-### Fixed
-
-- fixed Leaf\Http\Headers
-- Fixed response http status codes bug
-- Fixed header integration with response
-- Fixed header reliance on Set
-- Fixed throwErr code error
-- Fixed Leaf\Session package
-- Fixed response redirect
-- Fixed Leaf\Http\Request::body bugs
-- Sessions return false instead of throwing errors (Fix for web apps)
-- FS returns false instead of throwing errors
-- Fixed up Leaf\Http\Request::params
-- Fixed up Leaf\Http\Request::hasHeader
-- Fixed up header related methods on Leaf\Http\Request
-- Fixed bugs on Leaf\Environment
-- More untracked fixes
-
-### Changed
-
-- Switched Leaf\Session to native PHP sessions
-- Switched session package in Leaf\App
-- Changed controller file uploads to Leaf\FS
-- Leaf\Date methods can now be called static-ly
-- Switched Leaf\Date methods to camel case, but- with backward compatability for snake_case
-- Made all Leaf\FS methods static
-
-### Removed
-
-- Removed old session code
-- Removed setEncryptedCookie and getEncryptedCookie- on Leaf\App
-- Slashed unnecessary code from Leaf\Http\Request
-- Slashed unnecessary code from Leaf\Http\Session
-- Slashed unnecessary code from Leaf\Http\Cookie
-- Slashed unnecessary code from Leaf\Http\Response
-- Removed all method type tests from Leaf\Http\Request
-
-## v2.2.0 - Angel's Trumpet - Jul 7, 2020
-
-### Added
-
-- Added `Leaf\Auth::currentUser`
-- Added new cookies package relying on PHP's setcookie
-
-### Fixed
-
-- fixed hidden fields on Leaf\Auth::login
-- Fixed multiple-request type data on get and body at Leaf\Http\Request
-
-### Changed
-
-- Switched cookies package in Leaf\Http\Response
-- Switched cookies package in Leaf\App
-
-### Removed
-
-- Removed old cookies package and all it's methods
-- Removed setEncryptedCookie and getEncryptedCookie on Leaf\App
-- Slashed unnecessary code from Leaf\Http\Request
-
-## v2.1.0 - Elderberry - 19th June, 2020
-
-### Added
-
-- Added `Leaf\Auth::auto_connect`
-- Added default bypass for CORS errors
-- Added `Mysqli::auto_connect`
-- Added optional `db_type` option to `Leaf\Db\PDO` connection
-- Added `PDO::auto_connect`
-- Added deprecation warning for `Leaf\Db\PDO`
-
-### Fixed
-
-### Changed
-
-### Removed
-
-- Removed Leaf\Wynter
-
-## v2.1.0 - alpha - 24th May, 2020
-
-### Added
-
-- Added Route::resource
-- Added Session::retrieve
-
-### Fixed
-
-### Changed
-
-- Seperated Leaf Veins from Leaf Package
-- Renamed Session::getBody to Session::body
-
-### Removed
-
-- Removed Leaf\View
-
-## v2.0 - official - 21st April, 2020
-
-### Added
-
-- Added Leaf Mail
-- Added Date::days_ago
-- Added Date::months_ago
-- Added Date::years_ago
-- Added Date::day
-- Added Date::month
-- Added Date::year
-- Added Auth::setSecretKey
-- Added Auth::getSecretKey
-- Added Auth::validate
-- Added Leaf JS Scripts [BETA]
-- Added Leaf Envryption Helper [BETA]
-- Added Leaf Password Helper [BETA]
-- Added secret key for token encryption in Leaf Authentication
-
-### Fixed
-
-- Fixed Request::params
-- Fixed Request::getBody
-- Fixed Request Method Tests
-- Fixes to Auth::validateToken
-- Fixed bugs with Leaf DB packages
-- Fixed bugs on Auth::login and register
-- Fixed base64 security issues on Leaf Token [BETA]
-- Fixes on Form::isEmpty and isNull
-
-### Changed
-
-- Renamed Request `getBody` to `body`
-- Switched all `Date` methods to `snake_case`
-- Switched `FS` methods to `snake_case`
-- Shortened `Date` method names (Find out more in the [docs](https://leafphp.netlify.com/))
-- Made Leaf Authentication a helper (Leaf\Helper\Authentication)
-
-### Removed
-
-- Removed Response::count
-- Removed Response::getIterator
-- Removed Response header offeset methods
-
-## v2.0 - beta - 11th March, 2020
-
-### Added
-
-- Added DB->choose
-- Added DB->add
-- Added Auth->login
-- Added Auth->register
-- Added Session->unset
-- Added custom constructor to response
-- Added Response->messages(Http codes)
-- Added Response->setStatus/getStatus/status
-- Added Response->setHeader/getHeader/header
-- Added Response->setCookie/deleteCookie
-- Added Response->redirect
-- Added Request type checks
-- Added Request->cookies
-- Added Request->headers
-- Added Response Helpers
-- Added Leaf\Headers
-- Added Leaf\Cookies
-- Added ContentTypes Middleware
-- Added Flash messaging Middleware
-- Added PrettyExceptions Middleware
-- Added Logwriter and Log
-- Added Leaf View
-- Merged the Leaf Veins Templating engine and Leaf Core
-- Added Support for blade templating with Leaf Blade
-- Added support for more request types on Leaf::Request
-- Added Form::validateField
-- Provided security against XSS
-- Added Form::submit
-
-### Fixed
-
-- Fixed SESSION->id
-- Fixed headers bug with Response->respondWithCode
-- Fixed headers bug with Response->throwErr
-
-### Changed
-
-- Changed Leaf\Core namespace to Leaf
-- Changed Session->remove to Session->unset
-
-### Removed
-
-- Removed Auth->basicLogin
-- Removed Auth->emailLogin
-- Removed Auth->basicRegister
-
-## v1.5.0 - 11th December, 2019
-
-### Added
-
-- Added FS->deleteFolder
-- Added FS->deleteFile
-- Added Form->validate😅
-- Added Form->validate and return errors to base controllers
-- Added Leaf\Core\Str: equivalent of Illuminate\Support\Str with added methods
-- Added Leaf Mysqli🤔
-- Added Leaf PDO🤔
-- Added Leaf\Core\Auth: simple login and signup
-
-### Fixed
-
-- Fixed FS->deleteFile
-- Fixed FS->listDir
-- Fixed Leaf DB
-- Fixed init bug with session
-
-### Changed
-
-- Renamed Veins->renderTemplate to render
-- Rename veins->assign to set()
-- Renamed mkdir to createFolder
-- Renamed mkdirInBase to createFolderInBase
-- Renamed renameDir to renameFolder
-- Changed vein file extension from .vein to .vein.html
-- Split Leaf\Config\Db between Leaf\Core\Db\Mysqli and Leaf\Core\Db\PDO
-- Changed `renderHtml` to `renderPage`
-- Changed all `getParam`s to `get`
-
-### Removed
-
-Nothing was removed
-
-## v1.4.2 - 13th November, 2019
-
-### Added
-
-- Added FileSystem module
-- Added `mysqliQuery` method to `leaf\config\db`
-- Added a bunch of handy session methods
-- Added leaf token
-- Added leaf form
-
-### Fixed
-
-- Fixed a few problems with `leaf\config\db`;
-- Fixed tiny bug with `response->throwErr`
-
-### Changed
-
-- Changed `leaf\config\db`: connection variables and connection type are set on db init. `$db = new db($host, $user, $password, $dbname, "PDO")`
-- Renamed renderHtmlPage to renderHtml
-
-### Removed
-
-- Leaf\Config\DB has been depricated for now
-
-## v1.4.1 - 1st November, 2019
-
-### Added
-
-- Added base Leaf Controller `Leaf\Core\Controller`
-- Added base controller for APIs: `Leaf\Core\ApiController`
-- Added base Leaf Model `Leaf\Core\Model`
-- Added support for full MVC app
-- Added [Leaf Veins](https://github.com/leafsphp/veins) in default Leaf package
-- Added Error Handling for development and production
-- Added a base database layer connected with custom environment variables
-
-### Fixed
-
-- Fixed bug with `Response::renderHtmlPage()`
-- Fixed the HTTP code rendering in the browser from `Response::respondWithCode`
-
-### Changed
-
-- Changed `Validation` to `Form`
-
-### Removed
-
-- Removed Leaf `Exceptions`
-- Removed Middleware interfaces
diff --git a/src/coc/index.md b/src/coc/index.md
deleted file mode 100644
index 14e64a83..00000000
--- a/src/coc/index.md
+++ /dev/null
@@ -1,45 +0,0 @@
-# Code Of Conduct
-
-## Our Pledge
-
-In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, political party, or sexual identity and orientation. Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct.
-
-## Our Standards
-
-Examples of behavior that contributes to creating a positive environment include:
-
-- Using welcoming and inclusive language
-- Being respectful of differing viewpoints and experiences
-- Gracefully accepting constructive criticism
-- Focusing on what is best for the community
-- Showing empathy towards other community members
-
-Examples of unacceptable behavior by participants include:
-
-- The use of sexualized language or imagery and unwelcome sexual attention or advances
-- Trolling, insulting/derogatory comments, and personal or political attacks
-- Public or private harassment
-- Publishing others' private information, such as a physical or electronic address, without explicit permission
-- Other conduct which could reasonably be considered inappropriate in a professional setting
-
-## Our Responsibilities
-
-Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior.
-
-Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful.
-
-## Scope
-
-This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers.
-
-## Enforcement
-
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at mychi@leafphp.dev. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
-
-Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
-
-## Attribution
-
-This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
-
-[homepage]: https://www.contributor-covenant.org
diff --git a/src/codelabs/contributing.md b/src/codelabs/contributing.md
index 8c7e3de6..b44e1e68 100644
--- a/src/codelabs/contributing.md
+++ b/src/codelabs/contributing.md
@@ -1,6 +1,16 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
-# Contributing
+# Contributing to Codelabs
+
+We are glad to have you
## What we are looking for
diff --git a/src/codelabs/experiments/auth/api/index.md b/src/codelabs/experiments/auth/api/index.md
deleted file mode 100755
index de1675aa..00000000
--- a/src/codelabs/experiments/auth/api/index.md
+++ /dev/null
@@ -1,345 +0,0 @@
-# API Auth
-
-::: warning Version support
-This experiment supports `v3.0` upwards.
-:::
-
-## What Are We Building?
-
-Modern web app conventions have led to a lot of web apps relying on AJAX requests to a backend (API) using libraries like [axios](https://github.com/axios/axios). These backend APIs take in json encoded data from the frontend, perform some operations and send back a response.
-
-In this experiment, we'll be looking at how to create logins, signups and user updates with Leaf v3.0 +. We'll have various requests in JSON form, and some with headers which we'll be using for this experiment.
-
-::: details Detailed Explanation: A quick look at APIs
-*If you know what an API is, you can skip this part*
-
-***What is an API?***
-
-> An Application Programming Interface (API) allows two systems to communicate with one another. - smartbear.com
-
-For our use case, we can say that our API is the backend of whatever application we are building. Our frontend handles user interactions, however, if the frontend needs to perform an operation that needs data from our database for instance, it sends a request to our backend (API) which then checks and returns a response to our frontend. The frontend then performs an action based on whatever response the API returns.
-:::
-
-::: details Detailed Explanation: JWT Auth Concept
-*If you know how JWTs work, you can skip this part*
-
-***What is a JWT?***
-
-> JSON Web Token (JWT) is an open standard (RFC 7519) that defines a compact and self-contained way for securely transmitting information between parties as a JSON object. This information can be verified and trusted because it is digitally signed. - jwt.io
-
-Basically, you can see this as hashed token containing some specified information token locked with a secret key. JWTs also have expiration times, which means that you can issue a token for a particular timeframe.
-
-***JWTs in user authentication***
-
-- A user's information will be submited to our API
-- We check to the credentials against our database and return the user
-- We take the encode some unique user info into the JWT and return that to the frontend
-
-These steps will be explained into details below. You can check the [JWT spec](https://jwt.io/introduction) for more info.
-:::
-
-## Prerequisites
-
-- To get started with this tutorial, you will first need to set up a leaf 3 application. The easiest way to do this is to use the [Leaf CLI](https://cli.leafphp.dev).
-
-```sh
-leaf create test-app --basic --v3
-```
-
-This will generate a simple leaf 3 app with an `index.php` file as well.
-
-- You will also need basic knowledge on [leaf's router](https://leafphp.dev/docs/routing/)
-
-## Building Our Login
-
-Our authentication flow starts with a user entering their credentials on the frontend of an app. This is parsed and sent to the backend (our API) through an [API endpoint](https://smartbear.com/learn/performance-monitoring/api-endpoints/) or route. This means that our first task is to set up a route to handle the data passed into our API.
-
-We'll use [leaf's core router](https://leafphp.dev/docs/routing/) for this.
-
-```php
-require __DIR__ . "/vendor/autoload.php";
-
-app()->post("/login", function () {
- // login stuff here
-});
-
-app()->run();
-```
-
-Before we move on, let's give our data from the frontend a structure so we know exactly what we are working with. This app will take in a username and a password defined in this way.
-
-```js
-{
- "username": "mychi",
- "password": "password"
-}
-```
-
-Our next task is to get the data passed into our app and cross-check it with the data in our database. If the user credentials are found and match those in our database, we will generate a JWT and attach it to the response along with the user, otherwise, we throw an error.
-
-We can retrieve the `username` and `password` passed into our app using the leaf request object.
-
-```php
-$data = request()->get(["username", "password"]);
-```
-
-This grabs the username and password from the request and saves them in the `$data` variable.
-
-Now, we need to tackle the part that checks the database for the current credentials and generates a JWT if the user is found. Leaf provides an auth module to simply and quickly tackle this. To proceed, we will need to install the auth module.
-
-Composer:
-
-```sh
-composer require leafs/auth
-```
-
-Or with leaf CLI:
-
-```sh
-leaf install auth
-```
-
-After this, we should automatically have access to the `auth()` global.
-
-::: tip Using leaf auth
-When using Leaf auth in a leaf app, you don't need to work with classes and namespaces at all since all of the auth functionality is available on the `auth()` method. You don't even need to initialize it.
-:::
-
-Now, we have our auth module installed, but we still need to connect to our database before we can work with authentication:
-
-```php
-auth()->connect("host", "user", "password", "dbName");
-```
-
-eg:
-
-```php
-auth()->connect("127.0.0.1", "root", "", "appDB");
-```
-
-Now that we're done with that, let's check our database and generate our token. As usual, leaf provides a simple way of doing this.
-
-```php
-$res = auth()->login("users", $data);
-```
-
-This single line of code checks for a user in our database, prepares an error if authentication fails, and finally returns the user with a generated JWT if the authentication is successful.
-
-When the authentication is successful, the `$res` variable above will have the user and the generated JWT. But what happens when authentication fails? When authentication fails, the `$res` variable will be `null`. But how do we know what exactly went wrong? Simple! We can use the `errors` method on leaf auth:
-
-```php
-$res = auth()->login("users", $data);
-
-if ($res === null) {
- response()->throwErr([
- "status" => "failed",
- "data" => auth()->errors(),
- ], 401);
-}
-```
-
-We are using `response()->throwErr` to break the app with a specified response. This will make sure that the code below it doesn't run just like adding a `return` statement does.
-
-This handles the error response, but if the authentication is successful, the `$res` variable will contain the user and the generated JWT as mentioned above.
-
-```php
-$res = auth()->login("users", $data);
-
-if ($res === null) {
- response()->throwErr([
- "status" => "failed",
- "data" => auth()->errors(),
- ], 401);
-}
-
-response()->json([
- "status" => "success",
- "data" => $res,
-]);
-```
-
-So, putting all of this together, we'll have something like this:
-
-```php
-connect("host", "user", "password", "dbName");
-auth()->config("PASSWORD_ENCODE", function($password) {
- return \CustomPasswordHash::create($password);
-});
-
-app()->post("/login", function () {
- $data = request()->get(["username", "password"]);
- $res = auth()->login("users", $data);
-
- if ($res === null) {
- response()->throwErr([
- "status" => "failed",
- "data" => auth()->errors(),
- ]);
- }
-
- response()->json([
- "status" => "success",
- "data" => $res,
- ]);
-});
-
-app()->run();
-```
-
-The output will look like this:
-
-```js
-{
- "user": {
- "username": "mychi",
- "email": "mickdd22@gmail.com",
- "created_at": "2019-09-20 13:47:48"
- },
- "token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzYxMzUzMjgsImlzcyI6ImxvY2FsaG9zdCIsImV4cCI6MTU3NjEzNjIyOCwidXNlcklkIjoxfQ.7FODXGGJKioGQVX4ic0DJLoMIQTVUlsd4zFAJA4DAkg"
-}
-```
-
-## Using our login
-
-After creating our login handler, we just need to plug this into our frontend. We can do this using any library for handling network requests. For this example, we will use [axios](https://github.com/axios/axios)
-
-::: tip Note
-For this demonstration, we will be using axios with promises. Take a look at ES6 if you are not familiar with promises.
-:::
-
-```js
-axios.post('/login', {
- username: 'mcyhi',
- password: 'password',
-}).then((res) => {
- // success login instance
- if (res.data.status === "success") {
- localStorage["user"] = res.data.data.user;
- localStorage["token"] = res.data.data.token;
- }
-}).catch((err) => {
- if (err?.response && err?.response?.data?.status) {
- // a toast library
- toast.error(err?.response?.data?.auth);
- }
-});
-```
-
-## Building Our Register
-
-It's this easy to create and use logins, so what about registrations? Even easier! Registration involves saving the user in the database, if the user is returned immedietely, a token needs to be created as well. Since we've already configured Leaf Auth, let's just jump right into the code.
-
-```php{3}
-app()->post("/register", function () {
- $data = request()->get(["username", "email", "password"]);
- $res = auth()->register("users", $data, ["username", "email"]);
-
- if ($res === null) {
- response()->throwErr([
- "status" => "failed",
- "data" => auth()->errors(),
- ]);
- }
-
- response()->json([
- "status" => "success",
- "data" => $res,
- ]);
-});
-```
-
-The third line calls the `register` function which is responsible for registering the user. Unlike `login` above, we passed in a third parameter: an array of items which need to be unique in the database. In this case, leaf auth will make sure that there is no same `username` or `email` in the database before saving the user's credentials.
-
-## Building Our Update User
-
-To edit a user, we have to find the user we want to edit. This means that the user should be logged in. Since we're using JWT, we'll need to pass the token into the request as a bearer token in the authorization header.
-
-An example of this with axios will look like this:
-
-```js{7}
-import axios from "axios";
-
-axios({
- url: `${API_URL}/update`,
- method: "POST",
- headers: {
- Authorization: `Bearer ${token}`,
- },
- ...
-})
-```
-
-Back on our system, we'll have to detect the token, grab and decode it, find the data encoded into it and retrieve the user id. Sounds complex, but again, one line of code with Leaf.
-
-```php
-$userId = auth()->id() ?? response()->throwErr([
- "status" => "failed",
- "data" => auth()->errors(),
-]);
-```
-
-Based on this id, we can create a condition to find the user we want to update. This condition will be passed together with our params into the `update` method, which will look like this:
-
-```php
-$data = request()->get(["username", "email"]);
-
-// credentials to find user by
-$where = ["id" => auth()->id() ?? response()->throwErr(auth()->errors())];
-
-// unique data
-$uniques = ["username", "email"];
-
-$user = auth()->update("users", $data, $where, $uniques);
-```
-
-## Putting it all together
-
-```php
-connect("host", "user", "password", "dbName");
-auth()->config("PASSWORD_ENCODE", function ($password) {
- return \CustomPasswordHash::create($password);
-});
-
-app()->post("/login", function () {
- $data = request()->get(["username", "password"]);
- $res = auth()->login("users", $data);
-
- if (!$res) {
- response()->throwErr(auth()->errors());
- }
-
- response()->json($res);
-});
-
-app()->post("/register", function () {
- $data = request()->get(["username", "email", "password"]);
- $res = auth()->register("users", $data, ["username", "email"]);
-
- if (!$res) {
- response()->throwErr(auth()->errors());
- }
-
- response()->json($res);
-});
-
-app()->post("/update", function () {
- $data = $request->get(["username", "email"]);
- $where = ["id" => auth()->id() ?? response()->throwErr(auth()->errors())];
-
- $user = auth()->update("users", $data, $where, ["username", "email"]);
-});
-
-app()->run();
-```
-
-
-
-Experiment by Mychi Darko
diff --git a/src/codelabs/experiments/auth/index.md b/src/codelabs/experiments/auth/index.md
deleted file mode 100644
index 53c81b4d..00000000
--- a/src/codelabs/experiments/auth/index.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-aside: none
----
-
-# Authentication
-
-This is a collection of codelab experiments related to web/API authentication across different platforms. Since there are multiple setups of leaf, along with Leaf MVC and Leaf API, this page will contain variations to give you the best experience for the version you're using.
-
-| Topic | Description |
-| :------------------------------------------------- | :----------------------------------------------------------------- |
-| [API auth](/codelabs/experiments/auth/api/) | API authentication with base Leaf 3 |
-| [Session auth](/codelabs/experiments/auth/session/) | Session authentication with base Leaf 3 |
diff --git a/src/codelabs/experiments/auth/session/index.md b/src/codelabs/experiments/auth/session/index.md
deleted file mode 100755
index d6d9ab46..00000000
--- a/src/codelabs/experiments/auth/session/index.md
+++ /dev/null
@@ -1,266 +0,0 @@
-# Session Auth
-
-::: warning Version support
-This experiment supports `v3.0` upwards.
-:::
-
-## What are we building?
-
-Although most web apps mostly rely on APIs and token/OAuth, the practice of using built in sessions for authentication certainly hasn't faded out.
-
-In this experiment, we'll be looking at how to create logins, signups and user updates with Leaf v3. We'll be relying on session support in the auth package and we'll also be using blade for our templating.
-
-::: details Detailed Explanation: Session authentication
-Session based authentication is one in which the user state is stored on the server’s memory.
-
-Read the full article [here](https://dev.to/thecodearcher/what-really-is-the-difference-between-session-and-token-based-authentication-2o39)
-:::
-
-::: details Detailed Explanation: Templating engines
-For the sake of our tutorial, let's say that templating engines are a way of outputting code which allows us separate our logic from our views. There are many template engines out there, blade, twig, smarty and more.
-
-According to expressjs.com:
-
-> a template engine enables you to use static template files in your application. At runtime, the template engine replaces variables in a template file with actual values, and transforms the template into an HTML file sent to the client. This approach makes it easier to design an HTML page.
-:::
-
-## Building Our Login
-
-First of all, we need a route to handle our login screen. We'll use leaf's core router for this. To get started, we'll need to install leaf auth and leaf blade. We can do this with composer:
-
-```sh
-composer require leafs/auth
-composer require leafs/blade
-```
-
-or with leaf CLI:
-
-```sh
-leaf install auth
-leaf install blade
-```
-
-After this, we can create our `index.php` file:
-
-```php
-require __DIR__ . "/vendor/autoload.php";
-
-// show login page
-app()->get("/auth/login", function() {
- echo app()->blade->render("login");
-});
-
-// login logic
-app()->post("/auth/login", function() {
- // logic here
-});
-
-app()->run();
-```
-
-Next we'll define our blade view, `login.blade.php`:
-
-```php
-
- Login
-
- Sign into Leaf APP
-
-
-
-```
-
-Before we jump into the code, let's talk about the processes involved. When a user logs in, a new session is created for them. This session holds the user and the session tracker logs assigned by Leaf Auth. We can check the user's logged in state to load a page or redirect.
-
-To set all this up with Leaf, all we need to do is to tell leaf auth to use sessions instead of just JWTs.
-
-```php
-auth()->useSession();
-```
-
-or
-
-```php
-auth()->config("USE_SESSION", true);
-```
-
-::: tip Functional Mode ⚡️
-Note that the `auth` function we are using above comes from the auth package extending leaf 3's functional mode.
-:::
-
-```php
-require __DIR__ . "/vendor/autoload.php";
-
-auth()->useSession();
-
-app()->get("/auth/login", function() {
- app()->blade->render("login");
-});
-
-app()->post("/auth/login", function() {
- // logic here
-});
-```
-
-Now we can focus on the login logic. If you've used auth before in previous versions, adding session support literally changed nothing about the syntax, so you can still comfortably create your logins in the very same way.
-
-```php
-auth()->login("users", [
- "username" => $username,
- "password" => $password
-]);
-```
-
-Even the error handling works the same way too:
-
-```php
-$user = auth()->login("users", [
- "username" => $username,
- "password" => $password
-]);
-
-if (!$user) {
- // an error happened here, you can display
- // them on your template. The errors can be
- // grabbed with auth()->errors()
-}
-```
-
-On a successful login, `login` will redirect the user to `GUARD_HOME` which is simply the homepage route. This route can be configured using the config method.
-
-```php
-auth()->config("GUARD_HOME", "/dashboard");
-```
-
-Putting it all together, we can have something like this:
-
-```php
-// get username and password submitted from login form
-list($username, $password) = array_values(request(["username", "email"]));
-
-auth()->config("GUARD_HOME", "/dashboard");
-
-// attempt a login
-$user = auth()->login("users", [
- "username" => $username,
- "password" => $password
-]);
-
-// if there's a problem with credentials or system
-if (!$user) {
- // render login page
- return app()->blade->render("login", [
- // pass in errors and credentials
- "errors" => auth()->errors(),
- "username" => $username,
- "password" => $password,
- ]);
-}
-```
-
-As you can see nothing has changed in the login implementation even though a ton of new features have been added. Restructuring the code, we'll have something like this. There's one last thing though. When an already logged in user tries to go to the login page, we want to redirect to `GUARD_HOME`.
-
-This means we have to check the session to find if the user is logged in or not, redirect if the user is logged in and maintain the page if the user isn't. Leaf makes this simple as well as it provides a `guard` method.
-
-```php
-auth()->guard("guest");
-```
-
-This tells leaf that the page is a guest page and should not be accesible when the user is logged in. Putting all what we've discussed together should look like this:
-
-```php
-require __DIR__ . "/vendor/autoload.php";
-
-// connect to db. You can use autoConnect too
-auth()->connect("host", "user", "password", "dbName");
-auth()->config("GUARD_HOME", "/dashboard");
-
-app()->get("/auth/login", function() {
- auth()->guard("guest");
-
- app()->blade->render("login");
-});
-
-app()->post("/auth/login", function() {
- auth()->guard("guest");
-
- list($username, $password) = array_values(app()->request()->get(["username", "email"]));
-
- // attempt a login
- $user = auth()->login("users", [
- "username" => $username,
- "password" => $password
- ]);
-
- // if there's a problem with credentials or system
- if (!$user) {
- // render login page
- return app()->blade->render("login", [
- // pass in errors and credentials
- "errors" => auth()->errors(),
- "username" => $username,
- "password" => $password,
- ]);
- }
-});
-```
-
-## Building Our Register
-
-Registration involves saving the user in the database. From there we can immedietely initialize a session or go to the `GUARD_LOGIN` page so the user signs in. Since we've already configured Leaf Auth, let's just jump right into the code.
-
-```php
-app()->post("/auth/register", function() {
- auth()->guard("guest");
-
- $credentials = request()->get(["username", "email", "password"]);
-
- // automatically login immedietely the user is created
- auth()->config("SESSION_ON_REGISTER", true);
-
- $user = auth()->register("users", $credentials, [
- "username", "email"
- ]);
-
- if (!$user) {
- return app()->blade->render("register", array_merge(
- ["errors" => array_merge(is()->auth->errors()],
- request(["username", "email", "password"]))
- );
- }
-});
-```
-
-Here, we're creating a handler for our register method, getting the request data we need and saving it in the database using `register`. You might have noticed the 3rd parameter, `["username", "email"]`. This just makes sure that the same username and email don't already exist in the database. Leaf literally does everything for you. We can have a template like this:
-
-```php
-
-```
-
-And with this we've successfully created our register functionality. Read the auth docs for more info on session auth.
-
-Experiment by Mychi Darko
diff --git a/src/codelabs/experiments/caching/index.md b/src/codelabs/experiments/caching/index.md
deleted file mode 100644
index d78866d8..00000000
--- a/src/codelabs/experiments/caching/index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-aside: none
----
-
-# Caching
-
-This is a collection of codelab experiments related to caching across different platforms.
diff --git a/src/codelabs/experiments/deployment/digitalocean/index.md b/src/codelabs/experiments/deployment/digitalocean/index.md
index 5f4c847d..fb6d4d25 100644
--- a/src/codelabs/experiments/deployment/digitalocean/index.md
+++ b/src/codelabs/experiments/deployment/digitalocean/index.md
@@ -1,3 +1,11 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
# Deploying a LeafMVC Application to Digital Ocean
::: warning Version support
diff --git a/src/codelabs/experiments/deployment/heroku/index.md b/src/codelabs/experiments/deployment/heroku/index.md
index 56870485..c628ff0c 100644
--- a/src/codelabs/experiments/deployment/heroku/index.md
+++ b/src/codelabs/experiments/deployment/heroku/index.md
@@ -6,7 +6,7 @@ Version support. This tutorial assumes use of Leaf CLI >= 2.2.0 (🍊 Yomi Yomi
## What Are We Building?
-This experiment will guide you deploying your first Leaf application to Heroku. The same steps apply to Leaf MVC, Leaf API and Skeleton.
+This experiment will guide you deploying your first Leaf application to Heroku. The same steps apply to Leaf MVC.
::: details (New to Heroku?)
Heroku is a platform as a service (PaaS) that enables developers to build, run, and operate applications entirely in the cloud. Create an account, tether a credit card, and prepare to build.
diff --git a/src/codelabs/experiments/index.md b/src/codelabs/experiments/index.md
deleted file mode 100644
index 1a08d3c9..00000000
--- a/src/codelabs/experiments/index.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-aside: none
----
-
-# Experiments
-
-A codelab experiment is a single tutorial that focuses on a particular topic. It is interactive and in-depth covering what is needed in full.
-
-Below is a list of experiment topics.
-
-## Topics
-
-| Topic | Description |
-| :------------------------------------ | :----------------------------------------------------------------- |
-| [Hosting](/codelabs/experiments/deployment/) | Experiments related to web/API hosting |
-| [Auth](/codelabs/experiments/auth/) | Experiments related to web/API authentication |
-
-
-
-## Contributing
-
-If you don't find your topic here, you can simply create a pull request with your experiment in the topic folder you need. Find the full contribution guide [here](/codelabs/contributing)
diff --git a/src/codelabs/experiments/javascript/index.md b/src/codelabs/experiments/javascript/index.md
deleted file mode 100644
index c0248423..00000000
--- a/src/codelabs/experiments/javascript/index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-aside: none
----
-
-# JavaScript
-
-This is a collection of codelab experiments related to JavaScript across different platforms.
diff --git a/src/codelabs/experiments/mail/dynamic-mail-templating/README.md b/src/codelabs/experiments/mail/dynamic-mail-templating/README.md
deleted file mode 100755
index bbc6d916..00000000
--- a/src/codelabs/experiments/mail/dynamic-mail-templating/README.md
+++ /dev/null
@@ -1,105 +0,0 @@
-# Dynamic Emails With Templating
-
-## Base Example
-
-Writing and designing mails everytime you want to send a message to a user can be a major pain. One solution to this is to have an HTML or PHP script written as an email body, but of course this is very messy and unpractical.
-
-In this codelab experiment, we'll be using Leaf Mail, leaf's mail managing package in addition to Leaf Blade templating engine to send dynamic emails.
-
-So first we'll to prepare our system, initialise any needed package before we continue.
-
-```php
-
-
-
-
-
- {{ $title }}
-
-
-
- Dear {{ $name }},
-
- We are glad to announce that you have been employed as {{ $position }} at Leaf PHP
-
-
- Love, The Leaf Team.
-
-
-
-
-```
-
-### The System
-
-Basically, we've created a view which takes in a `$title`, `$name` and `$position`. So, back to our main system, we have to fill these fields and save the whole view into our mail body. Let's see how that works.
-
-**Be sure to read Leaf Blade docs and Leaf Mail docs.**
-
-```php
-smtp_connect("host", 0000, true, "username", "password");
-
-$mail->Subject = "Subject";
-$mail->Body = "BLADE VIEW HERE";
-```
-
-So as you can see, all we have to do is to load the blade view into the `Body` section. That's actually all there is to it. Now let's work with blade a bit. We'll have to configure the directories for our blade views, and their compiled files too, after that, we render and pass in the required variables.
-
-Note that rendering blade views doesn't output that view, it just returns it, to actually output the view, we have to explicitly use `echo` or Leaf's `renderMarkup`. Thus, we're taking advantage of this.
-
-```php
-$app->blade->configure("app/pages", "app/pages/cache");
-$body = $app->blade->render("mail", [
- "title" => "Employment",
- "name" => "Michael",
- "position" => "maintainer"
-]);
-```
-
-Now, our complete view is saved in the `$body` variable, simple right? Now let's patch all what we've done together and send our email.
-
-```php
-blade->configure("app/pages", "app/pages/cache");
-$mail->smtp_connect("host", 0000, true, "username", "password");
-
-$mail->Subject = "Subject";
-$mail->Body = $app->blade->render("mail", [
- "title" => "Employment",
- "name" => "Michael",
- "position" => "maintainer"
-]);
-// other mail fields go here
-$mail->send();
-```
-
-Dont forget to check Leaf Mail's documentation
-
-
-
-Experiment by Mychi Darko
diff --git a/src/codelabs/experiments/mail/index.md b/src/codelabs/experiments/mail/index.md
deleted file mode 100644
index 2e1f1e32..00000000
--- a/src/codelabs/experiments/mail/index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-aside: none
----
-
-# Mailing
-
-This is a collection of codelab experiments related to mailing.
diff --git a/src/codelabs/experiments/websocket/index.md b/src/codelabs/experiments/websocket/index.md
deleted file mode 100644
index 4e8caed7..00000000
--- a/src/codelabs/experiments/websocket/index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-aside: none
----
-
-# Websockets
-
-This is a collection of codelab experiments related to websockets across different platforms.
diff --git a/src/codelabs/index.md b/src/codelabs/index.md
index fa8d14db..8d347b89 100644
--- a/src/codelabs/index.md
+++ b/src/codelabs/index.md
@@ -1,38 +1,33 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
# Leaf Codelabs
-Codelabs is a space we created to give interactive tutorials on Leaf, PHP and JS concepts that help you achieve specific results in your apps. Codelabs takes one topic or "how-to" and dives deep into it, giving you all the information you need to successfully complete the tutorial yourself while also explaining useful concepts along the way.
+We created Codelabs to give you interactive step-by-step real-world tutorials on Leaf, PHP and JS concepts that help you achieve specific results in your apps. Codelabs takes one topic or "how-to" and dives deep into it, giving you all the information you need to successfully complete the tutorial yourself while also explaining useful concepts along the way.
## Codelabs vs the Docs
-How is `codelabs` different from the rest of our documentation? Why is this necessary?
-
-- **Greater Focus**: In the docs, we're essentially telling a story. Each section builds on and assumes knowledge from each previous section. In the codelabs section, each experiment can and should stand on its own. This means experiments can focus on one specific aspect of Leaf, rather than having to give a general overview.
-
-- **Greater Depth**: To avoid making the docs too long, we try to include only the simplest possible examples to help you understand each feature. Then we move on. In the codelabs section, we can include more complex examples, combining features in interesting ways. Each experiment can also be as long and detailed as it needs to be, in order to fully explore its niche.
+Codelabs are hands-on, standalone tutorials focused on specific Leaf features, unlike our docs, which follow a story-like flow. They dive deeper with complex examples that combine features in interesting ways that may not be fully covered in the docs.
-- **Teaching PHP/JS**: Although our docs are beginner friendly, we still assume basic familiarity with PHP concepts as we do not go over them into details in the docs. For example, we won't explain how forms and network requests work and how data is read. **In codelabs however**, essential PHP/JS features and concepts can be explored and explained in the context of how they help us build better Leaf apps.
-
-- **Hands-on**: Codelabs, unlike the docs packs in interactive hands-on tutorials which you can follow step-by-step. Each tutorial is specially crafted to help you "learn by doing" and is complementary to the docs. For this reason, you will always find links back to leaf, a module or a particular package.
+While our documentation is beginner-friendly, we only have the space to cover PHP and general web concepts. Codelabs on the other hand will explain any concepts that are essential to that specific tutorial, eg: "how to update your Leaf app on DigitalOcean" will explain DigitalOcean, SSH, and Linux concepts necessary to complete the tutorial.
## Experiments
-A codelab experiment is a single tutorial that focuses on a particular topic. It is interactive and in-depth, covering what is needed in full.
-
-Below is a list of experiment topics.
+We call a tutorial in Codelabs an "experiment". Each experiment is a standalone tutorial that focuses on a particular topic. It is interactive and in-depth, covering what is needed in full.
-| Topic | Description |
-| :------------------------------------------------------ | :------------------------------------------------------------- |
-| [Hosting/Deployment](/codelabs/experiments/deployment/) | Experiments related to web/API deployment |
+Below is a list of all experiments:
-
-
-
-
-
-
+| Topic | Description | Author |
+| :------------------------------------------------------ | :------------------------------------------------------------- | :----- |
+| [Deploying Leaf MVC to Digital Ocean](/codelabs/experiments/deployment/digitalocean/) | Deploying LeafMVC projects to a new Digital Ocean droplet | [Matthew Reichardt](https://github.com/matthewjamesr) |
-**We are migrating from codelabs.leafphp.dev to leafphp.dev/codelabs. Please bear with us as we move all the experiments here.**
+***This list is still being updated.***
## Contributing
-If you don't find your topic here, you can simply create a pull request with your experiment in the topic folder you need. Find the full contribution guide [here](/codelabs/contributing)
+If you've written a tutorial that you think would be a great addition to our Codelabs, feel free to submit a PR to our [GitHub repository](https://github.com/leafsphp/docs) with your tutorial. For our readers' benefit, be sure to follow the [contribution guide](/codelabs/contributing) when submitting your tutorial. Thank you for your contribution!
diff --git a/src/community/coc.md b/src/community/code-of-conduct.md
similarity index 77%
rename from src/community/coc.md
rename to src/community/code-of-conduct.md
index fd53230a..378971f0 100644
--- a/src/community/coc.md
+++ b/src/community/code-of-conduct.md
@@ -1,5 +1,15 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
# Code Of Conduct
+Our Code of Conduct governs how we behave in public or in private whenever Leaf or its community is involved. We expect it to be honored by everyone who represents the Leaf community officially or informally, claims affiliation with the project, or participates directly. It applies to all of our spaces, including GitHub, Twitter, and other social media platforms.
+
## Our Pledge
In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, sex characteristics, gender identity and expression, level of experience, education, socio-economic status, nationality, personal appearance, race, religion, political party, or sexual identity and orientation. Note, however, that religion, political party, or other ideological affiliation provide no exemptions for the behavior we outline as unacceptable in this Code of Conduct.
@@ -34,7 +44,7 @@ This Code of Conduct applies both within project spaces and in public spaces whe
## Enforcement
-Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at community@vuejs.org. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
+Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team at [mychi@leafphp.dev](mailto:mychi@leafphp.dev). All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately.
Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership.
diff --git a/src/community/community-guide.md b/src/community/community-guide.md
deleted file mode 100644
index dbeaa052..00000000
--- a/src/community/community-guide.md
+++ /dev/null
@@ -1,83 +0,0 @@
----
-outline: deep
----
-
-# Community Guide
-
-Vue's community is growing incredibly fast and if you're reading this, there's a good chance you're ready to join it. So... welcome!
-
-Now we'll answer both what the community can do for you and what you can do for the community.
-
-## Resources
-
-### Code of Conduct
-
-Our is a guide to make it easier to enrich all of us and the technical communities in which we participate.
-
-### Stay in the Know
-
-- Follow our [official Twitter account](https://twitter.com/vuejs).
-- Follow our [team members](./team) on Twitter or GitHub.
-- Follow the [RFC discussions](https://github.com/vuejs/rfcs).
-- Subscribe to the [official blog](https://blog.vuejs.org/).
-
-### Get Support
-
-- [Discord Chat](https://chat.vuejs.org/): A place for Vue devs to meet and chat in real time.
-- [Forum](https://forum.vuejs.org/): The best place to ask questions and get answers about Vue and its ecosystem.
-- [DEV Community](https://dev.to/t/vue): Share and discuss Vue related topics on Dev.to.
-- [Meetups](https://events.vuejs.org/meetups): Want to find local Vue enthusiasts like yourself? Interested in becoming a community leader? We have the help and support you need right here!
-- [GitHub](https://github.com/vuejs): If you have a bug to report or feature to request, that's what the GitHub issues are for. Please respect the rules specified in each repository's issue template.
-- [Twitter Community (unofficial)](https://twitter.com/i/communities/1516368750634840064): A Twitter community, where you can meet other Vue enthusiasts, get help, or just chat about Vue.
-
-### Explore the Ecosystem
-
-- [The Awesome Vue Page](https://github.com/vuejs/awesome-vue): See what other awesome resources have been published by other awesome people.
-- [Vue Telescope Explorer](https://vuetelescope.com/explore): Explore websites made with Vue, with insights on what framework / libraries they use.
-- [Made with Vue.js](https://madewithvuejs.com/): showcases of projects and libraries made with Vue.
-- [The "Show and Tell" Subforum](https://forum.vuejs.org/c/show-and-tell): Another great place to check out what others have built with and for the growing Vue ecosystem.
-
-## What You Can Do
-
-### Help Fellow Users
-
-Code contribution is not the only form of contribution to the Vue community. Answering a question for a fellow Vue user on Discord or the forum is also considered a valuable contribution.
-
-### Help Triage Issues
-
-Triaging an issue means gathering missing information, running the reproduction, verifying the issue's validity, and investigating the cause of the issue.
-
-We receive many issues in [our repositories on GitHub](https://github.com/vuejs) every single day. Our bandwidth is limited compared to the amount of users we have, so issue triaging alone can take an enormous amount of effort from the team. By helping us triage the issues, you are helping us become more efficient, allowing us to spend time on higher priority work.
-
-You don't have to triage an issue with the goal of fixing it (although that would be nice too). Sharing the result of your investigation, for example the commit that led to the bug, can already save us a ton of time.
-
-### Contribute Code
-
-Contributing bug fixes or new features is the most direct form of contribution you can make.
-
-The Vue core repository provides a [contributing guide](https://github.com/vuejs/core/blob/main/.github/contributing.md), which contains pull request guidelines and information regarding build setup and high-level architecture. Other sub-project repositories may also contain its own contribution guide - please make sure to read them before submitting pull requests.
-
-Bug fixes are welcome at any time. For new features, it is best to discuss the use case and implementation details first in the [RFC repo](https://github.com/vuejs/rfcs/discussions).
-
-### Share (and Build) Your Experience
-
-Apart from answering questions and sharing resources in the forum and chat, there are a few other less obvious ways to share and expand what you know:
-
-- **Develop learning materials.** It's often said that the best way to learn is to teach. If there's something interesting you're doing with Vue, strengthen your expertise by writing a blog post, developing a workshop, or even publishing a gist that you share on social media.
-- **Watch a repo you care about.** This will send you notifications whenever there's activity in that repository, giving you insider knowledge about ongoing discussions and upcoming features. It's a fantastic way to build expertise so that you're eventually able to help address issues and pull requests.
-
-### Translate Docs
-
-I hope that right now, you're reading this sentence in your preferred language. If not, would you like to help us get there?
-
-See the [Translations guide](/translations/) for more details on how you can get involved.
-
-### Become a Community Leader
-
-There's a lot you can do to help Vue grow in your community:
-
-- **Present at your local meetup.** Whether it's giving a talk or running a workshop, you can bring a lot of value to your community by helping both new and experienced Vue developers continue to grow.
-- **Start your own meetup.** If there's not already a Vue meetup in your area, you can start your own! Use the [resources at events.vuejs.org](https://events.vuejs.org/resources/#getting-started) to help you succeed!
-- **Help meetup organizers.** There can never be too much help when it comes to running an event, so offer a hand to help out local organizers to help make every event a success.
-
-If you have any questions on how you can get more involved with your local Vue community, reach out on Twitter at [@vuejs_events](https://www.twitter.com/vuejs_events)!
diff --git a/src/community/contribute.md b/src/community/contribute.md
new file mode 100644
index 00000000..ae05ce3f
--- /dev/null
+++ b/src/community/contribute.md
@@ -0,0 +1,41 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
+# How can I contribute to Leaf?
+
+Leaf is an open-source project, and we welcome contributions from the community. Your help is essential, and we're grateful for it. There are many ways to contribute to Leaf, from writing code to improving the documentation.
+
+## Reporting issues
+
+If you find a bug in Leaf, please report it on our [GitHub](https://github.com/leafsphp/) organization. We appreciate detailed bug reports, including steps to reproduce the issue and any relevant information about your environment. Also, please check if the issue has already been reported before creating a new one.
+
+Another thing we appreciate is reporting issues on the right repository. For instance, if you find a bug in `Leaf\Auth`, please report it on the leafsphp/auth repository. We have a lot of modules, so it's important to report issues on the right repository to ensure they get the attention they need.
+
+## Join our Discord server
+
+We have a [Discord server](https://discord.gg/Pkrm9NJPE3) where you can ask questions, share your projects, and get help from the community. We're always happy to help you with any questions you have about Leaf. You can also help others in the community by answering their questions.
+
+## Helping out with issues
+
+If you're a developer, you can help out by contributing fixes to issues on our GitHub repositories. We have a lot of issues that need attention, and we appreciate any help you can provide. You can also help by reviewing pull requests and providing feedback to other contributors. To get started, check out our [contribution guide](/community/guide).
+
+## Creating modules
+
+If you have an idea for a new module that you think would be useful to the Leaf community, you can create it and submit it to get featured on our documentation. People have vastly different needs, and your module could be the missing piece for someone's project. Reach out to us on Discord if you need help with your module. To get started, check out our [contribution guide](/community/guide).
+
+## Improving the documentation
+
+The documentation is an essential part of any project, and we're always looking for ways to improve it. If you find any errors or have suggestions for how we can make the documentation better, please let us know. You can also contribute to the documentation by submitting pull requests to the [Leaf documentation repository](https://github.com/leafsphp/docs). To get started, check out the [documentation guide](/community/docs-writing-guide).
+
+## Let us know how you're using Leaf
+
+We love hearing about how people are using Leaf in their projects. If you're using Leaf, we'd love to hear about it. You can share your projects on our Discord server or reach out to us on Twitter. We're always happy to see what people are building with Leaf.
+
+## Spread the word
+
+If you love Leaf and want to help us grow the community, you can spread the word by sharing Leaf with your friends and colleagues. You can also write blog posts or create videos about Leaf to help others learn about it. We appreciate any help you can provide in spreading the word about Leaf.
diff --git a/src/community/contributing/doc-style-guide.md b/src/community/contributing/doc-style-guide.md
deleted file mode 100644
index fe553a87..00000000
--- a/src/community/contributing/doc-style-guide.md
+++ /dev/null
@@ -1,152 +0,0 @@
-# Documentation Style Guide
-
-This guide will provide an overview of different design elements that are available for your use in creating documentation.
-
-## Alerts
-
-vuepress provides a custom container plugin to create alert boxes. There are four types:
-
-- **Info**: Provide information that is neutral
-- **Tip**: Provide information that is positive and encouraged
-- **Warning**: Provide information that users should be aware of as there is a low to moderate
-- **Danger**: Provide information that is negative and has a high risk to the user
-
-**Markdown Examples**
-
-```
-::: tip
-You can find more information at this site.
-:::
-
-::: tip
-This is a great tip to remember!
-:::
-
-::: warning
-This is something to be cautious of.
-:::
-
-::: danger DANGER
-This is something we do not recommend. Use at your own risk.
-:::
-```
-
-**Rendered Markdown**
-
-::: tip
-You can find more information at this site.
-:::
-
-::: tip
-This is a great tip to remember!
-:::
-
-::: warning
-This is something to be cautious of.
-:::
-
-::: danger DANGER
-This is something we do not recommend. Use at your own risk.
-:::
-
-## Code Blocks
-
-vuepress uses Prism to provide language syntax highlighting by appending the language to the beginning backticks of a code block:
-
-**Markdown Example**
-
-````
-```js
-export default {
- name: 'MyComponent'
-}
-```
-````
-
-**Rendered Output**
-
-```js
-export default {
- name: 'MyComponent'
-}
-```
-
-### Line Highlighting
-
-To add line highlighting to your code blocks, you need to append the line number in curly braces.
-
-#### Single Line
-
-**Markdown Example**
-
-````
-```js{2}
-export default {
- name: 'MyComponent',
- props: {
- type: String,
- item: Object
- }
-}
-```
-````
-
-**Rendered Markdown**
-
-```js{2}
-export default {
- name: 'MyComponent',
- props: {
- type: String,
- item: Object
- }
-}
-```
-
-#### Group of Lines
-
-````
-```js{4-5}
-export default {
- name: 'MyComponent',
- props: {
- type: String,
- item: Object
- }
-}
-```
-````
-
-```js{4-5}
-export default {
- name: 'MyComponent',
- props: {
- type: String,
- item: Object
- }
-}
-```
-
-#### Multiple Sections
-
-````
-```js{2,4-5}
-export default {
- name: 'MyComponent',
- props: {
- type: String,
- item: Object
- }
-}
-```
-````
-
-```js{2,4-5}
-export default {
- name: 'MyComponent',
- props: {
- type: String,
- item: Object
- }
-}
-```
diff --git a/src/community/contributing/index.md b/src/community/contributing/index.md
deleted file mode 100644
index c7fae465..00000000
--- a/src/community/contributing/index.md
+++ /dev/null
@@ -1,78 +0,0 @@
-# Contribution Guide
-
-
-
-Hi! We're really excited that you are interested in contributing to Leaf. Before submitting your contribution, please make sure to take a moment and read through the following guidelines:
-
-- [Development Setup](#development-setup)
-- [Pull Request Guidelines](#pull-request-guidelines)
-- [Project Structure](#project-structure)
-
-## Development Setup
-
-You will need PHP 7.4 + and [composer](https://getcomposer.org).
-
-After cloning the repo, run:
-
-```bash
-leaf install
-```
-
-Or with composer:
-
-```bash
-composer install
-```
-
-## Pull Request Guidelines
-
-We encourage contributions through pull requests on our repositories. Pull requests are usually of 2 types: bug fixes and feature additions. You can open a "draft" pull request to let the community keep track of work you're doing, however, pull requests will only be evaluated if they are marked as "ready for review" and all tests for new features are passing. Any inactive pull requests left in the "draft" state for an extended period will be closed. The following guidelines should be followed when submitting a pull request:
-
-- The `master` branch is just a snapshot of the latest stable release. All development should be done in dedicated branches. **Do not submit PRs against the `master` branch.**
-
-- Checkout a topic branch from the relevant branch, e.g. `v3.x`, and merge back against that branch.
-
-- It's OK to have multiple small commits as you work on the PR - GitHub will automatically squash it before merging.
-
-- If adding a new feature:
-
- - Add accompanying test case.
- - Provide a convincing reason to add this feature. Ideally, you should open a suggestion issue first with the `suggestion` or `feature request` tag and have it approved before working on it.
-
-- If fixing bug:
- - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`.
- - Provide a detailed description of the bug in the PR.
-
-## Project Structure
-
-- **`src`**: contains the source code.
-
- - **`Exception/`**: contains code for the general leaf exceptions.
-
- This contains default error states and screens for errors, down-times and the like. It also contains extensible mark-up and logging to keep track of errors. Basically, anything relating to errors.
-
- - **`Helpers/`**: contains default leaf utilities like the container (DI container).
-
- - **`App.php`**: contains initializers and main leaf code.
-
- - **`Config.php`**: class for configuring how leaf behaves.
-
- - **`functions.php`**: Base functions for functional mode.
-
- - **`Middleware.php`**: base class for creating leaf middleware.
-
- - **`View.php`**: view config for leaf.
-
-## Financial Contribution
-
-As a pure community-driven project without any corporate backing, we also welcome financial contributions via OpenCollective.
-
-- [Checkout our sponsor page](/support/)
-
-## Credits
-
-Thank you to all the people who have already code to Leaf!
-
-
diff --git a/src/community/contributing/writing-guide.md b/src/community/docs-writing-guide.md
similarity index 96%
rename from src/community/contributing/writing-guide.md
rename to src/community/docs-writing-guide.md
index 782c4580..298eaefd 100644
--- a/src/community/contributing/writing-guide.md
+++ b/src/community/docs-writing-guide.md
@@ -1,3 +1,11 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
# Leaf Docs Writing Guide
Writing documentation is an exercise in empathy. We're not describing an objective reality - the source code already does that. Our job is to help shape the relationship between users and the Leaf ecosystem. This ever-evolving guide provides some rules and recommendations on how to do that consistently within the Leaf ecosystem.
@@ -45,11 +53,10 @@ Writing documentation is an exercise in empathy. We're not describing an objecti
- **Almost always avoid humor (for English docs)**, especially sarcasm and pop culture references, as it doesn't translate well across cultures.
- **Never assume a more advanced context than you have to.**
- **In most cases, prefer links between sections of the docs over repeating the same content in multiple sections.** Some repetition in content is unavoidable and even essential for learning. However, too much repetition also makes the docs more difficult to maintain, because a change in the API will require changes in many places and it's easy to miss something. This is a difficult balance to strike.
-- **Specific is better than generic.** For example, a `` component example is better than ``.
-- **Relatable is better than obscure.** For example, a `` component example is better than ``.
+- **Specific is better than generic.** For example, a `UserPost` action example is better than `UserAction`.
- **Be emotionally relevant.** Explanations and examples that relate to something people have experience with and care about will always be more effective.
- **Always prefer simpler, plainer language over complex or jargony language.** For example:
- - "you can use Leaf with a script element" instead of "in order to initiate the usage of Leaf, one possible option is to actually inject it via a script HTML element"
+ - "you can create a Leaf instance" instead of "in order to initiate the usage of Leaf, one possible option is to actually instanciate a Leaf object"
- "function that returns a function" instead of "higher order function"
- **Avoid language that invalidate struggle**, such as "easy", "just", "obviously", etc. For reference, see [Words To Avoid in Educational Writing](https://css-tricks.com/words-avoid-educational-writing/).
@@ -85,8 +92,6 @@ Writing documentation is an exercise in empathy. We're not describing an objecti
### Tips, Callouts, Alerts, and Line Highlights
-We have some dedicated styles to denote something that's worth highlighting in a particular way. These are captured [on this page](https://v3.leafphp.dev/docs/doc-style-guide.html#alerts). **They are to be used sparingly.**
-
There is a certain temptation to abuse these styles, as one can simply add a change inside a callout. However, this breaks up the flow of reading for the user, and thus, should only be used in special circumstances. Wherever possible, we should attempt to create a narrative and flow within the page to respect the readers cognitive load.
Under no circumstances should 2 alerts be used next to one another, it's a sign that we're not able to explain context well enough.
diff --git a/src/community/faq.md b/src/community/faq.md
index f90fc68a..b9a9eaf5 100644
--- a/src/community/faq.md
+++ b/src/community/faq.md
@@ -1,65 +1,55 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
# Frequently Asked Questions
+## What makes Leaf different from other frameworks?
+
+Leaf is designed to be minimalistic and flexible, offering only the tools you need without unnecessary bloat. It supports a large ecosystem of modules and PHP packages. It grows with your project, and doesn't require you to learn a whole new framework to use it.
+
## Who maintains Leaf?
-Leaf is an independent, community-driven project. It was created by [Michael Darko](https://github.com/mychidarko) in 2019 as a personal side project. Today, Leaf is actively maintained by [a team of both full-time and volunteer members from all around the world](/community/team), where Michael serves as the project lead. You can find Leaf's history [here](/community/history).
+Leaf is an independent, community-driven project. It was created by [Michael Darko](https://github.com/mychidarko) in 2019 as a personal side project. Today, Leaf is actively maintained by [a little team](/community/team) and contributors all over the world, where Michael serves as the project lead.
-Leaf's development is primarily funded through sponsorships and personal contributions from Michael and friends. If you or your business benefit from Leaf, consider [sponsoring us](/support/) to support Leaf's development!
+Leaf's development is primarily funded through sponsorships and personal contributions from Michael and friends. If you or your business benefit from Leaf, consider [sponsoring us](/support) to support Leaf's development!
## What license does Leaf use?
Leaf is a free and open source project released under the [MIT License](https://opensource.org/licenses/MIT).
+## Can I use Leaf with existing PHP projects?
+
+Absolutely, Leaf can be easily integrated into existing projects or used to build new ones from scratch. Since Leaf is modular, you can use only the parts you need without carrying the entire framework with you.
+
## Is Leaf reliable?
-After going through 2 major versions over the past 2 years, Leaf is now a battle-tested framework suitable for just about any PHP project. It is also one of the most popular lightweight PHP micro-frameworks and even has it's variant - Leaf API being a very popular framework.
+After going through 2 major versions over the past 5 years, Leaf is now a battle-tested framework suitable for just about any PHP project. It is also one of the most popular lightweight PHP micro-frameworks and even has it's variant - Leaf MVC being a very popular framework.
Leaf is used by individuals for large and personal projects, as well as by companies all over the world.
## Is Leaf fast?
-Leaf 3 is one of the most performant and lightweight PHP frameworks today. It is also 100% compatible with standard PHP libraries and servers, which means there's almost no need for configurations and manual optimizations.
+Leaf is one of the most performant and lightest PHP frameworks today. It is 100% compatible with standard PHP libraries and servers, which means there's almost no need for configuration and manual optimizations.
-In sample benchmarks, Leaf even out-performs frameworks like Slim PHP which was considered the most lightweight PHP micro-framework with blazing speed.
+In sample benchmarks, Leaf even out-performs frameworks like Slim PHP, while using way less memory and CPU.
-## Is Leaf lightweight?
-
-As mentioned above, Leaf 3 is one of the most lightweight PHP frameworks with a source of about 30kb. With Leaf 3's functional mode, a hello world application can be prepared in just 10 lines of code, including spaces and PHP initializers.
-
-## What's the difference between Leaf 2 and Leaf 3?
+## What PHP versions does Leaf support?
-Leaf 3 is the current, latest major version of Leaf. It contains new features that are not present in Leaf 2 (most notably functional mode and modules), and also contains a few breaking changes that makes it incompatible with Leaf 2. Despite the differences, the majority of Leaf APIs are shared between the two major versions, so almost all of your Leaf 2 knowledge will continue to work in Leaf 3.
+Leaf supports PHP 7.4 and above, ensuring compatibility with modern PHP features and standards, but will completely switch to PHP 8.2 and above in the future.
-In general, Leaf 3 provides smaller bundle sizes, better performance, better scalability, and better IDE support. If you are starting a new project today, Leaf 3 is the recommended choice. The only reason for you to consider Leaf 2 as of now is if you feel Leaf 3 is too modular, of course this is solved if you use Leaf 3 with Leaf MVC or Leaf API.
-
-Since both Leaf 2 and 3 are wired to accept any PHP code, all external libraries usable in Leaf 2 will still work perfectly with Leaf 3. If you intend to migrate an existing Leaf 2 app to Leaf 3, consult the dedicated Leaf 3 Migration Guide.
+## Is Leaf lightweight?
-Leaf 2 will receive a final minor release (2.7) in 2022. This minor release will backport a selected subset of new features from Leaf 3. After that, Leaf 2 will enter maintenance mode: it will no longer ship new features, but will continue to receive critical bug fixes and security updates.
+Leaf is super lightweight, coming with only a router and a lightweight http abstraction out of the box. With Leaf's functional mode, a hello world application can be prepared in just 10 lines of code, including spaces and PHP initializers.
## Does Leaf scale?
-Yes. Despite a common misconception that Leaf is only suitable for simple use cases, Leaf is perfectly capable of handling large scale applications:
-
-- [Skeleton](https://skeleton.leafphp.dev) provides a base setup which holds your hand through separation of concerns. It provides a partial MVC setup which allows for incremental adoption.
-
- ::: warning Remember
- This is not a framework.
- :::
-
-- [Leaf API](https://api.leafphp.dev) is an MVC framework bootstrapped with Leaf at it's core. It uses the [MVC architecture](https://towardsdatascience.com/everything-you-need-to-know-about-mvc-architecture-3c827930b4c1) to ensure separation of concerns. Leaf API is specially crafted to aid rapid developement of powerful but scalable APIs.
-
-- [Leaf MVC](https://mvc.leafphp.dev) just like Leaf API is a framework built with leaf that relies on the MVC architecture. The main difference is leaf MVC comes with tools which aid in building fullstack web apps/APIs. This makes Leaf MVC more general purpose, compared to the one-track API machine: Leaf API.
-
-As you see above, all of these setups/frameworks are built using leaf as their core. Leaf can fit into any environment depending on how you use it.
+Yes. Despite a common misconception that Leaf is only suitable for simple use cases, Leaf is perfectly capable of handling large scale applications. Leaf is modular and grows with your project. It has has a more organized MVC setup: [Leaf MVC](https://leafphp.dev/) that can be used for fullstack web apps.
## How do I contribute to Leaf?
-We appreciate your interest! Please check out our [Contribution Guide](/community/contributing/).
-
-
-
-
-
-
+We appreciate your interest! Please check out our [Contribution Guide](/community/contribute).
diff --git a/src/community/guide.md b/src/community/guide.md
new file mode 100644
index 00000000..50833e09
--- /dev/null
+++ b/src/community/guide.md
@@ -0,0 +1,41 @@
+---
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
+---
+
+# Contribution Guide
+
+Hi there! We're thrilled that you'd like to contribute to the community. Your help is essential, and we're grateful for it. Before you get started, please take a moment to read through the following guidelines:
+
+- [Leaf & Modules](#leaf-and-modules)
+- [Code style guide](#code-style-guide)
+- [Code of Conduct](#code-of-conduct)
+- [Pull Request Guidelines](#pull-request-guidelines)
+- [Writing guide for documentation](/community/docs-writing-guide)
+
+## Leaf and Modules
+
+Leaf is built to be modular, so you can use only what you need. This also means that you can contribute to Leaf by creating modules that extend its functionality or simply adding new features to an existing module. Modules can be anything from simple helper functions to a full-blown set of new functionality for Leaf.
+
+The core of Leaf is a simple wrapper around Leaf's router and http modules that adds things like dependency injection, synced configuration, and a few other features. Everything else is built as modules.
+
+Leaf MVC takes this a step further by constructing a simple MVC structure around Leaf. MVC Core is a module that links the said MVC structure to Leaf's core, and the rest of the modules are built around this. We do it this way so that you can use Leaf's core and other modules without having to use the MVC structure. So, if you're contributing to Leaf's core or any of the modules, try not to make it dependent on the MVC structure.
+
+With that said, you're ready to start contributing to Leaf. If you're contributing to Leaf's core, you can find the source code [here](https://github.com/leafsphp/leaf). If you're contributing to a module, you can find the source code somewhere in our [GitHub organization](https://github.com/leafsphp). If you're contributing to the documentation, you can find the source code [here](https://github.com/leafsphp/docs).
+
+## Code style guide
+
+When contributing to Leaf, please make sure to follow the [PSR-12](https://www.php-fig.org/psr/psr-12/) coding standard. This is a set of rules that dictates how PHP code should be written. It's a good idea to familiarize yourself with these rules before contributing to Leaf (They're pretty simple standards, mostly about indentation and naming conventions. Most of us use them without even knowing it).
+
+We have a more compact guide [here](https://rebel-tibia-7d7.notion.site/2-Code-Quality-and-Reviews-183c0344a6cc43e7b3693880b0fb35a6) that you can follow. It's a really short guide, but the most important thing you should take away from it is that the top priority is to make anything you build developer-friendly. This means that your code should be easy to read, easy to understand, and easy to use.
+
+## Code of Conduct
+
+Our [Code of Conduct](/community/code-of-conduct) governs how we behave in public or in private whenever Leaf or its community is involved. We expect it to be honored by everyone who represents the Leaf community officially or informally, claims affiliation with the project, or participates directly. It applies to all of our spaces, including GitHub, Twitter, and other social media platforms.
+
+## Pull Request Guidelines
+
+Before you submit a pull request, check that it meets these guidelines:
diff --git a/src/community/history.md b/src/community/history.md
deleted file mode 100644
index cb904571..00000000
--- a/src/community/history.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-aside: none
----
-
-# History
-
-Leaf was started in October 2019 as a simple frameworkless boilerplate for developing APIs. The idea was to create a powerful, but fairly simple boilerplate which could just be cloned and used as a starter for projects.
-
-![Leaf PHP boilerplate](https://user-images.githubusercontent.com/26604242/145728756-4b3908af-4cf1-4be6-8250-f39f4155489d.png)
-
-Along the way, leaf's features got bundled and shipped as a library which people started calling a micro-framework. It was later published on [product hunt](https://www.producthunt.com/posts/leaf-php) and got a whole lot of people interested in it. Leaf even earned one of the top products of the day spots ⚡️
-
-![image](https://user-images.githubusercontent.com/26604242/145728962-60179763-62c6-4f88-97b9-6d24bccc9f36.png)
-
-After this, leaf went on to introduce many amazing features like leaf db, leaf auth and more. But after a long run with version 1, we decided to completely re-write leaf in order to add a few more features like middleware on a core level.
-
-The first commit to v2 was on 4 Mar 2020. This was the first commit since the v1.5 release a couple of months earlier. The stable v2 was released only a month later on 22 Apr 2020, and brought in a whole lot of upgrades to leaf, leaf MVC, leaf API and the creation of Skeleton.
-
-A year down the line, leaf 2 was featured in a lot of top 10s and upcoming/lightweight framework reviews. It was adopted in both professional workscapes and by hobbyists all over the world. You could say leaf 2 was really doing well, but then it started getting features that a lot of developers were not using in their apps. And that's when the idea of modules was born.
-
-We could ship leaf's features as installable plugins which developers will manually handpick for their apps, and the community agreed with us. We started working towards this, and discovered "functional mode" along the way. We also rebranded leaf to match our new goal of giving developers the best PHP experience and improving our usability.
-
-Today, v3 is almost stable and we've published over 30 modules on packagist. v3 has proven to be lighter than just about every framework out there, with a source of about 30kb and even faster than frameworks like Slim PHP.
diff --git a/src/community/images/ben-hong.jpeg b/src/community/images/ben-hong.jpeg
deleted file mode 100644
index 55891975..00000000
Binary files a/src/community/images/ben-hong.jpeg and /dev/null differ
diff --git a/src/community/images/evan-you.jpeg b/src/community/images/evan-you.jpeg
deleted file mode 100644
index 388b8892..00000000
Binary files a/src/community/images/evan-you.jpeg and /dev/null differ
diff --git a/src/community/index.md b/src/community/index.md
new file mode 100644
index 00000000..77d43d7e
--- /dev/null
+++ b/src/community/index.md
@@ -0,0 +1,10 @@
+---
+sidebar: false
+layout: page
+---
+
+
+
+
diff --git a/src/community/join.md b/src/community/join.md
deleted file mode 100644
index 5a74d01c..00000000
--- a/src/community/join.md
+++ /dev/null
@@ -1,58 +0,0 @@
----
-title: "Our Community"
----
-
-# Join the Leaf PHP Community!
-
-Leaf's community is growing incredibly fast and if you're reading this, there's a good chance you're ready to join it. So... welcome!
-
-Now we'll answer both what the community can do for you and what you can do for the community.
-
-## Resources
-
-### Code of Conduct
-
-Our [Code of Conduct](/coc/) is a guide to make it easier to enrich all of us and the technical communities in which we participate.
-
-### Get Support
-
-- [Forum](https://github.com/leafsphp/leaf/discussions/37): The best place to ask questions and get answers about Leaf and its ecosystem.
-- [GitHub](https://github.com/leafsphp/leaf): If you have a bug to report or feature to request, that's what the GitHub issues are for. We also welcome pull requests!
-- [Discord server](https://discord.gg/Pkrm9NJPE3): A place for Leaf devs to meet and chat in real time.
-
-
-
-## What You Can Do
-
-### Contribute Code
-
-As with any project, there are rules to contributing. To ensure that we can help you or accept your pull request as quickly as possible, please read [the contributing guide](/community/contributing/).
-
-After that, you'll be ready to contribute to Leaf's core repositories:
-
-- [Leaf](https://github.com/leafsphp/leaf): the core library
-- [Leaf MVC](https://github.com/leafsphp/leafMVC): MVC powered wrapper around Leaf PHP
-- [Leaf API](https://github.com/leafsphp/leafAPI): MVC powered wrapper specialized for building APIs.
-
-...as well as many smaller official [companion libraries](https://github.com/leafsphp).
-
-### Share (and Build) Your Experience
-
-Apart from answering questions and sharing resources in the forum and chat, there are a few other less obvious ways to share and expand what you know:
-
-- **Develop learning materials.** It's often said that the best way to learn is to teach. If there's something interesting you're doing with Leaf, strengthen your expertise by writing a blog post, developing a workshop, or even publishing a gist that you share on social media.
-- **Watch a repo you care about.** This will send you notifications whenever there's activity in that repository, giving you insider knowledge about ongoing discussions and upcoming features. It's a fantastic way to build expertise so that you're eventually able to help address issues and pull requests.
-
-### Help manage our Community
-
-With the growth of Leaf, we need more hands to moderate activities on our discord chat, keep up with our documentation, GitHub discussions, twitter and the like.
-
-If you want to help with any of these, kindly reach out on twitter [@leafphp](https://twitter.com/leafphp) or email [mychi@leafphp.dev](mailto:mychi@leafphp.dev)
-
-## Updates
-
-- [Youtube](https://twitter.com/leafphp): Get online streams, talks and tutorials on leaf and community packages.
-
-- [Twitter](https://twitter.com/leafphp): Get timely updates on everything that happens in the leaf PHP ecosystem.
-
-
diff --git a/src/community/releases.md b/src/community/releases.md
index e43c6775..e90aacb9 100644
--- a/src/community/releases.md
+++ b/src/community/releases.md
@@ -1,32 +1,14 @@
---
-outline: deep
+sidebar: false
+editLink: false
+prev: false
+next: false
+lastUpdated: false
---
-
-
# Releases
-
-The current latest stable version of Vue is {{ version }} .
-
-
-Checking latest version...
-
-
-A full changelog of past releases is available on [GitHub](https://github.com/vuejs/core/blob/main/CHANGELOG.md).
-
-## Release Cycle
-
-Vue does not have a fixed release cycle.
+This document outlines the release process for Leaf. We don't have a fixed release cycle, but we do follow a few guidelines to ensure that we ship stable releases with new features and bug fixes. We use [Semantic Versioning](https://semver.org/) for versioning.
- Patch releases are released as needed.
@@ -36,42 +18,54 @@ Vue does not have a fixed release cycle.
## Semantic Versioning Edge Cases
-Vue releases follow [Semantic Versioning](https://semver.org/) with a few edge cases.
+There are a cases where we may deviate from the strict SemVer rules:
-### TypeScript Definitions
+### Deprecations
-We may ship incompatible changes to TypeScript definitions between **minor** versions. This is because:
+We may periodically deprecate features that have new, better replacements in minor releases. We may also switch our base supported version of PHP or other dependencies in minor releases. In these cases, we will bump the minor version number.
-1. Sometimes TypeScript itself ships incompatible changes between minor versions, and we may have to adjust types to support newer versions of TypeScript.
+### RFCs
-2. Occasionally we may need to adopt features that are only available in a newer version of TypeScript, raising the minimum required version of TypeScript.
+New features and major changes to Leaf will undergo the **Request for Comments** (RFC) process. This ensures a controlled and transparent path for introducing new features, allowing the community to participate in and provide feedback on the design process before changes are implemented. Features that are introduced through the RFC process will be considered stable and will not be subject to the usual deprecation rules.
-If you are using TypeScript, you can use a semver range that locks the current minor and manually upgrade when a new minor version of Vue is released.
+### Security Releases
-### Compiled Code Compatibility with Older Runtime
+Security releases will be released as needed. We will always provide a security release for the latest minor version of Leaf. There are cases where fixing a security issue may require a breaking change, in which case we will release a new minor version.
-A newer **minor** version of Vue compiler may generate code that isn't compatible with the Vue runtime from an older minor version. For example, code generated by Vue 3.2 compiler may not be fully compatible if consumed by the runtime from Vue 3.1.
+## Latest Leaf Release
-This is only a concern for library authors, because in applications, the compiler version and the runtime version is always the same. A version mismatch can only happen if you ship pre-compiled Vue component code as a package, and a consumer uses it in a project using an older version of Vue. As a result, your package may need to explicit declare a minimum required minor version of Vue.
+You can find the latest stable release of Leaf on our [GitHub page](https://github.com/leafsphp/leaf/releases/latest)
-## Pre Releases
+```markdown:no-line-numbers
+```
-Minor releases typically go through a non-fixed number of beta releases. Major releases will go through an alpha phase and a beta phase.
+
-Pre-releases are meant for integration / stability testing, and for early adopters to provide feedback for unstable features. Do not use pre-releases in production. All pre-releases are considered unstable and may ship breaking changes in between, so always pin to exact versions when using pre-releases.
+## Latest Leaf MVC Release
-## Deprecations
+The latest stable release of Leaf MVC can be found on the Leaf MVC GitHub releases page
-We may periodically deprecate features that have new, better replacements in minor releases. Deprecated features will continue to work, and will be removed in the next major release after it entered deprecated status.
+```markdown
+## v3.4 - 25 August 2024
-## RFCs
+### Added
-New features with substantial API surface and major changes to Vue will go through the **Request for Comments** (RFC) process. The RFC process is intended to provide a consistent and controlled path for new features to enter the framework, and give the users an opportunity to participate and offer feedback in the design process.
+- Added CSRF config file by @ibnsultan
+- Added `SESSION_REDIRECT_ON_REGISTER` auth config
-The RFC process is conducted in the [vuejs/rfcs](https://github.com/vuejs/rfcs) repo on GitHub.
+### Changed
-## Experimental Features
+- Switched internals to new Leaf config API
-Some features are shipped and documented in a stable version of Vue, but marked as experimental. Experimental features are typically features that have an associated RFC discussion with most of the design problems resolved on paper, but still lacking feedback from real world usage.
+### Removed
-The goal of experimental features is to allow users to provide feedback for them by testing them in a production setting, without having to use an unstable version of Vue. Experimental features themselves are considered unstable, and should only be used in a controlled manner, with the expectation that the feature may change between any release types.
+- Discontinued custom public and assets paths
+```
diff --git a/src/community/team.md b/src/community/team.md
index dbde9c81..81632a7f 100644
--- a/src/community/team.md
+++ b/src/community/team.md
@@ -1,11 +1,124 @@
---
-page: true
-title: Meet the Team
sidebar: false
+layout: page
+title: Meet the Team
---
+
+
-
+
+
+ Our Team
+ Core team members are those who are actively involved in the maintenance of one or more core projects. They have made significant contributions to the Leaf ecosystem, with a long term commitment to the success of the project and its users.
+
+
+
+
+ Community Moderators
+
+ Community moderators are volunteers who help maintain the community and keep it a friendly and welcoming place for everyone.
+
+
+
+
+
+
+
+ Former core team members
+
+ Here we honor some no-longer-active core team members who have made valuable contributions in the past.
+
+
+
+
+
+
diff --git a/src/community/team/Member.ts b/src/community/team/Member.ts
deleted file mode 100644
index 9ad76d87..00000000
--- a/src/community/team/Member.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-export interface Member {
- name: string
- avatarPic?: string
- title: string
- company?: string
- companyLink?: string
- projects: Link[]
- location: string
- languages: string[]
- website?: Link
- socials: Socials
- sponsor?: boolean | string
- reposPersonal?: string[]
-}
-
-export interface Link {
- label: string
- url: string
-}
-
-export interface Socials {
- github: string
- twitter?: string
- codepen?: string
- instagram?: string
- linkedin?: string
-}
diff --git a/src/community/team/TeamHero.vue b/src/community/team/TeamHero.vue
deleted file mode 100644
index 0ad0f910..00000000
--- a/src/community/team/TeamHero.vue
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
-
-
diff --git a/src/community/team/TeamList.vue b/src/community/team/TeamList.vue
deleted file mode 100644
index 95aaa1d2..00000000
--- a/src/community/team/TeamList.vue
+++ /dev/null
@@ -1,117 +0,0 @@
-
-
-
-
-
-
-
diff --git a/src/community/team/TeamMember.vue b/src/community/team/TeamMember.vue
deleted file mode 100644
index 70e11d8d..00000000
--- a/src/community/team/TeamMember.vue
+++ /dev/null
@@ -1,395 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
{{ member.name }}
-
- {{ member.title }}
-
- @
-
- {{ member.company }}
-
-
- {{ member.company }}
-
-
-
-
-
-
-
-
Projects
-
-
-
-
-
- {{ project.label }}
-
-
-
-
-
-
-
-
Location
-
-
-
- {{ member.location }}
-
-
-
-
-
-
-
-
Website
-
-
-
-
- {{ member.website.label }}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/src/community/team/TeamPage.vue b/src/community/team/TeamPage.vue
deleted file mode 100644
index 12b89dd9..00000000
--- a/src/community/team/TeamPage.vue
+++ /dev/null
@@ -1,79 +0,0 @@
-
-
-
-
-
-
-
- Meet the Team
- The development of Leaf and its ecosystem is guided by a our
- core team.
-
-
-
-
-
- Core Team Members
- Core team members are those who are actively involved in the
- maintenance of one or more core projects. They have made significant
- contributions to the Leaf ecosystem, with a long term commitment to the
- success of the project and its users.
-
-
-
-
-
-
-
-
-
diff --git a/src/community/team/members-core.json b/src/community/team/members-core.json
deleted file mode 100644
index 4d3bc5a7..00000000
--- a/src/community/team/members-core.json
+++ /dev/null
@@ -1,57 +0,0 @@
-[
- {
- "name": "Michael Darko",
- "title": "Creator/Maintainer",
- "company": "Leaf PHP",
- "projects": [
- {
- "label": "leafsphp/*",
- "url": "https://www.github.com/leafsphp"
- }
- ],
- "location": "Ghana",
- "languages": ["English"],
- "socials": {
- "github": "mychidarko",
- "twitter": "mychidarko"
- },
- "sponsor": false
- },
- {
- "name": "André Rosa",
- "title": "Developer",
- "company": "Leaf PHP",
- "projects": [
- {
- "label": "leafsphp/*",
- "url": "https://www.github.com/leafsphp"
- }
- ],
- "location": "Portugal",
- "languages": ["Portuguese", "English"],
- "socials": {
- "github": "crosa7",
- "twitter": "andre_crosa"
- },
- "sponsor": false
- },
- {
- "name": "Ashley Nyanteh",
- "title": "Community Manager",
- "avatarPic": "https://user-images.githubusercontent.com/26604242/221550910-1a711f42-9589-4981-96e0-d0de19778e7a.png",
- "company": "Leaf PHP",
- "projects": [
- {
- "label": "Leaf PHP Community",
- "url": "https://bento.me/leafphp"
- }
- ],
- "location": "Ghana",
- "languages": ["English"],
- "socials": {
- "twitter": "ashleybruwaa",
- "linkedin": "ashley-bruwah-nyanteh-1811691b4"
- },
- "sponsor": false
- }
-]
diff --git a/src/community/team/members-emeriti.json b/src/community/team/members-emeriti.json
deleted file mode 100644
index 62081660..00000000
--- a/src/community/team/members-emeriti.json
+++ /dev/null
@@ -1,241 +0,0 @@
-[
- {
- "name": "Sarah Drasner",
- "title": "Director of Engineering, Core Developer Web",
- "company": "Google",
- "companyLink": "https://google.com",
- "projects": [
- {
- "label": "vuejs.org",
- "url": "https://github.com/vuejs/vuejs.org"
- },
- {
- "label": "vue-vscode-snippets",
- "url": "https://github.com/sdras/vue-vscode-snippets"
- },
- {
- "label": "intro-to-vue",
- "url": "https://github.com/sdras/intro-to-vue"
- },
- {
- "label": "vue-vscode-extensionpack",
- "url": "https://github.com/sdras/vue-vscode-extensionpack"
- },
- {
- "label": "ecommerce-netlify",
- "url": "https://github.com/sdras/ecommerce-netlify"
- }
- ],
- "location": "Denver, CO, USA",
- "languages": ["English"],
- "website": {
- "label": "sarah.dev",
- "url": "https://sarah.dev/"
- },
- "socials": {
- "github": "sdras",
- "twitter": "sarah_edo",
- "codepen": "sdras"
- }
- },
- {
- "name": "Chris Fritz",
- "title": "Educator & Consultant",
- "location": "Durham, NC, USA",
- "languages": ["English", "German"],
- "socials": {
- "github": "chrisvfritz",
- "twitter": "chrisvfritz"
- },
- "reposPersonal": ["vue-enterprise-boilerplate"]
- },
- {
- "name": "Blake Newman",
- "title": "Performance Specializer & Code Deleter",
- "location": "London, UK",
- "languages": ["English"],
- "socials": {
- "github": "blake-newman",
- "twitter": "blakenewman"
- }
- },
- {
- "name": "kingwl",
- "title": "Software Development Engineer",
- "company": "Chaitin",
- "companyLink": "https://chaitin.cn/",
- "projects": [
- {
- "label": "vue",
- "url": "https://github.com/vuejs/vue"
- }
- ],
- "location": "Beijing, China",
- "languages": ["Chinese"],
- "socials": {
- "github": "kingwl"
- }
- },
- {
- "name": "Alan Song",
- "title": "Cofounder",
- "company": "Futurenda",
- "companyLink": "https://www.futurenda.com/",
- "projects": [
- {
- "label": "vue-router",
- "url": "https://github.com/vuejs/vue-router"
- }
- ],
- "location": "Hangzhou, China",
- "languages": ["Chinese", "English"],
- "socials": {
- "github": "fnlctrl"
- }
- },
- {
- "name": "defcc",
- "title": "Details Deity & Bug Surgeon",
- "company": "zbj.com",
- "companyLink": "http://www.zbj.com/",
- "location": "Chongqing, China",
- "languages": ["Chinese", "English"],
- "socials": {
- "github": "defcc"
- }
- },
- {
- "name": "gebilaoxiong",
- "title": "Issue Annihilator",
- "company": "zbj.com",
- "companyLink": "http://www.zbj.com/",
- "location": "Chongqing, China",
- "languages": ["Chinese", "English"],
- "socials": {
- "github": "gebilaoxiong"
- }
- },
- {
- "name": "Denis Karabaza",
- "title": "Software Engineer",
- "company": "Neolant",
- "companyLink": "http://neolant.ru/",
- "location": "Dubna, Russia",
- "languages": ["Russian", "English"],
- "socials": {
- "github": "simplesmiler",
- "twitter": "simplesmiler"
- }
- },
- {
- "name": "Edd Yerburgh",
- "title": "Full Stack Developer",
- "projects": [
- {
- "label": "vue-test-utils",
- "url": "https://github.com/vuejs/vue-test-utils"
- },
- {
- "label": "avoriaz",
- "url": "https://github.com/avoriaz"
- }
- ],
- "location": "London, UK",
- "languages": ["English"],
- "socials": {
- "github": "eddyerburgh",
- "twitter": "EddYerburgh"
- },
- "website": {
- "label": "www.eddyerburgh.me",
- "url": "https://www.eddyerburgh.me"
- }
- },
- {
- "name": "Pine Wu",
- "title": "Nomad",
- "projects": [
- {
- "label": "vetur",
- "url": "https://github.com/vuejs/vetur"
- }
- ],
- "location": "Shanghai, China",
- "languages": ["Chinese", "English", "Japanese"],
- "socials": {
- "github": "octref",
- "twitter": "octref"
- }
- },
- {
- "name": "ULIVZ",
- "title": "Senior Frontend Developer",
- "company": "AntFinancial",
- "companyLink": "https://www.antfin.com",
- "projects": [
- {
- "label": "vuepress",
- "url": "https://www.github.com/vuejs/vuepress"
- }
- ],
- "location": "Hangzhou, China",
- "languages": ["Chinese", "English"],
- "socials": { "github": "ulivz", "twitter": "_ulivz" }
- },
- {
- "name": "Katashin",
- "title": "Software Engineer",
- "company": "ClassDo",
- "companyLink": "https://classdo.com",
- "projects": [
- {
- "label": "vuex",
- "url": "https://github.com/vuejs/vuex"
- },
- {
- "label": "vue-class-component",
- "url": "https://github.com/vuejs/vue-class-component"
- },
- {
- "label": "vue-designer",
- "url": "https://github.com/ktsn/vue-designer"
- }
- ],
- "location": "Singapore",
- "languages": ["Japanese", "English"],
- "socials": {
- "github": "ktsn",
- "twitter": "ktsn"
- }
- },
- {
- "name": "Michał Sajnóg",
- "title": "Senior Frontend Developer / Team Leader",
- "company": "Netguru",
- "companyLink": "https://netguru.co/",
- "location": "Poznań, Poland",
- "languages": ["Polish", "English"],
- "projects": [
- {
- "label": "eslint-plugin-vue",
- "url": "https://github.com/vuejs/eslint-plugin-vue"
- },
- {
- "label": "vue-devtools",
- "url": "https://github.com/vuejs/devtools"
- },
- {
- "label": "vue-computed-helpers",
- "url": "https://github.com/michalsnik/vue-computed-helpers"
- },
- {
- "label": "vue-content-placeholders",
- "url": "https://github.com/michalsnik/vue-content-placeholders"
- }
- ],
- "socials": {
- "github": "michalsnik",
- "twitter": "michalsnik"
- }
- }
-]
diff --git a/src/community/team/members-partner.json b/src/community/team/members-partner.json
deleted file mode 100644
index d28634ba..00000000
--- a/src/community/team/members-partner.json
+++ /dev/null
@@ -1,651 +0,0 @@
-[
- {
- "name": "Maria Lamardo",
- "title": "Front End Engineer",
- "company": "Pendo",
- "projects": [
- {
- "label": "vuejs/events",
- "url": "https://github.com/vuejs/events"
- }
- ],
- "location": "Raleigh, NC, USA",
- "languages": ["English", "Spanish"],
- "socials": {
- "github": "mlama007",
- "twitter": "MariaLamardo"
- }
- },
- {
- "name": "Daniel Roe",
- "title": "Framework Architect",
- "company": "Nuxt",
- "projects": [
- {
- "label": "nuxt",
- "url": "https://github.com/nuxt"
- },
- {
- "label": "typed-vuex",
- "url": "https://github.com/danielroe/typed-vuex"
- }
- ],
- "location": "United Kingdom",
- "languages": ["English"],
- "socials": {
- "github": "danielroe",
- "twitter": "danielcroe",
- "linkedin": "daniel-roe"
- }
- },
- {
- "name": "Pratik Patel",
- "avatarPic": "https://pbs.twimg.com/profile_images/1541624512/profile-pic-09-11-2011_400x400.png",
- "title": "Organizer",
- "company": "VueConf US",
- "projects": [
- {
- "label": "us.vuejs.org",
- "url": "https://us.vuejs.org/"
- }
- ],
- "location": "Atlanta, GA, USA",
- "languages": ["English"],
- "socials": {
- "twitter": "prpatel"
- }
- },
- {
- "name": "Vincent Mayers",
- "avatarPic": "https://pbs.twimg.com/profile_images/916531463905992706/MNvTkO5K_400x400.jpg",
- "title": "Organizer",
- "company": "VueConf US",
- "projects": [
- {
- "label": "us.vuejs.org",
- "url": "https://us.vuejs.org/"
- }
- ],
- "location": "Atlanta, GA, USA",
- "languages": ["English"],
- "socials": {
- "twitter": "vincentmayers"
- }
- },
- {
- "name": "Luke Thomas",
- "avatarPic": "https://pbs.twimg.com/profile_images/1123492769299877888/aviXE_M5_400x400.jpg",
- "title": "Creator",
- "company": "Vue.js Amsterdam",
- "projects": [
- {
- "label": "vuejs.amsterdam",
- "url": "https://vuejs.amsterdam"
- }
- ],
- "location": "Amsterdam, Netherlands",
- "languages": ["Dutch", "English", "German"],
- "socials": {
- "twitter": "lukevscostas",
- "linkedin": "luke-kenneth-thomas-578b3916a"
- }
- },
- {
- "name": "Jos Gerards",
- "avatarPic": "https://pbs.twimg.com/profile_images/1110510517951627269/LDzDyd4N_400x400.jpg",
- "title": "Event Manager",
- "company": "Vue.js Amsterdam",
- "projects": [
- {
- "label": "vuejs.amsterdam",
- "url": "https://vuejs.amsterdam"
- }
- ],
- "location": "Amsterdam, Netherlands",
- "languages": ["Dutch", "English", "German"],
- "socials": {
- "twitter": "josgerards88",
- "linkedin": "josgerards"
- }
- },
- {
- "name": "Jen Looper",
- "title": "CEO",
- "company": "Vue Vixens",
- "projects": [
- {
- "label": "vuevixens.org",
- "url": "https://vuevixens.org/"
- },
- {
- "label": "nativescript-vue.org",
- "url": "https://nativescript-vue.org/"
- }
- ],
- "location": "Boston, MA, USA",
- "languages": ["English", "French"],
- "socials": {
- "github": "jlooper",
- "twitter": "jenlooper"
- }
- },
- {
- "name": "Alex Jover",
- "title": "Web, PWA and Performance Consultant",
- "company": "Freelance",
- "projects": [
- {
- "label": "v-runtime-template",
- "url": "https://github.com/alexjoverm/v-runtime-template"
- },
- {
- "label": "v-lazy-image",
- "url": "https://github.com/alexjoverm/v-lazy-image"
- },
- {
- "label": "vue-testing-series",
- "url": "https://github.com/alexjoverm/vue-testing-series"
- }
- ],
- "location": "Alicante, Spain",
- "languages": ["Spanish", "English"],
- "website": {
- "label": "alexjover.com",
- "url": "https://alexjover.com"
- },
- "socials": {
- "github": "alexjoverm",
- "twitter": "alexjoverm"
- }
- },
- {
- "name": "Sebastien Chopin",
- "title": "#1 Nuxt Brother",
- "company": "NuxtJS",
- "companyLink": "https://nuxtjs.org",
- "location": "Bordeaux, France",
- "languages": ["French", "English"],
- "projects": [
- {
- "label": "nuxt/*",
- "url": "https://github.com/nuxt"
- },
- {
- "label": "nuxt-community/*",
- "url": "https://github.com/nuxt-community"
- },
- {
- "label": "nuxt/vue-meta",
- "url": "https://github.com/nuxt/vue-meta"
- }
- ],
- "socials": {
- "github": "Atinux",
- "twitter": "Atinux"
- }
- },
- {
- "name": "Alexandre Chopin",
- "title": "#1 Nuxt Brother",
- "company": "NuxtJS",
- "companyLink": "https://nuxtjs.org",
- "location": "Bordeaux, France",
- "languages": ["French", "English"],
- "projects": [
- {
- "label": "nuxt/*",
- "url": "https://github.com/nuxt"
- },
- {
- "label": "nuxt-community/*",
- "url": "https://github.com/nuxt-community"
- },
- {
- "label": "vue-flexboxgrid",
- "url": "https://github.com/alexchopin/vue-flexboxgrid"
- }
- ],
- "socials": {
- "github": "alexchopin",
- "twitter": "iamnuxt"
- }
- },
- {
- "name": "Khary Sharpe",
- "title": "Viral Newscaster",
- "location": "Kingston, Jamaica",
- "languages": ["English"],
- "projects": [
- {
- "label": "VueJsNews",
- "url": "https://twitter.com/VueJsNews"
- }
- ],
- "website": {
- "label": "www.kharysharpe.com",
- "url": "http://www.kharysharpe.com/"
- },
- "socials": {
- "github": "kharysharpe",
- "twitter": "kharysharpe"
- }
- },
- {
- "name": "Pooya Parsa",
- "title": "Technical Advisor",
- "company": "Fandogh (AUT University)",
- "companyLink": "https://fandogh.org",
- "location": "Tehran, Iran",
- "languages": ["Persian", "English"],
- "projects": [
- {
- "label": "nuxt/*",
- "url": "https://github.com/nuxt"
- },
- {
- "label": "nuxt-community/*",
- "url": "https://github.com/nuxt-community"
- },
- {
- "label": "bootstrap-vue/*",
- "url": "https://github.com/bootstrap-vue"
- }
- ],
- "socials": {
- "github": "pi0",
- "twitter": "_pi0_"
- }
- },
- {
- "name": "Xin Du",
- "title": "Nuxpert",
- "location": "Dublin, Ireland",
- "languages": ["Chinese", "English"],
- "projects": [
- {
- "label": "nuxt/*",
- "url": "https://github/com/nuxt"
- },
- {
- "label": "nuxt-community/*",
- "url": "https://github/com/nuxt-community"
- }
- ],
- "socials": {
- "github": "clarkdo",
- "twitter": "ClarkDu_"
- }
- },
- {
- "name": "Yi Yang",
- "title": "Interface Elementologist",
- "company": "ele.me",
- "companyLink": "https://www.ele.me",
- "location": "Shanghai, China",
- "languages": ["Chinese", "English"],
- "projects": [
- {
- "label": "elemefe/element",
- "url": "https://github.com/elemefe/element"
- },
- {
- "label": "elemefe/mint-ui",
- "url": "https://github.com/elemefe/mint-ui"
- }
- ],
- "socials": {
- "github": "Leopoldthecoder"
- }
- },
- {
- "name": "Bruno Lesieur",
- "title": "Cofounder",
- "company": "Orchard ID",
- "companyLink": "https://www.orchard-id.com/",
- "projects": [
- {
- "label": "vuejs-fr/*",
- "url": "https://vuejs-fr"
- },
- {
- "label": "vuejs-fr/*",
- "url": "https://Haeresis/node-atlas-hello-vue"
- },
- {
- "label": "https://node-atlas.js.org/",
- "url": "https://node-atlas.js.org/"
- }
- ],
- "location": "Annecy, France",
- "languages": ["French", "English"],
- "website": {
- "label": "blog.lesieur.name/",
- "url": "https://blog.lesieur.name/"
- },
- "socials": {
- "github": "Haeresis",
- "twitter": "ZetesEthique"
- }
- },
- {
- "name": "ChangJoo Park",
- "title": "Vuenthusiastic Korean Community Organizer",
- "location": "Seoul, South Korea",
- "languages": ["Korean", "English"],
- "projects": [
- {
- "label": "vuejs-kr/kr.vuejs.org",
- "url": "https://github.com/vuejs-kr/kr.vuejs.org"
- },
- {
- "label": "ChangJoo-Park/vue-component-generator",
- "url": "https://github.com/ChangJoo-Park/vue-component-generator"
- },
- {
- "label": "vuejs-kr.github.io",
- "url": "https://vuejs-kr.github.io"
- }
- ],
- "socials": {
- "github": "changjoo-park",
- "twitter": "pcjpcj2"
- }
- },
- {
- "name": "Erick Petrucelli",
- "title": "Head of Engineering",
- "company": "Airbank",
- "companyLink": "https://www.joinairbank.com/",
- "location": "João Pessoa, Brazil",
- "languages": ["Portuguese", "English"],
- "projects": [
- {
- "label": "vuejs-br",
- "url": "https://github.com/vuejs-br"
- }
- ],
- "socials": {
- "github": "ErickPetru",
- "linkedin": "erick-petrucelli",
- "twitter": "erickpetru"
- }
- },
- {
- "name": "Razvan Stoenescu",
- "title": "Deep Space Quasar Creator",
- "company": "Quasar Framework",
- "companyLink": "https://quasar.dev/",
- "location": "Bucharest, Romania",
- "languages": ["Romanian", "English"],
- "projects": [
- {
- "label": "quasarframework/quasar",
- "url": "https://github.com/quasarframework/quasar"
- },
- {
- "label": "quasarframework",
- "url": "https://github.com/quasarframework"
- }
- ],
- "socials": {
- "github": "rstoenescu",
- "twitter": "quasarframework"
- }
- },
- {
- "name": "Jilson Thomas",
- "title": "Senior Frontend Developer",
- "company": "Nominator",
- "companyLink": "https://nominator.com/",
- "projects": [
- {
- "label": "vuejobs.com",
- "url": "https://vuejobs.com"
- }
- ],
- "location": "Toronto, Canada",
- "languages": ["English"],
- "socials": {
- "github": "JillzTom",
- "twitter": "jilsonthomas"
- }
- },
- {
- "name": "Israel Ortuño",
- "title": "Full Stack Web Developer",
- "company": "Freelance",
- "projects": [
- {
- "label": "vuejobs.com",
- "url": "https://vuejobs.com"
- }
- ],
- "location": "Alicante, Spain",
- "languages": ["Spanish", "English"],
- "socials": {
- "github": "IsraelOrtuno",
- "twitter": "IsraelOrtuno"
- }
- },
- {
- "name": "John Leider",
- "title": "CEO",
- "company": "Vuetify LLC",
- "companyLink": "https://vuetifyjs.com",
- "location": "Fort Worth, TX, USA",
- "languages": ["English"],
- "projects": [
- {
- "label": "vuetifyjs/vuetify",
- "url": "https://github.com/vuetifyjs/vuetify"
- }
- ],
- "socials": {
- "github": "vuetifyjs",
- "twitter": "vuetifyjs"
- }
- },
- {
- "name": "Grigoriy Beziuk",
- "title": "Full Stack Web Developer",
- "company": "Self Employed",
- "companyLink": "http://gbezyuk.ru",
- "location": "Moscow, Russia",
- "languages": ["Russian", "German", "English"],
- "projects": [
- {
- "label": "translation-gang/ru.vuejs.org",
- "url": "https://github.com/translation-gang/ru.vuejs.org"
- }
- ],
- "socials": {
- "github": "gbezyuk"
- }
- },
- {
- "name": "Alexander Sokolov",
- "title": "Russian Translation Sharp Eye",
- "location": "Krasnodar, Russia",
- "languages": ["Russian", "English"],
- "projects": [
- {
- "label": "translation-gang/ru.vuejs.org",
- "url": "https://github.com/translation-gang/ru.vuejs.org"
- }
- ],
- "socials": { "github": "Alex-Sokolov" }
- },
- {
- "name": "Anthony Gore",
- "title": "Author",
- "company": "Vue.js Developers",
- "companyLink": "https://vuejsdevelopers.com/",
- "location": "Sydney, Australia",
- "languages": ["English"],
- "website": {
- "label": "vuejsdevelopers.com",
- "url": "https://vuejsdevelopers.com"
- },
- "socials": { "github": "anthonygore", "twitter": "anthonygore" }
- },
- {
- "name": "EGOIST",
- "title": "Build Tool Simplificator",
- "location": "Chengdu, China",
- "projects": [
- {
- "label": "poi",
- "url": "https://github.com/egoist/poi"
- },
- {
- "label": "ream",
- "url": "https://github.com/egoist/ream"
- },
- {
- "label": "vue-play",
- "url": "https://github.com/egoist/vue-play"
- }
- ],
- "languages": ["Chinese", "English"],
- "socials": { "github": "egoist", "twitter": "_egoistlily" }
- },
- {
- "name": "Alex Kyriakidis",
- "title": "Consultant / Author",
- "location": "Thessaloniki, Greece",
- "languages": ["el", "English"],
- "socials": { "github": "hootlex", "twitter": "hootlex" },
- "projects": [
- {
- "label": "vuejs-paginator",
- "url": "https://github.com/hootlex/vuejs-paginator"
- },
- {
- "label": "vuedo/vuedo",
- "url": "https://github.com/vuedo/vuedo"
- },
- {
- "label": "the-majesty-of-vuejs-2",
- "url": "https://github.com/hootlex/the-majesty-of-vuejs-2"
- },
- {
- "label": "vuejsfeed.com",
- "url": "https://vuejsfeed.com/"
- },
- {
- "label": "vueschool.io",
- "url": "https://vueschool.io/"
- }
- ]
- },
- {
- "name": "Rolf Haug",
- "title": "Educator & Consultant",
- "company": "Vue School",
- "companyLink": "https://vueschool.io/",
- "location": "Oslo, Norway",
- "languages": ["English"],
- "projects": [
- {
- "label": "vueschool.io",
- "url": "https://vueschool.io/"
- }
- ],
- "website": {
- "label": "rah.no",
- "url": "https://rah.no"
- },
- "socials": { "github": "rahaug", "twitter": "rahaug" }
- },
- {
- "name": "Andrew Tomaka",
- "title": "The Server Server",
- "company": "Michigan State University",
- "companyLink": "https://msu.edu/",
- "location": "East Lansing, MI, USA",
- "languages": ["English"],
- "projects": [
- {
- "label": "vuejs/*",
- "url": "https://www.github.com/vuejs"
- }
- ],
- "socials": { "github": "atomaka", "twitter": "atomaka" },
- "website": {
- "label": "atomaka.com",
- "url": "https://atomaka.com/"
- }
- },
- {
- "name": "Blake Newman",
- "title": "Software Engineer",
- "company": "Attest",
- "companyLink": "https://www.askattest.com/",
- "location": "London, UK",
- "languages": ["English"],
- "projects": [
- {
- "label": "vuejs.london",
- "url": "https://vuejs.london"
- }
- ],
- "socials": { "github": "blake-newman", "twitter": "blakenewman" }
- },
- {
- "name": "Filip Rakowski",
- "title": "Co-founder of Vue Storefront",
- "company": "Divante",
- "companyLink": "https://divante.co/",
- "location": "Wrocław, Poland",
- "languages": ["Polish", "English"],
- "projects": [
- {
- "label": "DivanteLtd/vue-storefront",
- "url": "https://vuestorefront.io"
- },
- {
- "label": "DivanteLtd/storefront-ui",
- "url": "https://storefrontui.io"
- }
- ],
- "socials": { "github": "filrak", "twitter": "filrakowski" }
- },
- {
- "name": "Gregg Pollack",
- "title": "Vue Instructor",
- "company": "Vue Mastery",
- "companyLink": "https://www.vuemastery.com/",
- "location": "Orlando, FL, USA",
- "languages": ["English"],
- "projects": [
- {
- "label": "www.vuemastery.com",
- "url": "https://www.vuemastery.com"
- },
- {
- "label": "news.vuejs.org/",
- "url": "https://news.vuejs.org/"
- }
- ],
- "socials": { "github": "gregg", "twitter": "greggpollack" }
- },
- {
- "name": "Adam Jahr",
- "title": "Vue Instructor",
- "company": "Vue Mastery",
- "companyLink": "https://www.vuemastery.com/",
- "location": "Orlando, FL, USA",
- "languages": ["English"],
- "projects": [
- {
- "label": "www.vuemastery.com",
- "url": "https://www.vuemastery.com"
- },
- {
- "label": "news.vuejs.org/",
- "url": "https://news.vuejs.org/"
- }
- ],
- "socials": { "github": "atomjar", "twitter": "adamjahr" }
- }
-]
diff --git a/src/community/team/members-translation.json b/src/community/team/members-translation.json
deleted file mode 100644
index 852fcb8d..00000000
--- a/src/community/team/members-translation.json
+++ /dev/null
@@ -1,39 +0,0 @@
-[
- {
- "name": "Michael Darko",
- "title": "Creator/Maintainer",
- "company": "Leaf PHP",
- "projects": [
- {
- "label": "leafsphp/*",
- "url": "https://www.github.com/leafsphp"
- }
- ],
- "location": "Ghana",
- "languages": ["English"],
- "socials": {
- "github": "mychidarko",
- "twitter": "mychidarko"
- },
- "sponsor": false
- },
- {
- "name": "Ashley Nyanteh",
- "title": "Community Manager",
- "avatarPic": "https://user-images.githubusercontent.com/26604242/221550910-1a711f42-9589-4981-96e0-d0de19778e7a.png",
- "company": "Leaf PHP",
- "projects": [
- {
- "label": "Leaf PHP Community",
- "url": "https://bento.me/leafphp"
- }
- ],
- "location": "Ghana",
- "languages": ["English"],
- "socials": {
- "instagram": "bruwaaaa",
- "twitter": "ashleybruwaa"
- },
- "sponsor": false
- }
-]
diff --git a/src/docs/auth/config.md b/src/docs/auth/config.md
new file mode 100644
index 00000000..b4bf67e5
--- /dev/null
+++ b/src/docs/auth/config.md
@@ -0,0 +1,73 @@
+# Auth Config
+
+We understand that every application is different and may require a different level of control over the authentication system. Whether you want to use tokens, sessions, or your own custom setup, you can configure it without any hassle.
+
+Leaf Auth is flexible enough to adapt to whatever system works best for you.
+
+If you are using Leaf MVC, we have already created a config file available at `config/auth.php`. You can follow this documentation to update your config file.
+
+## Specifying the table to use
+
+Leaf assumes that you will save your users in a table named `users`. If you want to use a different table, you can configure Leaf Auth using `db.table`:
+
+```php:no-line-numbers
+auth()->config('db.table', 'admins');
+```
+
+## Specifying the primary key
+
+Most databases use `id` as the primary key. If you are using a different field as the primary key, you can configure Leaf Auth using `id.key`:
+
+```php:no-line-numbers
+auth()->config('id.key', 'admin_id');
+```
+
+If you are using UUIDs as your primary key, you can configure Leaf Auth to use them:
+
+```php:no-line-numbers
+auth()->config('id.uuid', UUID::v4());
+```
+
+## Using timestamps
+
+Leaf will always try to set the `created_at` and `updated_at` fields in your database. If you want to turn this off, you can set `timestamps` to `false`:
+
+```php:no-line-numbers
+auth()->config('timestamps', false);
+```
+
+Different databases have different ways of handling timestamps. If you get an error concerning the format of the timestamp, you can configure Leaf Auth to use a different format:
+
+```php:no-line-numbers
+auth()->config('timestamps.format', 'YYYY-MM-DD HH:MM:SS');
+```
+
+You can find the date format documentation [here](/docs/utils/date#formatting-dates).
+
+## Create session on registration
+
+Leaf will require a user to manually login after registration. If you want to automatically log in a user after registration, you can configure Leaf Auth to do that:
+
+```php:no-line-numbers
+auth()->config('session.register', true);
+```
+
+You can also set the redirect URL after registration:
+
+```php:no-line-numbers
+auth()->config('session.registerRedirect', '/dashboard');
+```
+
+## Auth with tokens
+
+This is the default way Leaf handles authentication. There are a few things you can configure to make your token authentication more secure like the token lifetime:
+
+```php:no-line-numbers
+auth()->config('token.lifetime', 3600); // 1 hour
+```
+
+You can also set the secret key for your tokens:
+
+```php:no-line-numbers
+auth()->config('token.secret', 'your-secret-key');
+```
diff --git a/src/docs/auth/index.md b/src/docs/auth/index.md
new file mode 100644
index 00000000..8ac0f138
--- /dev/null
+++ b/src/docs/auth/index.md
@@ -0,0 +1,97 @@
+# Authentication
+
+
+
+Numerous web applications offer their users a means to authenticate and access the application by "logging in." Adding this functionality to web applications can be a challenging and potentially dangerous task.
+
+Leaf provides a lightweight but very powerful authentication system to handle all the complexities of authentication in a few lines of code. We understand that authentication is a critical part of your application, so we've made it as simple and secure as possible.
+
+## Setting up
+
+You can install Leaf Auth using the Leaf CLI:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install auth
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/auth
+```
+
+:::
+
+The next step is to link your database and start signing users in.
+
+## Connecting to a database
+
+To do any kind of authentication, you need to connect to some kind of database which will store your users' data. If you are already using Leaf DB or Leaf MVC, then your database connection will automatically be used by Leaf Auth, so you don't need to connect to your database again.
+
+If you are not using Leaf DB or Leaf MVC, you can connect to your database manually:
+
+```php
+auth()->connect([
+ 'dbtype' => '...',
+ 'charset' => '...',
+ 'port' => '...',
+ 'host' => '...',
+ 'dbname' => '...',
+ 'user' => '...',
+ 'password' => '...'
+]);
+```
+
+If you have an existing PDO connection, you can pass it to Leaf Auth:
+
+```php
+$db = new PDO('mysql:dbname=test;host=127.0.0.1', 'root', '');
+
+auth()->dbConnection($db);
+
+// you can use leaf auth the same way you always have
+```
+
+## Auth + Leaf MVC
+
+If you are using Leaf MVC, you can set up Leaf Auth to work with your default database connection by heading over to the `public/index.php` file and uncommenting the line that connects to the database:
+
+```php
+/*
+|--------------------------------------------------------------------------
+| Sync Leaf Db with ORM and connect
+|--------------------------------------------------------------------------
+|
+| Sync Leaf Db with ORM and connect to the database
+| This allows you to use Leaf Db without having
+| to initialize it in your controllers.
+|
+| If you want to use a different connection from those
+| used in your models, you can remove the line below and
+| add your own connection with:
+| db()->connect(...)
+|
+| **Uncomment the line below to use Leaf Db**
+| **You don't need this line to use Leaf Auth**
+*/
+// \Leaf\Database::initDb(); [!code --]
+\Leaf\Database::initDb(); // [!code ++]
+```
+
+That's all you need to do. Leaf Auth will automatically connect to your database using the details in your environment file. The auth configuration for your project can be found in the `config/auth.php` file. You can edit this file to change the configuration of Leaf Auth.
+
+## Database Considerations
+
+Leaf Auth doesn't give you any structure for your database, with that, you can structure your database in any way you prefer. However, there are some things you should note:
+
+1. By default, Leaf Auth assumes that your database primary key is `id`. If you have a database where you are using another field, say `admin_id` as the primary key, you will need to tell Leaf the name of your primary key. You can do this using the `id.key` config:
+
+ ```php:no-line-numbers
+ auth()->config('id.key', 'admin_id');
+ ```
+
+2. Leaf Auth assumes that you will save your users in a database table named `users`, this might however not be the case for your application. If you want to use a different table, you can configure Leaf Auth using `db.table`:
+
+ ```php:no-line-numbers
+ auth()->config('db.table', 'admins');
+ ```
diff --git a/src/docs/auth/login.md b/src/docs/auth/login.md
new file mode 100644
index 00000000..29712818
--- /dev/null
+++ b/src/docs/auth/login.md
@@ -0,0 +1,198 @@
+# User Login
+
+
+
+
+
+Leaf Auth provides a flexible and secure login system that works for both token based and session based authentication. It provides a unified way to authenticate users in your web apps and APIs.
+
+::: details Token vs Session Authentication
+
+- Token based authentication is a system where a user is given a token upon login which is then used to authenticate the user on every request. It is the most common authentication system for APIs. This video by Hamy Labs explains how token authentication works
+
+
+
+
+
+
+- Session-based authentication is a method where, after a user logs in, the server creates a session to remember them. Every time the user makes a request, their session ID is sent back to the server to verify their identity, allowing them to stay logged in while using the app.
+
+
+
+:::
+
+## Signing a user in
+
+To sign a user in, you can use the `login()` method. This method takes in an array of data you want to use to authenticate the user. This data is usually the user's email and password, but can be anything as long as the password field is present.
+
+```php
+auth()->login([
+ 'email' => 'm@example.com',
+ 'password' => 'password'
+]);
+```
+
+The `login()` method returns `true` if the user is successfully authenticated and `false` if the user is not authenticated. You can then use the `errors()` method to get the error message.
+
+```php
+$success = auth()->login([
+ 'email' => 'user@example.com',
+ 'password' => 'password'
+]);
+
+if ($success) {
+ // User is authenticated
+} else {
+ // User is not authenticated
+ $error = auth()->errors();
+}
+```
+
+You can get the data and tokens needed for authentication using the `data()` method:
+
+```php
+$data = auth()->data();
+// ['user' => [...], 'accessToken' => '...', 'refreshToken' => '...']
+```
+
+If you want to use a couple of fields from the user within your application, you can use the user method. You can find the documentation for the Auth user method [here](/docs/auth/user).
+
+## Switching to session auth
+
+Leaf uses token based authentication by default which uses a JWT to authenticate your users. Sessions are a more common way to authenticate users in fullstack applications. To switch to session based authentication, you can update your auth config:
+
+```php:no-line-numbers
+auth()->config('session', true);
+```
+
+With the addition of session auth, `login()` will automatically start a session, but will behave in the same way, which means redirects and any other functionality you need will be left up to you to handle:
+
+```php
+auth()->config('session', true);
+
+...
+
+// session is automatically started
+$success = auth()->login([
+ 'email' => 'user@example.com',
+ 'password' => 'password'
+]);
+
+if ($success) {
+ // User is authenticated
+ $user = auth()->user();
+
+ response()->redirect('/dashboard');
+} else {
+ // User is not authenticated
+ $error = auth()->errors();
+}
+```
+
+This lets you handle complex control flows...or the simple redirect ones in a manner you prefer.
+
+If you need finer control over how PHP creates your session, you can add your own config to the `session.cookie` config:
+
+```php
+auth()->config('session.cookie', [
+ 'secure' => true,
+ 'httponly' => true,
+ 'samesite' => 'lax'
+]);
+```
+
+## Auth with no password
+
+Leaf Auth usually expects a password field to authenticate users. This is necessary because most applications require a password to authenticate users. The field is usually named `password`, however, you can configure Leaf Auth to expect a different field:
+
+```php:no-line-numbers
+auth()->config('password.key', 'pass');
+```
+
+Better still, you can turn off password authentication completely. This is useful in multi-step authentication systems, where you might authenticate a set of parameters before authenticating the password. To turn off password authentication, you can configure Leaf Auth like this:
+
+```php:no-line-numbers
+auth()->config('password.key', false);
+```
+
+Once this is done, Leaf will no longer expect a password field to authenticate users and will also turn off password hashing and verification.
+
+## Password verification
+
+Password verification is done to check if a password matches the hashed password in the database. By default, Leaf uses the `Leaf\Helpers\Password::verify` method which has support for `bcrypt` and `argon2`. If you however want to use a different method or turn off password verification, you can do that directly in the config:
+
+```php
+auth()->config('password.verify', false); // turn off verification
+
+auth()->config('password.verify', function ($password, $hash) {
+ return Password::verify($password, $hash);
+});
+```
+
+These are the available options you can pass to `password.verify`:
+
+- `false` - This turns off password verification
+- `null`/`true` - This uses the default verification method (Leaf\Helpers\Password::verify)
+- `function` - This uses a custom method. The method should accept a password and a hash and return a boolean.
+
+## Custom error messages
+
+Leaf Auth provides default error messages for different operations. If you want to customize these messages, you can configure Leaf Auth to use your custom messages:
+
+```php:no-line-numbers
+auth()->config('messages.loginParamsError', 'Username is incorrect!');
+auth()->config('messages.loginPasswordError', 'Password is incorrect!');
+```
+
+## Hiding sensitive information
+
+The output of Leaf's authentication methods is an object with the user's data and the token or session. By default, the password field is hidden from the user data. This is a security measure to prevent the password from being exposed.
+
+```json
+{
+ "user": {
+ "username": "mychidd22",
+ "email": "mychidd22@gmail.com",
+ "created_at": "2024-10-26 19:29:37.000000",
+ "updated_at": "2024-10-26 19:29:37.000000"
+ },
+ "accessToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyLmlkIjo5MjQsImlhdCI6MTczMDAyOTAwNywiZXhwIjo4NjQwMCwiaXNzIjoibG9jYWxob3N0OjU1MDAifQ.yLldIhOkUxn54-3RWLD7PJONoWwqpZ5mmP8fEZ4nNfs",
+ "refreshToken": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyLmlkIjo5MjQsImlhdCI6MTczMDAyOTAwNywiZXhwIjozNDU2MDAsImlzcyI6ImxvY2FsaG9zdDo1NTAwIn0.tqfp5Co4vLtq3_J0r5Fp-XwuDSB1i6uC4AcogQ3vnc8"
+}
+```
+
+If you want to customize what items are hidden from the user data, you can configure Leaf Auth to hide them:
+
+```php:no-line-numbers
+auth()->config('hidden', ['password', 'id', 'email', ...]);
+```
+
+## Controlling session lifetime
+
+Whether you are using token or session based auth, you might want to control how long a user's session or token lasts. You can set the lifetime of a user's session or token config like this:
+
+::: code-group
+
+```php [Token Lifetime]
+auth()->config('token.lifetime', '1 hour'); // 1 hour'
+auth()->config('token.lifetime', 60 * 60 * 24 * 7); // 1 week
+auth()->config('token.lifetime', 0); // never expire
+```
+
+```php [Session Lifetime]
+auth()->config('session.lifetime', '1 hour'); // 1 hour
+auth()->config('session.lifetime', 60 * 60 * 24 * 7); // 1 week
+auth()->config('session.lifetime', 0); // never expire
+```
+
+:::
diff --git a/src/docs/auth/mvc.md b/src/docs/auth/mvc.md
new file mode 100644
index 00000000..fe5379d6
--- /dev/null
+++ b/src/docs/auth/mvc.md
@@ -0,0 +1 @@
+# MVC Support
diff --git a/src/docs/auth/protected-routes.md b/src/docs/auth/protected-routes.md
new file mode 100644
index 00000000..8eb48f55
--- /dev/null
+++ b/src/docs/auth/protected-routes.md
@@ -0,0 +1,135 @@
+# Protected Routes
+
+
+
+There are usually parts of your application that you want to be available to only logged in users or guest users. That's where protected routes come in. Protected routes are setup to allow users with a certain authentication status to access them.
+
+## The `user` method
+
+The `user()` method is a way to check if a user is logged in. It returns the currently logged in user if an authenticated user is found and `null` if a user is not logged in.
+
+This works for both session and token based authentication. In case of token based authentication, Leaf Auth will also check if the token is valid. If it is, the user is returned, if not, `null` is returned. You can get the reason for the authentication failure by calling the `errors()` method.
+
+```php{1,7}
+$user = auth()->user();
+
+if ($user) {
+ // user is logged in
+} else {
+ // user is not logged in
+ $errors = auth()->errors();
+}
+```
+
+Using this method, you can easily protect your routes by checking if a user is logged in. If a user is not logged in, you can redirect them to the login page or return a 401 error. Here's an example:
+
+```php
+app()->get('/protected', function () {
+ $user = auth()->user();
+
+ if ($user) {
+ // user is logged in
+ } else {
+ // user is not logged in
+ response()->redirect('/login');
+ }
+});
+```
+
+For API routes, you can return a 401 error if a user is not logged in.
+
+```php
+app()->get('/protected', function () {
+ $user = auth()->user();
+
+ if ($user) {
+ // user is logged in
+ } else {
+ // user is not logged in
+ response()->json([
+ 'error' => 'Unauthorized',
+ 'data' => auth()->errors(),
+ ], 401);
+ }
+});
+```
+
+## The `id` method
+
+The id() method lets you get the ID of the user who is currently logged in. This is helpful when you need to work with the user's ID in your app. If no user is logged in, the method returns `null` instead.
+
+```php
+app()->get('/protected', function () {
+ $id = auth()->id();
+
+ if ($id) {
+ // user is logged in
+ } else {
+ // user is not logged in
+ response()->redirect('/login');
+ }
+});
+```
+
+## Using Middleware
+
+Leaf Auth also provides a middleware that you can use to protect your routes. The `auth` middleware checks if a user is logged in and allows you to set a callback function to run if a user is not logged in.
+
+```php
+auth()->middleware('auth.required', function () {
+ response()->redirect('/login');
+});
+```
+
+Once you have defined a callback for the middleware, you can use it in your routes like this:
+
+```php
+app()->get('/protected', ['middleware' => 'auth.required', function () {
+ // this route is protected
+}]);
+
+// or on a route group
+app()->group('/protected', ['middleware' => 'auth.required', function () {
+ app()->get('/route', function () {
+ // this route is protected
+ });
+}]);
+```
+
+If you use this method, the middleware will run before the route is executed. If the user is not logged in, the callback function you defined will be executed. This means you can remove the check for a logged in user from your route handler.
+
+```php
+app()->get('/protected', ['auth.required', function () {
+ $user = auth()->user();
+
+ // no need to check if user is logged in
+}]);
+```
+
+## Protected Guest Routes
+
+You can also protect routes that should only be accessible to guest users. This is useful for routes like the login and register routes. You can use the `auth.guest` middleware to protect these routes.
+
+```php
+auth()->middleware('auth.guest', function () {
+ response()->redirect('/dashboard');
+});
+```
+
+You can then use this middleware on your guest routes like this:
+
+```php
+app()->get('/login', ['middleware' => 'auth.guest', function () {
+ // this route is only accessible to guest users
+}]);
+```
+
+This middleware will run before the route is executed. If a user is logged in, the callback function you defined will be executed. This means you can remove the check for a guest user from your route handler.
+
+## Session Guards
+
+The previous version of Leaf Auth had a feature called session guards. This feature has been deprecated in the latest version of Leaf Auth. If you were using session guards in your app, you can switch to the new middleware system to protect your routes.
+
+The middleware system is more flexible and allows you to define more complex authentication logic using the middleware callback functions.
+
+You can also use the middleware system to protect routes for both logged in and guest users, which is essentially what session guards were used for.
diff --git a/src/docs/auth/session.md b/src/docs/auth/session.md
new file mode 100644
index 00000000..43bb3a1d
--- /dev/null
+++ b/src/docs/auth/session.md
@@ -0,0 +1 @@
+# Auth Session
diff --git a/src/docs/auth/signup.md b/src/docs/auth/signup.md
new file mode 100644
index 00000000..eaa34013
--- /dev/null
+++ b/src/docs/auth/signup.md
@@ -0,0 +1,218 @@
+# User Sign Up
+
+
+
+
+
+Leaf Auth provides a flexible and secure login system that works for both token based and session based authentication. It provides a unified way to authenticate users in your web apps and APIs.
+
+::: details Token vs Session Authentication
+
+- Token based authentication is a system where a user is given a token upon login which is then used to authenticate the user on every request. It is the most common authentication system for APIs. This video by Hamy Labs explains how token authentication works
+
+
+
+
+
+
+- Session-based authentication is a method where, after a user logs in, the server creates a session to remember them. Every time the user makes a request, their session ID is sent back to the server to verify their identity, allowing them to stay logged in while using the app.
+
+
+
+:::
+
+## Database Pre-requisites
+
+Leaf Auth doesn't force you to use any specific structure for your database, so you’re free to organize it however you like. But, there are a few important things to keep in mind to make sure everything works smoothly.
+
+### Specifying the table to use
+
+Leaf assumes that you will save your users in a table named `users`. If you want to use a different table, you can configure Leaf Auth using `db.table`:
+
+```php:no-line-numbers
+auth()->config('db.table', 'admins');
+```
+
+### Specifying the primary key
+
+Most databases use `id` as the primary key. If you are using a different field as the primary key, you can configure Leaf Auth using `id.key`:
+
+```php:no-line-numbers
+auth()->config('id.key', 'admin_id');
+```
+
+If you are using UUIDs as your primary key, you just need to pass in your primary key instead of leaving it up to Leaf to generate it:
+
+```php{2}
+auth()->register([
+ 'id' => 'your-uuid',
+ ...
+]);
+```
+
+Once Leaf detects a field with the same name as your primary key, it will use that field as the primary key.
+
+## Signing a user up
+
+To sign a user up is to create a new user account on your application. This is usually done by collecting the user's details and storing them in your database. You also need to validate the user's details to ensure they are correct and that they don't conflict with existing data.
+
+Leaf allows you to do all this using the `register()` method. This method takes in an array of data you want to use to create the user.
+
+```php
+auth()->register([
+ 'username' => 'example',
+ 'email' => 'm@example.com',
+ 'password' => 'password'
+]);
+```
+
+If the user is successfully saved in the database, a session or token is created for them and the user is returned. If Leaf Auth fails to save the user, the method returns `false`. You can then use the `errors()` method to get the error message.
+
+```php
+$success = auth()->register([
+ 'username' => 'example',
+ 'email' => 'user@example.com',
+ 'password' => 'password'
+]);
+
+if ($success) {
+ // User is authenticated
+ $token = auth()->data();
+ // ['user' => [...], 'accessToken' => '...', 'refreshToken' => '...']
+
+
+ $username = auth()->user()->username;
+} else {
+ // User is not authenticated
+ $error = auth()->errors();
+}
+```
+
+## Unique fields
+
+There are some fields in your database that should not be repeated for different users. For example, you wouldn't want two users to have the same email address. You can configure Leaf Auth to check for unique fields when a user is being registered:
+
+```php:no-line-numbers
+auth()->config('unique', ['email', 'username']);
+```
+
+Now if a user tries to register with an email or username that already exists in the database, Leaf Auth will return an error. You can get the error message using the `errors()` method.
+
+```php
+$data = auth()->register([
+ 'username' => 'example',
+ 'email' => 'example@example.com',
+ 'password' => 'password'
+]);
+
+if (!$data) {
+ $error = auth()->errors();
+ // ['email' => 'The email already exists']
+}
+```
+
+## Using timestamps
+
+Leaf will always try to set the `created_at` and `updated_at` fields in your database. If you want to turn this off, you can set `timestamps` to `false`:
+
+```php:no-line-numbers
+auth()->config('timestamps', false);
+```
+
+One thing to watch out for is the format of the timestamp. Different databases have different accepted timestamp formats. If you get an error concerning the format of the timestamp, you can configure Leaf Auth to use a different format:
+
+```php:no-line-numbers
+auth()->config('timestamps.format', 'YYYY-MM-DD HH:MM:SS');
+```
+
+You can find the date format documentation [here](/docs/utils/date#formatting-dates).
+
+## Password hashing
+
+Leaf allows you to customize how user passwords should be encoded before they are stored in your database. By default, Leaf uses the `Leaf\Helpers\Password::hash` method which has support for `bcrypt` and `argon2`. If you however want to use a different method or turn off password encoding, you can do that directly in the config:
+
+```php
+auth()->config('password.encode', false); // turn off encoding
+
+auth()->config('password.encode', function ($password) {
+ // return the encoded password
+ return Password::hash($password);
+});
+```
+
+These are the available options you can pass to `password.encode`:
+
+- `false` - This turns off password encoding
+- `null`/`true` - This uses the default encoding method (Leaf\Helpers\Password::hash)
+- `function` - This uses a custom method. The method should accept a password and return the encoded password.
+
+## Hiding sensitive information
+
+The output of Leaf's authentication methods is an object with the user's data and the token or session. By default, the password field is hidden from the user data. This is a security measure to prevent the password from being exposed.
+
+```php
+[
+ 'user' => [
+ 'username' => 'mychidarko',
+ 'email' => 'user@example.com',
+ 'created_at' => '2019-09-20 13:47:48'
+ ],
+ 'token' => 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpYXQiOjE1NzYxMzUzMjgsImlzcyI6ImxvY2FsaG9zdCIsImV4cCI6MTU3NjEzNjIyOCwidXNlcklkIjoxfQ.7FODXGGJKioGQVX4ic0DJLoMIQTVUlsd4zFAJA4DAkg'
+]
+```
+
+If you want to customize what items are hidden from the user data, you can configure Leaf Auth to hide them:
+
+```php:no-line-numbers
+auth()->config('hidden', ['password', 'id', 'email', ...]);
+```
+
+## Switching to session auth
+
+Leaf uses token based authentication by default which uses a JWT to authenticate your users. Sessions are a more common way to authenticate users in fullstack applications. To switch to session based authentication, you can update your auth config:
+
+```php:no-line-numbers
+auth()->config('session', true);
+```
+
+Switching to session auth does not change the default behaviour of the `register()` method. It does everything the same way it would if you were using token based authentication except that it creates a new session when a user is registered.
+
+```php:no-line-numbers
+auth()->config('session', true);
+
+...
+
+// will create a session
+$success = auth()->register([
+ 'username' => 'example',
+ 'email' => 'example@example.com',
+ 'password' => 'password'
+]);
+
+if ($success) {
+ response()->redirect('/dashboard');
+} else {
+ $error = auth()->errors();
+ // ['email' => 'The email already exists']
+}
+```
+
+You can also control things like the cookie settings and more:
+
+```php
+auth()->config('session.cookie', [
+ 'secure' => true,
+ 'httponly' => true,
+ 'samesite' => 'lax'
+]);
+```
diff --git a/src/docs/auth/user.md b/src/docs/auth/user.md
new file mode 100644
index 00000000..1f0e8a61
--- /dev/null
+++ b/src/docs/auth/user.md
@@ -0,0 +1,142 @@
+# User Operations
+
+After successfully logging in or registering a user, Leaf Auth provides a bunch of functionality that you can use to manage your users. These range from updating user details to other CRUD operations.
+
+## Getting user information
+
+You can usually get the current user's information using the `data()` method, however, the output is an array of the user's data together with the tokens which is not very convenient for use within your application.
+
+```php
+$data = auth()->data();
+// ['user' => [...], 'accessToken' => '...', 'refreshToken' => '...']
+```
+
+The `user()` method allows you to pick out exactly the information you need from the user's data. If you need all the user's data, you can use the `get()` method:
+
+```php
+$user = auth()->user()->get();
+
+// or pick specific fields
+$email = auth()->user()->email;
+$username = auth()->user()->username;
+```
+
+Picking specific fields also gives you access to fields you may have hidden using the auth config. This is useful because it allows you to perform operations on the user's data without mistakenly exposing hidden fields.
+
+```php
+auth()->config('hidden', ['secret_field']);
+
+$secretField = auth()->user()->secret_field;
+```
+
+While this may seem like a lot of work, it's a good way to ensure that your user's data is secure and only accessible where needed.
+
+## User relationships
+
+Relationships are a way to connect different models in your application. For instance, a user may have many posts, or a user may have many transactions. Using relationships, you can fetch related data from your database. If you have a user model with a one-to-many relationship with a posts model, you can fetch the user's posts using the user object:
+
+```php
+$posts = auth()->user()->posts();
+// will return a Leaf DB instance with posts by the current user
+// SELECT * FROM posts WHERE user_id = $current_user_id
+```
+
+You can further filter the data by using any of the Leaf DB methods:
+
+```php:no-line-numbers
+$posts = auth()->user()->posts()->where('title', 'like', '%leaf%')->get();
+```
+
+You can do this by calling whatever table your user is related to as a method on the user object. For instance, if you want to grab all user transactions from the `transactions` table, you can call the `transactions()` method on the user object. If you want to grab all books your user has read from the `read_books` table, you can call the `readBooks()` method on the user object.
+
+It will return a Leaf DB instance with the related data. You can further filter the data by using any of the Leaf DB methods:
+
+```php:no-line-numbers
+$posts = auth()
+ ->user()
+ ->transactions()
+ ->where('amount', '>', 1000)
+ ->get();
+
+$books = auth()
+ ->user()
+ ->readBooks()
+ ->where('title', 'Building with Leaf')
+ ->first();
+```
+
+## Updating a logged-in user
+
+Updating user information means allowing users to change their details (like username, email, or password) in your application. It is a very common feature in most applications.
+
+Leaf provides an `update()` method that allows you to update a user's information. It returns `true` if the user is successfully updated and `false` if the user is not updated. You can get the error message using the `errors()` method.
+
+```php
+$success = auth()->update($data);
+
+if ($success) {
+ // User is updated
+} else {
+ // User is not updated
+ $error = auth()->errors();
+}
+```
+
+### Unique values
+
+Leaf Auth allows you to set unique fields which should not be repeated for different users. For example, you wouldn't want two users to have the same email address. You can configure Leaf Auth to check for unique fields when a user is being updated:
+
+```php:no-line-numbers
+auth()->config('unique', ['email', 'username']);
+```
+
+Now if a user tries to update their profile with an email or username that already exists in the database, Leaf Auth will return an error. You can get the error message using the `errors()` method.
+
+```php
+$success = auth()->update([
+ 'username' => 'example',
+ 'email' => 'example@example.com'
+]);
+
+if (!$success) {
+ $error = auth()->errors();
+ // ['email' => 'email already exists']
+}
+```
+
+## Password reset
+
+Leaf Auth doesn't have a full built-in password reset flow which involves sending an email to the user with a link to reset their password. This may be added in the future, but for now, Leaf Auth comes with a simple `updatePassword()` method that allows you to change a user's password. It takes care of verifying the old password and hashing the new password.
+
+```php
+$success = auth()->updatePassword($oldPassword, $newPassword);
+
+if ($success) {
+ // Password is updated
+} else {
+ // Password is not updated
+ $error = auth()->errors();
+}
+```
+
+## Signing a user out
+
+When a user chooses to end their session, or their session expires, you can sign them out using the `logout()` method. This method will end the user's session or delete their token.
+
+```php
+auth()->logout();
+
+// or redirect the user after logout
+auth()->logout('/login');
+
+// or redirect to a named route
+auth()->logout(['homepage']);
+```
+
+If you want to perform a custom operation when a user logs out, you can pass a function to the `logout()` method:
+
+```php
+auth()->logout(function () {
+ // your logout handler
+});
+```
diff --git a/src/docs/cli/creating-an-app.md b/src/docs/cli/creating-an-app.md
new file mode 100644
index 00000000..093d3bdc
--- /dev/null
+++ b/src/docs/cli/creating-an-app.md
@@ -0,0 +1,122 @@
+# Creating a new app with the CLI
+
+
+
+
+
+The Leaf CLI is a powerful tool and offers multiple ways to create a new Leaf app. These are all tailored towards different preferences and use cases. You can create a new Leaf app using:
+
+- [The basic installation method](#basic-installation)
+- [Custom installation method](#customizing-your-app)
+- [The GUI installation method](#gui-installation)
+
+
+
+## Basic Installation
+
+Once you have the Leaf CLI installed, you can create a new Leaf app by running the following command:
+
+```bash:no-line-numbers
+leaf create my-app
+```
+
+This will open up a prompt asking you to choose a template for your app. You can choose between a basic Leaf app, a full Leaf MVC application, or a Leaf MVC application which has been fine-tuned for creating APIs.
+
+```bash
+? What kind of app do you want to create? [leaf]
+ [0] leaf
+ [1] leaf mvc
+ [2] leaf mvc for apis
+ >
+```
+
+After you've made your choice, the CLI will create a new directory with the name you provided and set up a new Leaf app for you. All you have to do is navigate into the new directory and run the app.
+
+```bash:no-line-numbers
+cd my-app
+leaf serve
+```
+
+## Customizing your app
+
+Leaf is modular and flexible, so you can customize your app to fit your needs. Leaf CLI allows you to do this on installation by allowing you to select only the features you need. This way, you can keep your app lightweight and only include the features you need.
+
+To set up a new Leaf app with only the features you need, you can run the following command:
+
+```bash:no-line-numbers
+leaf create my-app --custom
+```
+
+This will open up a prompt asking you to choose the features you want to include in your app. You can choose between the following features:
+
+```bash:no-line-numbers
+? What modules would you like to add? [none] eg: 1,2,7
+ [0] None
+ [1] Database
+ [2] Authentication
+ [3] Session support
+ [4] Cookie support
+ [5] CSRF protection
+ [6] CORS support
+ [7] Leaf Date
+ [8] Leaf Fetch
+ >
+```
+
+For Leaf MVC, you can also select things like the View engine you prefer to use:
+
+```bash
+? What view engine would you like to use? [Blade]
+ [0] Blade
+ [1] Bare UI
+ [2] React/Vue
+ >
+```
+
+Whether to add a bundler for your frontend assets:
+
+```bash
+? Do you want to add Vite to bundle your assets? [Yes]
+```
+
+And whether to add a testing framework:
+
+```bash
+? What testing framework would you like to use? [none]
+ [0] none
+ [1] pest
+ [2] phpunit
+ >
+```
+
+Once you have selected the features you want, the CLI will set up a new Leaf app with only the features you selected. You can then navigate into the new directory and run the app.
+
+```bash:no-line-numbers
+cd my-app
+leaf serve
+```
+
+## GUI Installation
+
+Not everyone is comfortable with the command line, and that's okay. If you prefer a graphical user interface, you can use the Leaf GUI to create a new Leaf app. The Leaf GUI opens up a browser window where you can select the features you want and create a new Leaf app with just a few clicks.
+
+To use the Leaf GUI, you can run the following command:
+
+```bash:no-line-numbers
+leaf ui
+```
+
+
+
+It allows you to select the features you want to include in your app and creates a new Leaf app with only the features you selected. You can then navigate into the new directory and run the app.
+
+```bash:no-line-numbers
+cd my-app
+leaf serve
+```
diff --git a/src/docs/cli/index.md b/src/docs/cli/index.md
index eaa0da7e..b995534b 100644
--- a/src/docs/cli/index.md
+++ b/src/docs/cli/index.md
@@ -3,7 +3,7 @@
@@ -11,422 +11,64 @@ import VideoDocs from '/@theme/components/VideoDocs.vue'
-Leaf CLI is a simple command line tool for creating and interacting with your Leaf applications. It gives you the options to create projects, install dependencies, run scripts, scaffold items and much more.
+Leaf CLI is a command line tool that helps you create, manage and deploy Leaf applications. It's a powerful tool that helps you get started with Leaf quickly and easily. You can do things like creating apps, running your projects, installing dependencies, and more.
## Installation
-
-You can install the leaf cli using composer. Composer is a dependency manager for PHP. You can follow the instructions on [getcomposer.org](https://getcomposer.org) to install composer on your system. From there, you should have access to the `composer` command from anywhere on your system.
+*This guide will assume that your system meets all the [technical requirements](/docs/installation#technical-requirements).*
-```bash
+You can verify that composer is installed by running:
+
+```bash:no-line-numbers
composer --version
```
-You should then be able to get the Leaf CLI up and and running on your system using composer:
+To install the Leaf CLI, you can run the following command:
-```bash
+```bash:no-line-numbers
composer global require leafs/cli
```
-After that, you should have access to the `leaf` command from anywhere on your system.
+This tells Composer to install the Leaf CLI globally on your system. You can verify that the CLI is installed correctly by running:
-```bash
+```bash:no-line-numbers
leaf --version
```
-## command not found: leaf
-
-If you get a `command not found: leaf` error, it means your composer bin is not in your system path.
-
-You need to make sure that Composer's system-wide vendor bin directory is in your system `$PATH` so the leaf executable can be located by your system. This directory exists in different locations based on your operating system; however, some common locations include:
-
-- Windows: `%USERPROFILE%\AppData\Roaming\Composer\vendor\bin`
-- macOS: `$HOME/.composer/vendor/bin`
-- GNU / Linux Distributions: `$HOME/.config/composer/vendor/bin` or `$HOME/.composer/vendor/bin`
-
-You could also find the composer's global installation path by running `composer global about` and looking up from the first line.
-
-## Adding composer bin to path
-
-Once you find your composer global installation path, you can add it to your path. **There are some examples below which you can copy and paste in your terminal.**
+## [Error] command not found: leaf
-Eg (Adding composer bin to path linux):
+If you get an error saying `leaf: command not found`, you need to add Composer's global bin directory to your system's PATH. This directory contains every package installed through `composer global require`. Let's fix this by adding the directory to your PATH.
-```bash
-export PATH=$PATH:$HOME/.config/composer/vendor/bin
-```
-
-Eg (Adding composer bin to path mac):
+Depending on your operating system, the composer bin directory will be located in different places. You can find the location by running:
-```bash
-export PATH=$PATH:$HOME/.composer/vendor/bin
-echo $PATH
+```bash:no-line-numbers
+composer global config bin-dir --absolute
```
-::: tip NOTE
-To get leaf cli installed permanently, you will need to add your composer bin your `.bashrc` or `.zshrc` file on mac and linux.
+If this command does not work, you can try these common locations:
-**zsh:**
+- Windows: `%USERPROFILE%\AppData\Roaming\Composer\vendor\bin`
+- macOS: `$HOME/.composer/vendor/bin`
+- GNU / Linux Distributions: `$HOME/.config/composer/vendor/bin` or `$HOME/.composer/vendor/bin`
-```bash
-echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.zshrc
-source ~/.zshrc
-```
+## Adding to PATH
-**bash:**
+Once you have the location, you can add it to your PATH. On Mac and Linux, you can do this by running these in your terminal:
-```bash
+```bash:no-line-numbers
echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.bashrc
source ~/.bashrc
```
-:::
-
-## Creating a leaf app
-
-
-
-To start a new project, open up your terminal and move into a directory you want to generate your projects in. From there, you can use the `leaf create` command to set up a new Leaf app in that directory:
-
-```bash
-leaf create
-```
-
-This will prompt you to select a preset. Presets are quick ways to get your project up and running as quickly as possible. You can select a preset from the list of presets displayed to you:
-
-```bash
-? What kind of app do you want to create? [leaf]
- [0] leaf
- [1] leaf mvc
- [2] leaf api
- >
-```
-
-*You can select a number or type in the preset you prefer.*
-
-A leaf app will be generated based on the associated preset. As you can see, there are 3 presets:
-
-- **Leaf**: a bare Leaf project
-- **Leaf MVC**: a Leaf project with leaf mvc
-- **Leaf API**: a Leaf project with leaf api
-
-The Leaf CLI will automatically install the dependencies for the preset you selected and set up your project using Leaf 3. From there, you can `cd` into your project and start building.
-
-```bash
-cd
-leaf serve
-```
-
-### Custom installation New
-
-The Leaf CLI also comes with a custom installation option. This allows you to customize your project to your liking. You can select the features you want to add to your project and the Leaf CLI will set it up for you.
-
-```bash
-leaf create --custom
-```
-
-This will prompt you to select the features you want to add to your project. You can select the features you want to add to your project from the list of features displayed to you:
-
-```bash
-? What modules would you like to add? [none] eg: 1,2,7
- [0] None
- [1] Database
- [2] Authentication
- [3] Session support
- [4] Cookie support
- [5] CSRF protection
- [6] CORS support
- [7] Leaf Date
- [8] Leaf Fetch
- >
-```
-
-For Leaf MVC, you can also select things like the View engine you prefer to use:
-
-```bash
-? What view engine would you like to use? [Blade]
- [0] Blade
- [1] Bare UI
- [2] React/Vue
- >
-```
-
-Whether to add a bundler for your frontend assets:
-
-```bash
-? Do you want to add Vite to bundle your assets? [Yes]
-```
-
-And whether to add a testing framework:
-
-```bash
-? What testing framework would you like to use? [none]
- [0] none
- [1] pest
- [2] phpunit
- >
-```
-
-### GUI New
-
-These new options are quite a lot to take in, so we've also added a GUI to help you select the features you want to add to your project. The GUI allows you to select different structures and features you want to add to your project. The GUI can also install and setup frontend systems like React, Vue, Tailwind and more.
-
-You can get started with the following command:
-
-```bash
-leaf ui
-```
-
-
-
-### Quick presets
-
-Leaf CLI also provides a quicker way to initialize your project without having to go through the interactive installer. You can use the `--mvc`, `--api`, and `--basic` options to generate your project based on a specific presets. These generate the following:
-
-- `--basic`: a bare Leaf project
-- `--mvc`: a Leaf project with leaf mvc
-- `--api`: a Leaf project with leaf api
-
-```bash
-leaf create --mvc
-```
-
-### Adding Tests
-
-The Leaf CLI by default will generate your project without any testing framework. However, you will be prompted to add a testing framework if you select the `--custom` option.
-
-```bash
-leaf create --custom
-```
-
-You can still add a testing framework without using the `--custom` option by using either the `--pest` for Pest PHP tests:
-
-```bash
-leaf create --pest
-```
-
-Or the `--phpunit` option for PHPUnit tests:
-
-```bash
-leaf create --phpunit
-```
-
-### Using docker
-
-Leaf CLI also provides a way to generate your project with docker. You can use the `--docker` option to add all the necessary files to your project to run it with docker.
-
-```bash
-leaf create --docker
-```
-
-If you are using the `--custom` option, you will be asked if you want to add docker to your project. For the full docker guide, you can check out the [docker guide](/docs/introduction/docker).
-
-## Running your leaf apps
-
-After generating your leaf app, you can `cd` into the directory and spin up a local dev server using leaf cli's `serve` command.
-
-```bash
-cd backend-api
-leaf serve
-```
-
-You can also specify the port to run your leaf app on using the `--port` or `-p` options.
-
-```bash
-leaf serve -p 3000
-```
-
-### File watching
-
-In v2.1, you can also start the leaf server with hot module watching. This reloads your application anytime a change is made to your application code. To get started, simply start the leaf server with the `--watch` flag.
-
-```bash
-leaf serve --port 8000 --watch
-```
-
-### Dependency Management
-
-The serve command will also try to install dependencies for your project if it doesn't detect a `vendor` folder present in the current working directory.
-
-
-
-## Testing your Leaf apps
-
-Testing helps prevent bugs in your app which you may not catch until you publish your app to production. Leaf introduced a test runner which helps you initialize testing and run tests in your app without needing any config first. Alchemy has also been integrated into the Leaf CLI and so you can use it's functionality directly.
-
-### Setting up tests
-
-If you already have a project and want to setup tests, you can use the `test:setup`. It will automatically detect the testing framework you are using and setup tests for you. It also supports Pest PHP and PHPUnit, so you can use either of them using the `--phpunit` or `--pest` options.
-
-```bash
-# pest
-leaf test:setup --pest
-
-# phpunit
-leaf test:setup --phpunit
-```
-
-This will create a `tests` folder in your project and add example tests to it based on the testing framework you are using.
-
-### Running tests
-
-To run tests you've setup or created, you can use the `test` command.
-
-```bash
-leaf test
-```
-
-## Installing packages
-
-This cli tool also adds a feature to install leaf packages from composer.
-
-```bash
-leaf install leafs/ui
-```
-
-If you are installing a leaf module or package, you can leave out the `leafs/` part.
-
-```bash
-leaf install ui
-```
-
-You can also pass in a bunch of packages to install at once.
-
-```bash
-leaf install ui db illuminate/support
-```
-
-***Versioning***
-
-Leaf CLI also allows you to install a particular version of any package using `@`
-
-```bash
-leaf install ui@1.0 illuminate/support@9.0.2
-```
-
-## Interactive Shell
-
-You can also use the interactive shell to interact with your app.
+Or if you're using Zsh:
-```bash
-$ leaf interact
-...
->>> $user = new User;
-...
->>> $user->name = "Mychi";
-...
->>> $user->save();
-```
-
-## Updating leaf cli
-
-Leaf CLI keeps getting better with every release, and by default, it checks for updates every time you run a command. However, you can also manually update your leaf cli using the `update` command.
-
-```bash
-leaf update
-```
-
-If this doesn't work, or you want to hard reset the Leaf CLI to clear cache, you can re-install it via composer:
-
-```bash
-composer global remove leafs/cli
-composer global require leafs/cli
-```
-
-## View commands New
-
-Leaf CLI also allows you to create and interact with frontend setups using the `view` commands. You can scaffold frontend setups like React, Vue, templating engines, build tools, and more.
-
-### Scaffolding views
-
-Leaf CLI ships with a `view:install` command that allows you to setup React, Vue, and templating engines like Blade and BareUI. You can use the `--react`, `--vue`, `--blade`, and `--bareui` options to scaffold your frontend setup.
-
-```bash
-leaf view:install --react
-```
-
-You can also use the `--vite` and `--tailwind` options to scaffold Vite and Tailwind respectively.
-
-### Running frontend setups
-
-Since Leaf CLI is a backend tool, it doesn't come with a frontend server. However, you can use the `view:dev` command to run your frontend setup which may include in a dev server for your frontend.
-
-```bash
-leaf view:dev
-```
-
-### Building frontend setups
-
-You can also use the `view:build` command to build your frontend setup for production.
-
-```bash
-leaf view:build
-```
-
-## Running Scripts
-
-Leaf CLI also now allows you run scripts defined in your `composer.json` file. For example, if you have this in your composer.json:
-
-![image](https://user-images.githubusercontent.com/26604242/166419297-225b0b00-c979-4096-a23d-4f7858def8fb.png)
-
-You can run the test script like this:
-
-```bash
-leaf run test
-```
-
-## Usage Guide
-
-```bash
- _ __ ___ _ ___
-| | ___ __ _ / _| / __| | |_ v2.8.3
-| |__/ -_) _` | _| | (__| |__ | |
-|____\___\__,_|_| \___|____|___|
-
-
-Usage:
- command [options] [arguments]
-
-Options:
- -h, --help Display help for the given command. When no command is given display help for the list command
- -q, --quiet Do not output any message
- -V, --version Display this application version
- --ansi|--no-ansi Force (or disable --no-ansi) ANSI output
- -n, --no-interaction Do not ask any interactive question
- -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
-
-Available commands:
- completion Dump the shell completion script
- create [init|new] Create a new Leaf PHP project
- deploy [publish] Deploy your leaf project
- help Display help for a command
- install Add a new package to your leaf app
- interact Interact with your application
- list List commands
- run Run a script in your composer.json
- serve Run your Leaf app
- test Test your leaf application through leaf alchemy
- uninstall Uninstall a package
- update Update leaf cli to the latest version
- test
- test:setup Add tests to your application
- view
- view:build Run your frontend dev server
- view:dev Run your frontend dev server
- view:install Run a script in your composer.json
+```bash:no-line-numbers
+echo 'export PATH="$PATH:$HOME/.composer/vendor/bin"' >> ~/.zshrc
+source ~/.zshrc
```
-
-This is the full list of commands available with Leaf CLI 2. A new update command has been added to allow you seamlessly update leaf CLI without having to run a bunch of commands. You don't even need to run this manually since leaf cli will automatically check for updates and upgrade to the latest stable release.
diff --git a/src/docs/cli/managing-apps.md b/src/docs/cli/managing-apps.md
new file mode 100644
index 00000000..6d920fc2
--- /dev/null
+++ b/src/docs/cli/managing-apps.md
@@ -0,0 +1,176 @@
+# Managing apps
+
+
+
+
+
+Besides creating apps, Leaf CLI also helps you manage your apps. This includes things like running your app, dependency management, running commands, and more. This guide covers all such features.
+
+## Running your app
+
+You can run your app by navigating into your app's directory and running the `leaf serve` command. This will start a development server and serve your app on `localhost:5500`.
+
+```bash:no-line-numbers
+cd my-app
+leaf serve
+```
+
+You can also specify a port to run your app on by passing the `--port` or `-p` flag:
+
+```bash:no-line-numbers
+leaf serve --port=8080
+```
+
+The serve command also has a `--watch` flag that watches your app for changes and automatically reloads your app when changes are detected:
+
+```bash:no-line-numbers
+leaf serve --watch
+```
+
+*Note: The `--watch` flag is only available when running your app in development mode and uses nodejs to watch your app for changes.*
+
+If you want to run your application from a different directory, you can pass the path to the directory as an argument:
+
+```bash:no-line-numbers
+leaf serve /path/to/your/app
+```
+
+::: info Automatic dependency installation
+When running your app, Leaf will automatically try to install missing dependencies if no `vendor` directory is found in your app's directory.
+:::
+
+## Running commands
+
+Leaf CLI also allows you to run commands in your app's directory. If you have a command in your `composer.json` file, you can run it using the `leaf run` command:
+
+```bash:no-line-numbers
+leaf run my-command
+```
+
+## Dependency management
+
+Leaf CLI also has commands built on top of Composer to help you manage your app's dependencies. Leaf has a whole ecosystem of packages that are treated as first-class citizens in the Leaf ecosystem, and are given special treatment by the CLI. This makes working with Leaf packages a breeze, but also allows you to work with any Composer package.
+
+::: details Are you a visual learner?
+
+This video will help you understand how to work with packages on the Leaf CLI.
+
+
+
+:::
+
+### Installing packages
+
+This cli tool also adds a feature to install leaf packages from composer.
+
+```bash:no-line-numbers
+leaf install leafs/ui
+```
+
+If you are installing a leaf module or package, you can leave out the `leafs/` part.
+
+```bash:no-line-numbers
+leaf install ui
+```
+
+You can also pass in a bunch of packages to install at once.
+
+```bash:no-line-numbers
+leaf install ui db illuminate/support
+```
+
+***Versioning***
+
+Leaf CLI also allows you to install a particular version of any package using `@`
+
+```bash:no-line-numbers
+leaf install ui@1.0 illuminate/support@9.0.2
+```
+
+### Uninstalling packages
+
+This works the same way as installing packages, but you use the `uninstall` command instead.
+
+```bash:no-line-numbers
+leaf uninstall ui
+leaf uninstall ui db illuminate/support
+```
+
+## View commands
+
+Leaf CLI also allows you to create and interact with frontend setups using the `view` commands. You can scaffold frontend setups like React, Vue, templating engines, build tools, and more.
+
+### Scaffolding views
+
+Leaf CLI ships with a `view:install` command that allows you to set up React, Vue, and templating engines like Blade and BareUI. You can use the `--react`, `--vue`, `--blade`, and `--bareui` options to scaffold your frontend setup.
+
+```bash:no-line-numbers
+leaf view:install --react
+```
+
+You can also use the `--vite` and `--tailwind` options to scaffold Vite and Tailwind respectively.
+
+### Running frontend setups
+
+Since Leaf CLI is a backend tool, it doesn't come with a frontend server. However, you can use the `view:dev` command to run your frontend setup which may include in a dev server for your frontend.
+
+```bash:no-line-numbers
+leaf view:dev
+```
+
+### Building frontend setups
+
+You can also use the `view:build` command to build your frontend setup for production.
+
+```bash:no-line-numbers
+leaf view:build
+```
+
+### API Reference
+
+This is the full list of commands you can use to manage your app's dependencies:
+
+```bash:no-line-numbers
+
+ _ __ ___ _ ___
+| | ___ __ _ / _| / __| | |_ v2.12.0
+| |__/ -_) _` | _| | (__| |__ | |
+|____\___\__,_|_| \___|____|___|
+
+
+Usage:
+ command [options] [arguments]
+
+Options:
+ -h, --help Display help for the given command. When no command is given display help for the list command
+ -q, --quiet Do not output any message
+ -V, --version Display this application version
+ --ansi|--no-ansi Force (or disable --no-ansi) ANSI output
+ -n, --no-interaction Do not ask any interactive question
+ -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug
+
+Available commands:
+ completion Dump the shell completion script
+ create [init|new] Create a new Leaf PHP project
+ deploy [publish] Deploy your leaf project
+ help Display help for a command
+ install Add a new package to your leaf app
+ interact Interact with your application
+ list List commands
+ run Run a script in your composer.json
+ serve Run your Leaf app
+ test Test your leaf application through leaf alchemy
+ ui [gui] Start the Leaf CLI GUI process
+ uninstall Uninstall a package
+ update Update leaf cli to the latest version
+ view
+ view:build Run your frontend dev server
+ view:dev [view:serve] Run your frontend dev server
+ view:install Run a script in your composer.json
+```
diff --git a/src/docs/config/container.md b/src/docs/config/container.md
new file mode 100644
index 00000000..897e3e31
--- /dev/null
+++ b/src/docs/config/container.md
@@ -0,0 +1,57 @@
+# Service Container
+
+A Dependency Injection (DI) Container is like a helper that organizes how different parts of your app work together. Instead of manually creating objects and initializing classes when one part of your app needs another, the container automatically retrieves them for you.
+
+Leaf comes with a lightweight service container that simplifies managing dependencies in your app. You can register classes and dependencies with the container and they will be available from anywhere in your app. While it is not a full-fledged dependency injection container, it is powerful enough to handle most of your application's needs.
+
+## Registering Dependencies
+
+Registering a dependency means adding the dependency to the container so you can call it from anywhere in your app on the Leaf instance. We can do this using the `register()` method. It takes in two parameters:
+
+- The name of the dependency
+- A function that returns the dependency
+
+```php
+app()->register('something', function ($c) {
+ return new Something();
+});
+```
+
+In the example above, we set the `something` property on our app using Leaf's `register()` method. The `something` property will return an instance of the `Something` class.
+
+## Using Dependencies
+
+Once we have registered a dependency in Leaf's container, we can access it directly on the Leaf instance. We can do this by calling the dependency name as a property on the Leaf instance.
+
+```php
+$something = app()->something;
+$something->doSomething();
+
+// or
+
+app()->something->doSomething();
+```
+
+In the example above, we access the `something` dependency by calling it as a property on the Leaf instance. We then call the `doSomething()` method on the `something` dependency.
+
+If the dependency is a class, you can call its methods directly. If it is a function, you can call it directly.
+
+```php
+app()->register('something', function ($c) {
+ return function () {
+ return 'Hello World!';
+ };
+});
+
+$something = app()->something();
+```
+
+## Checking if a Dependency Exists
+
+You can check if a dependency exists in the container by calling the `has()` method. It takes in the name of the dependency and returns a boolean.
+
+```php
+if (app()->has('something')) {
+ echo 'Dependency exists';
+}
+```
diff --git a/src/docs/config/debugging.md b/src/docs/config/debugging.md
new file mode 100644
index 00000000..08ce6193
--- /dev/null
+++ b/src/docs/config/debugging.md
@@ -0,0 +1,145 @@
+# Debugging
+
+
+
+Debugging is the process of finding and fixing errors (bugs) in your code. When your program isn't working as expected, you "debug" by identifying where things go wrong and correcting them. It often involves reading error messages, using print statements or tools (like a debugger) to check the values of variables, and running the code step by step.
+
+## Debugging in Leaf
+
+While Leaf doesn't ship with a full-fledged debugger out of the box, it still provides tools that point you in the right direction. Your Leaf apps run in a development environment by default, which means you can see detailed error messages and stack traces in your browser when something goes wrong. This stack trace is Leaf's customized error page that shows you where the error occurred in your code.
+
+
+
+It provides other information like the kind of information entering your app, your environment variables and other server information. This is useful for finding out what went wrong and where.
+
+## Leaf DevTools
+
+Leaf provides DevTools to give you more insight into your app than you can get from the error page. It has a beautiful and intuitive interface that give you information about your Leaf application, and a light-weight library that you can use to interact with the devtools frontend.
+
+
+
+To get started with the DevTools, you need to install the Leaf DevTools module:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install devtools
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/devtools
+```
+
+:::
+
+After installing the devtools module, you need to add the hook to your app. This will register the devtools routes and allow your Leaf app to communicate with the DevTools. You can do this by adding this line to your app root.
+
+```php{5}
+/leafDevTools`. The DevTools will show you information about your app, like the routes, the request and response, and the environment variables. You can also use the DevTools to interact with your app, like making requests to your app and seeing the response.
+
+### Server Debug Logs
+
+When working with JavaScript, you can use `console.log` to log information to the console. In PHP, you can use `echo` or `var_dump` to log information to the browser. However, this can be a bit cumbersome, especially when you're working with APIs or other server-side code. Leaf provides a `log` function that you can use to log information to the server. This is useful for debugging your app in a non-invaisive way.
+
+```php
+\Leaf\DevTools::console('This data should be logged in the console');
+```
+
+Adding this line to your code will log the data to the Leaf DevTools console without affecting the output of your app. This allows you to debug your app while going through the normal flow of your app.
+
+```php
+\Leaf\DevTools::console('This data should be logged in the console');
+\Leaf\DevTools::console('This is a warning', 'warn');
+\Leaf\DevTools::console('This is an error', 'error');
+\Leaf\DevTools::console('This is an info message', 'info');
+\Leaf\DevTools::console('This is a debug message', 'log');
+```
+
+These will output different colored messages in the console:
+
+
+
+***Leaf will only allow access to the DevTools when the app is in a development environment, but not every hosting provider sets the environment to `production` automatically. To be safe, we recommend uninstalling the DevTools module before deploying your app.***
+
+## Disabling Debugging
+
+All Leaf applications run in a development environment by default. This means you can see detailed error messages and stack traces and are even able use devtools with much leaner security. However, when you're ready to deploy your app to production, you should disable debugging to prevent sensitive information from leaking. You can do this by setting the `debug` configuration option to `false`:
+
+```php
+app()->config([
+ 'debug' => false
+]);
+```
+
+We know that it's really easy to forget to disable debugging when deploying your app, so Leaf will automatically disable debugging when you set the `APP_ENV` environment variable to `production`. This is usually done automatically by your hosting provider, but if you're deploying your app manually on a VPS or Cloud, you can set the `APP_ENV` environment variable in your `.env` file.
+
+We understand that you might want to enable debugging in production for some reason, however, Leaf will not allow you to debug in production. Debugging in production can expose sensitive information about your app, which can be used by attackers to exploit your app. If you truly need to debug in production, you should turn to logging instead. Logging works in both development and production environments and is a safer way to debug your app.
+
+## Logging
+
+Logs are records of events in your application. They capture significant things like errors, requests, or user actions, helping you track your app's behavior. Log files are essential for debugging and understanding production issues. A typical log file looks like this:
+
+```log{4-5}
+[2021-03-31 22:44:53]
+ERROR - ErrorException: Trying to access array offset on value of type int in /home/mychi/Projects/leafphp/leaf/src/Experimental/Cache.php:83
+Stack trace:
+#0 /home/mychi/Projects/leafphp/leaf/src/Experimental/Cache.php(83): Leaf\Exception\General::handleErrors()
+#1 /home/mychi/Projects/leafphp/leaf/test/index.php(45): Leaf\Experimental\Cache::get()
+#2 [internal function]: {closure}()
+#3 /home/mychi/Projects/leafphp/leaf/src/Router.php(337): call_user_func_array()
+#4 /home/mychi/Projects/leafphp/leaf/src/Router.php(392): Leaf\Router::invoke()
+#5 /home/mychi/Projects/leafphp/leaf/src/Router.php(443): Leaf\Router::handle()
+#6 /home/mychi/Projects/leafphp/leaf/src/App.php(863): Leaf\Router::run()
+#7 /home/mychi/Projects/leafphp/leaf/test/index.php(52): Leaf\App->run()
+#8 {main}
+```
+
+Leaf offers a user-friendly logger for logging errors and other stuff in your app. It's integrated with Leaf's core, so no initialization is required, and you may not need to use the logger directly. To start logging, first install the Leaf logger module:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install logger
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/logger
+```
+
+:::
+
+Once you have installed the logger module, you need to tell Leaf to log all exceptions/errors. You can do this simply by enabling the `log.enabled` configuration option.
+
+```php
+app()->config([
+ 'log.enabled' => true
+]);
+```
+
+You also need to tell Leaf which directory to save logs into. By default, Leaf saves logs in the `logs` directory in your app's root directory. You can change this by setting the `log.dir` configuration option:
+
+```php
+app()->config([
+ 'log.enabled' => true,
+ 'log.dir' => __DIR__ . '/logs/'
+]);
+```
+
+All logs will be saved in a `log.txt` file in the directory you specify. You can also specify a custom log file name by setting the `log.file` configuration option:
+
+```php{4}
+app()->config([
+ 'log.enabled' => true,
+ 'log.dir' => __DIR__ . '/logs/',
+ 'log.file' => 'app.log'
+]);
+```
diff --git a/src/docs/config/deployment.md b/src/docs/config/deployment.md
new file mode 100644
index 00000000..d36c65e5
--- /dev/null
+++ b/src/docs/config/deployment.md
@@ -0,0 +1 @@
+# Deployment
diff --git a/src/docs/config/environment.md b/src/docs/config/environment.md
new file mode 100644
index 00000000..9bcdbdcb
--- /dev/null
+++ b/src/docs/config/environment.md
@@ -0,0 +1,71 @@
+# Application Environment
+
+
+
+
+
+You can think of your application's environment as a set of configurations that define how your application behaves in different situations. For example, you may run a local database when developing your app, but will want your app to connect to a remote database when it's in production.
+
+Common environments include `development`, `testing`, and `production`. Leaf already has some pre-programmed bahaviours for these environments, but you can also create your own custom environments. One way to do this is to use environment variables.
+
+## Environment Variables
+
+Environment variables are variables that are set in your application's current environment instead of being hardcoded in your code. This allows you to change your application's behaviour without changing your code which is pretty cool and useful for things like setting up different credentials for development and production.
+
+::: details New to Environment Variables?
+
+Adam Culp of Beachcasts php programming videos shares what environment variables are and how to use phpdotenv to retrieve them from $_ENV for usage in a PHP app.
+
+
+
+:::
+
+## Loading Environment Variables
+
+::: tip Leaf MVC
+
+If you use Leaf MVC, this step is already done for you, so you can go ahead and use `_env()` to access any environment variable you need.
+
+:::
+
+To use environment variables in your Leaf application, you need to load them from your `.env` file into PHP's `$_ENV` and `$_SERVER` globals. You can then access these variables using the `_env()` helper function that Leaf provides. Here are some popular environment loaders:
+
+- [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv)
+- [symfony/dotenv](https://github.com/symfony/dotenv)
+
+## Using Environment Variables
+
+Leaf comes with a pretty handy helper function `_env()` that you can use to access your environment variables. The `_env()` function takes in a key and a default value. If the key is found, the value is returned, otherwise the default value is returned.
+
+```php:no-line-numbers
+$secretKeyFromEnv = _env('SECRET_KEY', 'mySecretIfNotFound');
+```
+
+## Application Modes
+
+As mentioned earlier, Leaf has some pre-programmed behaviours for common environments like `development`, `testing`, and `production`. Leaf uses the `development` environment by default if no environment is set, but you can also set the environment your app should run in manually using the `mode` setting in your application settings.
+
+```php
+app()->config([
+ 'mode' => 'production'
+]);
+```
+
+You can also set the application mode using the `APP_ENV` environment variable. If Leaf detects that the `APP_ENV` environment variable is set, it will automatically set the application mode to the value of the `APP_ENV` variable.
+
+## Using Application Modes
+
+You can also tell Leaf to run a specific script when the application mode matches a given mode. This is done using the `script()` method. The `script()` method accepts two arguments: the mode and a callable.
+
+```php
+app()->script('production', function() {
+ // Run this script when the application mode is production
+});
+```
diff --git a/src/docs/config/index.md b/src/docs/config/index.md
old mode 100755
new mode 100644
index 396dd8d6..8615517e
--- a/src/docs/config/index.md
+++ b/src/docs/config/index.md
@@ -1,148 +1,34 @@
-# Overview
+# Configuration
-
+Unlike other popular frameworks, Leaf works out of the box without any external configuration (unless you are using Leaf MVC). While the default configuration is good enough for most use cases, you can still configure Leaf to better suit your needs.
-
+Since Leaf modules are designed to be plug-and-play, they have their own individual accepted configuration options which you can find in their respective documentation. This document covers the global configuration options that are available to you.
-Unlike other frameworks, Leaf requires no configuration out of the box. However, Leaf provides options for those who want to customize the framework to their needs.
+## Configuring Leaf
-## Applying Config
-
-There are 3 2 main ways to apply config to your Leaf application. Although they achieve the same result, each method has its own advantages and disadvantages. Let's take a look:
-
-
-
-- **Passing config during instantiation**
-
- To define settings upon instantiation, pass an associative array into the Leaf constructor. The array keys are the setting names and the array values are the setting values. This is the most performant way to define settings for Leaf, and we'll recommend this if you're using class mode.
-
- ```php
- $app = new Leaf\App([
- 'debug' => true
- ]);
- ```
-
-- **Using the `config()` method**
-
- This method is the most common way to apply config to your Leaf application. It's also the most flexible way to apply config. You can apply config at any point in your application, and you can apply multiple config at once. *Note that the config will only be applied to code that comes after the config method.*
-
- ```php
- $app = new Leaf\App;
- $app->config([
- 'debug' => true,
- 'views.path' => '../views'
- ]);
- ```
-
-
-
-
-- **Using the `config()` method**
-
- The `config()` method is the recommended way to apply config to your Leaf application. It allows you to set and get config values at any point in your application, and you can apply multiple config at once. *Note that the config will only be applied to code that comes after the config method.*
-
- ```php
- app()->config([
- 'debug' => true,
- 'views.path' => '../views'
- ]);
- ```
-
-
-
-- **Using the `Leaf\Config` class**
-
- The Config class is the central point for all of Leaf's config. It allows you to set and get config from anywhere in your app. However, it is best to set config before initializing Leaf.
-
- ```php
- Leaf\Config::set([
- 'views.path' => 'views',
- 'views.cachePath' => 'views/cache'
- ]);
-
- // your leaf app after this
- ```
-
-## Nested Config
-
-Leaf allows you to nest config into groups. This means that you can group config into arrays. This is especially useful when you're scoping features based on some configuration.
-
-For example, you can group all your server config into a `server` array:
-
-
-
-```php
-$app = new Leaf\App([
- 'server' => [
- 'host' => 'localhost',
- 'port' => 8080
- ]
-]);
-```
-
-
-
+To add any configuration to Leaf, you can pass an array of configuration options to the `config()` method. This method takes in an array of configuration options and merges them with the default configuration.
```php
app()->config([
- 'server' => [
- 'host' => 'localhost',
- 'port' => 8080
- ]
+ 'debug' => true,
+ 'views.path' => 'views',
]);
```
-
-
-You can then access the config using the `config()` method:
-
-
-
-```php
-$app->config('server.host'); // localhost
-```
+## Retrieving Configuration
-
-
+You can retrieve configuration values by passing a key to the `config()` method. This will return the value of the configuration key you pass to it.
```php
-app()->config('server.host'); // localhost
+$debug = app()->config('debug');
```
-
-
-You can also retrieve the entire config group by passing the group name:
+## Logging
-
-
-```php
-$app->config('server'); // ['host' => 'localhost', 'port' => 8080]
-```
+Leaf has a built-in logger that can be used to log errors and other messages. You can check the [debug page](/docs/config/debugging#logging) for more information on how to use Leaf's logger. This page will show you all the configs available for Leaf's logger.
-
-
+To get started, make sure you have the logger module installed. Once installed, you should have access to a `logger()` method on the Leaf instance. You can use this method to access Leaf's logger if you want to manually log messages.
```php
-app()->config('server'); // ['host' => 'localhost', 'port' => 8080]
+$app->logger()->info('Hello World!');
```
-
-
-
-This isn't limited to only retrieving config. You can also set config using the same method:
-
-
-
-```php
-$app->config('server.host', '127.0.0.1');
-```
-
-
-
-
-```php
-app()->config('server.host', '127.0.0.1');
-```
-
-
diff --git a/src/docs/config/nsm.md b/src/docs/config/nsm.md
deleted file mode 100755
index baa1e91f..00000000
--- a/src/docs/config/nsm.md
+++ /dev/null
@@ -1,99 +0,0 @@
-# Application Environment
-
-
-
-
-
-When building an application, it is helpful to distinguish between what is "running locally" versus what is "running in production". For example, you may have a different database running locally than you do on your production server.
-
-To make this a breeze, Leaf provides robust support for environment based configuration, allowing you to conveniently handle configuration values for different environments.
-
-## Environment variables
-
-In a sense of your applications, environment variables are dynamic values that affect the way your applications behave. They are part of the environment in which a process runs. For example, your app can use the value of the TEMP environment variable to discover a suitable location to store temporary files. Environment variables are easy to change between environments, such as development, staging, and production.
-
-
-
-## Loading env variables
-
-Leaf doesn't come with an env loader out of the box, but you can add one yourself. Env loaders allow you to load environment variables from a `.env` file into PHP's `$_ENV` and `$_SERVER` globals. You can then access these variables using the `_env()` helper function that Leaf provides. Here's a list of some of the most popular env loaders:
-
-- [vlucas/phpdotenv](https://github.com/vlucas/phpdotenv)
-- [symfony/dotenv](https://github.com/symfony/dotenv)
-
-## Using env variables
-
-After loading your env variables, you can access them using the `_env()` helper function. The `_env()` function takes in a key and a default value. If the key is found, the value is returned, otherwise the default value is returned.
-
-```php
-$serverEnvironment = _env('APP_ENV', 'development');
-```
-
-## Application Modes
-
-Using the concept of environments like `development`, `testing`, and `production` is a common way to prepare an application to behave correctly in each environment. Leaf takes this concept one step further and introduces the concept of application modes. Application modes allow you to configure your application for a specific purpose.
-
-For example, you may want to enable debugging in “development” mode but not in “production” mode. The examples below demonstrate how to configure Leaf differently for a given mode.
-
-### Setting your application mode
-
-Leaf will automatically set the application mode based on the value of the `APP_ENV` environment variable. If the `APP_ENV` environment variable is not set, Leaf will set the application mode to `development`. This is because Leaf assumes you are developing your application locally when no environment is set.
-
-You can also set the application mode manually using the `mode` setting in your application settings.
-
-
-
-```php
-$app->config([
- 'mode' => 'production'
-]);
-```
-
-
-
-
-```php
-app()->config([
- 'mode' => 'production'
-]);
-```
-
-
-
-### Using your application mode
-
-The Leaf instance provides a `script()` method that allows you to register a callable that will be invoked when the application mode matches the given mode. The `script()` method accepts two arguments: the mode and a callable.
-
-
-
-```php
-$app->script('production', function () use ($app) {
- $app->config([
- 'log.enable' => true,
- 'debug' => false
- ]);
-});
-```
-
-
-
-
-```php
-app()->script('production', function () {
- app()->config([
- 'log.enable' => true,
- 'debug' => false
- ]);
-});
-```
-
-
-
-The above example will enable logging and disable debugging when the application mode is set to `production`.
diff --git a/src/docs/config/settings.md b/src/docs/config/settings.md
old mode 100755
new mode 100644
index 37bba912..6ddfcb15
--- a/src/docs/config/settings.md
+++ b/src/docs/config/settings.md
@@ -1,128 +1 @@
# App Settings
-
-
-
-Leaf has lots of configurations which can be used to determine the way Leaf behaves in your application. You can check the [config page](/docs/config/) for more information on how to set and get configs. This page will show you all the configs available in Leaf. Note that we will only cover the user-facing configs, configs that are used internally by Leaf will not be covered here.
-
-## app.down
-
-This configuration tells Leaf whether to place your app in a maintenance like state. By default, this is set to `false`, but you can set it to `true` to place your app in a maintenance like state.
-
-```php
-'app.down' => true
-```
-
-When your app is in a maintenance like state, Leaf will automatically load the `down` screen. You can customize this screen using Leaf's `setDown` method.
-
-```php
-$app->setDown(function () {
- echo 'Custom Down Handler!';
-});
-```
-
-**You can read more about the down screen [here](/docs/routing/errors#application-down).**
-
-## debug
-
-By default, Leaf will display all errors and warnings you encounter while developing your app. However, when you're ready to deploy your app, you should turn off debugging to prevent users from seeing errors. You can do this by setting the `debug` config to `false`.
-
-```php
-'debug' => false
-```
-
-Note that when you set `debug` to `false`, Leaf will automatically turn off error reporting and display a custom error page to users. You can customize this page using Leaf's `setError` method.
-
-```php
-$app->setError(function () {
- echo "Custom Error Handler!";
-});
-```
-
-## Logging
-
-Leaf has a built-in logger that can be used to log errors and other messages. You can check the [logging page](/docs/tooling/logging) for more information on how to use Leaf's logger. This page will show you all the configs available for Leaf's logger.
-
-To get started, make sure you have the [logger module](/docs/tooling/logging) installed. Once installed, you should have access to a `logger()` method on the Leaf instance. You can use this method to access Leaf's logger if you want to manually log messages.
-
-```php
-$app->logger()->info('Hello World!');
-```
-
-Below are all the configs available for Leaf's logger:
-
-### log.enabled
-
-This enables or disables Leaf’s logger. You need to set this to `true` to enable logging.
-
-```php
-'log.enabled' => true
-```
-
-Note that if `log.enabled` is set to `false`. Leaf will skip initializing anything related to logs, as such, you won't have access to `$app->logger()`, `$app->log` or `$app->logWriter`.
-
-### log.dir
-
-This tells leaf which directory to save and look for logs.
-
-```php
-'log.dir' => __DIR__ . '/logs/'
-```
-
-### log.file
-
-This setting tells leaf which file to write logs to.
-
-```php
-'log.file' => 'crashes.log'
-```
-
-*By default, Leaf will write logs to a file named `log.txt`.*
-
-### log.level
-
-Leaf has these log levels:
-
-- \Leaf\Log::EMERGENCY
-- \Leaf\Log::ALERT
-- \Leaf\Log::CRITICAL
-- \Leaf\Log::ERROR
-- \Leaf\Log::WARN
-- \Leaf\Log::NOTICE
-- \Leaf\Log::INFO
-- \Leaf\Log::DEBUG
-
-The `log.level` application setting determines which logged messages will be honored and which will be ignored. For example, if the `log.level` setting is `\Leaf\Log::INFO`, debug messages will be ignored while info, warn, error, and fatal messages will be logged.
-
-### log.open
-
-This option takes in a boolean and determines whether Leaf should create the specified log file if it doesn't exist.
-
-### log.writer
-
-Use a custom log writer to direct logged messages to the appropriate output destination. By default, Leaf’s logger will write logged messages to `STDERR`. If you use a custom log writer, it must implement this interface:
-
-```php
-public write(mixed $message, int $level);
-```
-
-The `write()` method is responsible for sending the logged message (not necessarily a string) to the appropriate output destination (e.g. a text file, a database, or a remote web service). The `$level` argument is one of the log levels listed above.
-
-```php
-'log.writer' => new \My\LogWriter()
-```
-
-## views.path
-
-The relative or absolute path to the filesystem directory that contains your Leaf application’s view files.
-
-```php
-'views.path' => './views'
-```
-
-## views.cachePath
-
-When using a view engine, this config tells Leaf where to store cached views.
-
-```php
-'views.cachePath' => './views/cache'
-```
diff --git a/src/modules/password/index.md b/src/docs/data/encryption.md
old mode 100755
new mode 100644
similarity index 89%
rename from src/modules/password/index.md
rename to src/docs/data/encryption.md
index 184bdb16..1758aacf
--- a/src/modules/password/index.md
+++ b/src/docs/data/encryption.md
@@ -1,25 +1,27 @@
-# Leaf Password
-
-
+# Password Encryption
Password encoding and verification are one of the most important parts of any application. This usually involves a lot of security concerns and can be a pain to implement. Leaf makes this process a lot easier with the password helper.
-This module simply helps create and manage passwords, encrypt and verify without any security concerns. It is fully static, as such, can be used from anywhere in your application.
+Before you go on, Leaf already has a [full authentication system](/docs/auth/) that comes with simple authentication, session/token management and so much more. Your use case may already be covered by Leaf Auth, so be sure to check that first.
+
+## Setting up
-## Installation
+You can install the password helper using the Leaf CLI:
-You can quickly install a password helper through the leaf cli:
+::: code-group
-```bash
+```bash:no-line-numbers [Leaf CLI]
leaf install password
```
-or you can install it via composer:
-
-```bash
+```bash:no-line-numbers [Composer]
composer require leafs/password
```
+:::
+
+From there, you can use any of the Password methods.
+
## spice
Just as the name implies, spice adds a little "spice" to users' passwords. They help make even weak passwords a pain for systems to crack by chaining additional characters to the password before encoding or decoding.
diff --git a/src/docs/data/validation.md b/src/docs/data/validation.md
new file mode 100644
index 00000000..fbad7357
--- /dev/null
+++ b/src/docs/data/validation.md
@@ -0,0 +1,271 @@
+# Data Validation
+
+Input validation is the process of checking the data that users enter into your app (like forms, login pages, or search boxes) to make sure it's correct and safe. This helps prevent mistakes, like someone entering letters where numbers are needed, and protects your app from harmful data, like malicious code.
+
+Leaf provides a form module that helps you easily validate your data. This module comes with a lot of built-in rules validation rules, and even allows you add your own custom rules.
+
+## Setting Up
+
+You can install the form module using the Leaf CLI:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install form
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/form
+```
+
+:::
+
+Once you've installed the form module, you can start validating data right on the incoming request.
+
+## Validating an incoming request
+
+Validation is usually done inside your route handler. This can be a function passed into the router or a controller method. Regardless of where you're validating your data, you can easily validate incoming data on the `request()` object.
+
+Here's how you can validate incoming data:
+
+```php
+$validatedData = request()->validate([
+ 'title' => 'string|min:5',
+ 'body' => 'email',
+ 'description' => ['optional', 'string', 'min:8']
+]);
+```
+
+The `validate()` method takes an array of rules to validate the incoming data. The keys in your array should match the keys in the incoming data. For example, if you're validating a form with a username and password, your validation array should look like this:
+
+```php
+[
+ 'username' => '...',
+ 'password' => '...',
+]
+```
+
+If the incoming data doesn't match the rules you've set, the validation will fail and the `validate()` method will return false. You can get the validation errors by calling the `errors()` method on the request object.
+
+```php
+$validatedData = request()->validate([
+ 'title' => 'string|min:5',
+ 'body' => 'email',
+ 'description' => 'optional|string|min:8'
+]);
+
+if(!$validatedData) {
+ // Handle validation errors
+ $errors = request()->errors();
+}
+```
+
+We do this to allow you handle validation errors in your own way. You can return the errors as JSON, redirect the user back to the form, or do anything else you want.
+
+## Customizing Error Messages
+
+Leaf Form comes with a default set of error messages for each validation rule. However, you can customize these messages to suit your needs. You can do this by using the `message()` method on the request object.
+
+```php
+request()->validator()->message([
+ 'required' => '{field} is required',
+ 'email' => '{field} must be a valid email address',
+]);
+```
+
+It takes in an array of messages where the key is the rule name and the value is the message you want to display. The message also contains a few placeholders that you can use to display the field name in the error message. Here's a list of all the available placeholders:
+
+- `{field}`: The name of the field being validated
+- `{value}`: The value of the field being validated
+
+If you want to capitalize the first letter of the placeholder, you just need to capitalize the first letter of the placeholder. For example, `{Field}` will display the field name with the first letter capitalized.
+
+```php
+request()->validator()->message([
+ 'required' => '{Field} is required',
+ 'email' => '{field} debe ser una dirección de correo válida',
+]);
+
+...
+
+$validatedData = request()->validate([
+ 'title' => 'string',
+ 'email' => 'email',
+]);
+
+if (!$validatedData) {
+ $errors = request()->errors();
+ // 'title' => 'Title is required'
+ // 'email' => 'email debe ser una dirección de correo válida'
+}
+```
+
+## Available Validation Rules
+
+Leaf Form comes with a number of built-in rules that you can use to validate data. Here's a list of all the available rules:
+
+| Rule | Description |
+| --- | --- |
+| `email` | The field under validation must be formatted as an e-mail address. |
+| `text` | The field under validation must contain only alphabetic characters and spaces. |
+| `textOnly` | The field under validation must contain only alphabetic characters (no-spaces). |
+| `alpha` | The field under validation must contain only alphabetic characters. |
+| `alphaNum` | The field under validation must contain only alpha-numeric characters. |
+| `alphaDash` | The field under validation must contain only alpha-numeric characters, underscores, and dashes. |
+| `username` | The field under validation must contain only alpha-numeric characters and underscores. |
+| `number` | The field under validation must contain only numeric characters. |
+| `float` | The field under validation must contain only float values. |
+| `date` | The field under validation must be a valid date. |
+| `min` | The field under validation must have a minimum value. |
+| `max` | The field under validation must have a maximum value. |
+| `between` | The field under validation must be between two values in length. |
+| `match` | The field under validation must match a value. |
+| `contains` | The field under validation must contain a value. |
+| `in` | The field under validation must be included in a given list of values. |
+| `ip` | The field under validation must be a valid IP address. |
+| `ipv4` | The field under validation must be a valid IPv4 address. |
+| `ipv6` | The field under validation must be a valid IPv6 address. |
+| `url` | The field under validation must be a valid URL. |
+| `domain` | The field under validation must be a valid domain. |
+| `creditCard` | The field under validation must be a valid credit card number. |
+| `phone` | The field under validation must be a valid phone number. |
+| `uuid` | The field under validation must be a valid UUID. |
+| `slug` | The field under validation must be a valid slug. |
+| `json` | The field under validation must be a valid JSON string. |
+| `regex` | The field under validation must match a given regular expression. |
+
+## Optional Fields
+
+Unlike other validation libraries, Leaf expects all incoming data to be present. This is because we believe that all incoming data should be validated. However, we understand that there are cases where you might want to make a field optional. You can do this by adding the `optional` rule to the field.
+
+```php{4}
+$validatedData = request()->validate([
+ 'title' => 'string|min:5',
+ 'body' => 'email',
+ 'description' => 'optional|string|min:8'
+]);
+```
+
+## Passing parameters to rules
+
+Some rules like `min`, `max`, `between`, `match`, `contains`, `in` and `regex` require additional parameters. You can pass these parameters to the rules by separating them with a colon (`:`).
+
+```php{2}
+request()->validate([
+ 'bio' => 'min:10',
+]);
+```
+
+Some rules like `between` and `in` require multiple parameters. You can pass these parameters by using an array.
+
+```php{2}
+request()->validate([
+ 'bio' => 'between:[18,30]',
+]);
+```
+
+## Custom Validation Rules
+
+You can create your own rules using the `addRule()` method or it's alias `rule()`. It takes in three arguments:
+
+- The name of the rule
+- The rule's handler which can be a regular expression or a function that returns a boolean
+- The rule's error message for when the rule fails
+
+::: code-group
+
+```php [Regular Expression]
+request()->validator()->rule('isEven', '/^\d*[02468]$/', '{field} must be even.');
+
+...
+
+$validatedData = request()->validate([
+ 'number' => 'isEven',
+]);
+```
+
+```php [Validator Function]
+request()->validator()->rule('superTest', function ($value) {
+ // in functions, you can also add the error messages like this
+ request()->validator()->message('superTest', '{field} should be superTest!');
+
+ return $value === 'superTest';
+});
+
+...
+
+$validatedData = request()->validate([
+ 'test' => 'superTest'
+]);
+```
+
+:::
+
+## Validating Indexed Arrays
+
+PHP provides 2 different kinds of arrays: indexed arrays and associative arrays. Indexed arrays are arrays with numeric keys, while associative arrays are arrays with string keys.
+
+An indexed array can contain a list of values, like a list of numbers or strings. Leaf allows you to validate the values in an indexed array to make sure they're what you expect.
+
+```php
+['one', 'two', 'three'] // Indexed array of strings
+[1, 2, 3] // Indexed array of numbers
+```
+
+You can validate an indexed array like this:
+
+```php
+$validatedData = request()->validate([
+ 'items' => 'array',
+ 'numbers' => 'array'
+ 'emails' => 'array',
+ 'passwords' => 'array'
+]);
+```
+
+The example above shows how to use the `array` rule to validate an indexed array. The `array` rule takes a type argument that can be any of the available validation rules. Using this, you can make sure that arrays don't contain any unexpected values.
+
+## Validating Associative Arrays/Objects
+
+Associative arrays are arrays with string keys. They're usually used to represent objects or key-value pairs. Leaf allows you to validate the values in an associative array to make sure they're what you expect.
+
+```php
+['name' => 'John Doe', 'age' => 25] // Associative array of strings and numbers
+```
+
+Unlike indexed arrays, validating associative arrays requires you to specify the rules for each key in the array. You can do this by using the `.` operator to specify the rules for each key.
+
+```php
+$validatedData = request()->validate([
+ 'user.name' => 'string',
+ 'user.age' => ['number', 'optional']
+]);
+```
+
+Things get a bit funny here because a user may pass a string with the key `user.name` into your application. If you try to validate this, Leaf will fail the validation because it's expecting an associative array or object. To fix this, you can use `\.` instead of `.` to escape the `.` character.
+
+```php
+$validatedData = request()->validate([
+ 'user\.name' => 'string',
+]);
+```
+
+## Validating Data from other sources
+
+Sometimes, you may want to validate data that does not come from the request object. You can do this by accessing the `Leaf\Form` class directly. We have a `form()` shortcut that returns the validator instance.
+
+```php
+$dataToValidate = [
+ 'name' => 'John Doe',
+ 'age' => 25
+];
+
+$validatedData = form()->validate($dataToValidate, [
+ 'name' => 'string',
+ 'age' => 'number'
+]);
+
+if (!$validatedData) {
+ $errors = form()->errors();
+}
+```
diff --git a/src/docs/database/builder.md b/src/docs/database/builder.md
new file mode 100644
index 00000000..74b0af80
--- /dev/null
+++ b/src/docs/database/builder.md
@@ -0,0 +1,369 @@
+# Query Builder
+
+Although you can write raw queries using the `query()` method, there's no fun in that. Leaf DB provides a query builder that makes it easy to write queries in a more readable and secure way. Let's take a look at what you can do with the query builder.
+
+## Creating a database
+
+This is something you would usually want to do outside of your application, but there are a few rare cases where you might want to create a database from within your application. Leaf DB provides a `create()` method that allows you to do just that.
+
+```php
+db()->create('dbname')->execute();
+```
+
+
+
+## Dropping a database
+
+Dropping a database is the opposite of creating one. It deletes the database and all its contents. Leaf DB provides a `drop()` method that allows you to do this.
+
+```php
+db()->drop('dbname')->execute();
+```
+
+Be careful when using this method, as it will delete all the data in the database.
+
+## Adding data to a database
+
+Inserting data into a database means adding new entries to a table. You specify which table and columns to use, then provide the data. To do this, Leaf provides the `insert()` method.
+
+This method needs the name of the table you want to add data to, like "users", and then it allows you to build the rest of your query from there. What we need now is to add the data we want to insert into the table. We can do this using the `params()` method.
+
+Here's an example:
+
+```php
+db()->insert('users')->params(['username' => 'mychi']);
+```
+
+This is equivalent to the following SQL query:
+
+```sql
+INSERT INTO users (username) VALUES ('mychi')
+```
+
+Of course, it automatically takes care of parameter binding, which is important for preventing SQL injection attacks. Now that we have our query, we can execute it using the `execute()` method. Here's an example:
+
+```php
+db()
+ ->insert('users')
+ ->params(['username' => 'mychi'])
+ ->execute();
+```
+
+This will insert a new user with the username "mychi" into the users table.
+
+## Making values unique
+
+A unique column does not allow duplicate values. Eg. you can't have two users with the same email address in a lot of applications. You'll usually get an error if you try to insert a duplicate value into a unique column. Leaf DB provides a `unique()` helper that makes sure the value you're trying to insert is unique.
+
+```php{8}
+db()
+ ->insert('users')
+ ->params([
+ 'username' => 'mychi',
+ 'email' => 'mychi@leafphp.dev',
+ 'password' => hash('test')
+ ])
+ ->unique('username', 'email')
+ ->execute();
+```
+
+This also works when you are updating a row. If you try to update a row with a value that already exists in a unique column, you'll get an error.
+
+## Getting the last inserted ID
+
+When you insert a new row into a table, the database assigns it a unique ID. This ID is **usually** an auto-incrementing integer that starts at 1 and increments by 1 for each new row. Leaf DB provides a `lastInsertId()` method that allows you to get the ID of the last row you inserted.
+
+```php
+db()->insert('users')->params(['username' => 'mychi'])->execute();
+
+$lastId = db()->lastInsertId();
+```
+
+## Reading data from a database
+
+Reading from a database means retrieving data stored in a table. Leaf DB provides a `select()` method that allows you to build a query to retrieve data from a table. The `select()` method takes the name of the table you want to read from as its argument.
+
+```php
+db()->select('users')->all();
+```
+
+This will return all the rows in the users table. You can also specify the columns you want to return by passing them as the second argument to the `select()` method.
+
+```php
+db()->select('users', 'name, created_at')->all();
+```
+
+This will return only the name and created_at columns from the users table.
+
+Most of the time, you'll want to read data based on certain conditions. That's where conditional queries come in.
+
+## Conditional queries
+
+Leaf DB provides a `where()` method that allows you to add conditions to your query. The `where()` method takes a column name, an operator, and a value as its arguments.
+
+```php
+db()
+ ->select('users')
+ ->where('name', 'John Doe')
+ ->fetchObj();
+```
+
+This will return the matching row in the users table where the name is "John Doe". You can also pass an array of column names and values to the `where()` method.
+
+```php
+db()
+ ->select('users')
+ ->where(['name' => 'John Doe', 'age' => 20])
+ ->fetchObj();
+```
+
+The `where()` method also allows you to use comparison operators like `>`, `<`, `>=`, `<=`, `!=`, and `LIKE`.
+
+```php
+db()
+ ->select('items')
+ ->where('tag', 'LIKE', '%new%')
+ ->fetchAll();
+```
+
+This will return all the rows in the items table where the tag column contains the word "new".
+
+### OR conditions
+
+By default, the `where()` method adds conditions using the `AND` operator. Meaning all conditions must be met for a row to be returned. For example, the following query will return all the rows in the users table where the name is "John Doe" and the age is 20.
+
+```php
+db()
+ ->select('users')
+ ->where(['name' => 'John Doe', 'age' => 20])
+ ->fetchAll();
+```
+
+If you have a record where the name is "John Doe" but the age is not 20, it won't be returned. If you want to return rows where any of the conditions are met, you can use the `orWhere()` method.
+
+```php
+db()
+ ->select('users')
+ ->where('name', 'John Doe')
+ ->orWhere('age', 20)
+ ->fetchAll();
+```
+
+This will return all the rows in the users table where the name is "John Doe" or the age is 20. You can make things easier by passing an array of conditions to the `orWhere()` method.
+
+```php
+db()
+ ->select('users')
+ ->orWhere(['name' => 'John Doe', 'age' => 20])
+ ->fetchAll();
+```
+
+## Finding Data by ID
+
+Almost every database table has an `id` column that uniquely identifies each row. Leaf DB provides a `find()` method that allows you to retrieve a row by its `id`.
+
+```php
+db()->select('users')->find(1);
+```
+
+This will look in the "users" table for the row with the `id` of 1 and return it.
+
+## Updating data in a database
+
+Updating data in a database works by finding the data you want to update and then passing new data in to change the existing data. Leaf DB provides an `update()` method that allows you to build a query to update data in a table. You need to pair this with the `params()` method to specify the new data you want to update.
+
+Here's an example:
+
+```php
+db()
+ ->update('users')
+ ->params(['name' => 'Jane Doe'])
+ ->execute();
+```
+
+This will update every row in the users table with the name "Jane Doe". This is not something you want to do, so you can use conditional queries to update specific rows.
+
+```php
+db()
+ ->update('users')
+ ->params(['name' => 'Jane Doe'])
+ ->where('id', 1)
+ ->execute();
+```
+
+This will update the row in the users table with the `id` of 1 to have the name "Jane Doe".
+
+## Deleting data from a database
+
+Deleting data from a database works by finding the data you want to delete and then removing it from the table. Leaf DB provides a `delete()` method that allows you to build a query to delete data from a table.
+
+Here's an example:
+
+```php
+db()->delete('users')->execute(); // careful now 🙂
+```
+
+This query will delete all the rows in the users table (be careful with this one). There is rarely a case where you would want to delete all the rows in a table, so you can use conditional queries to delete specific rows.
+
+```php
+db()
+ ->delete('users')
+ ->where('id', '1')
+ ->execute();
+```
+
+This will delete the row in the users table with the `id` of 1.
+
+## Database Transactions
+
+Database transactions are a way to ...
+Leaf DB allows you to create database transactions using the `transaction()` method. It takes in a callable which is every query you want to perform as part of your transaction.
+
+```php
+db()->transaction(function ($db) {
+ $db->insert('purchases')->params(...)->execute();
+ $db->update('balances')->params(...)->where(...)->execute();
+
+ // you can even do external stuff here
+ $res = fetch()->post(...)
+
+ $doSomething = $res->data;
+
+ ...
+});
+```
+
+If anything in the function fails, Leaf will automatically rollback every change that has been made in the database till that point and return `false`. You can get the associated error using the `errors()` method.
+
+```php
+$success = db()->transaction(function () {
+ ...
+});
+
+if ($success) {
+ // do something
+} else {
+ $errors = db()->errors();
+}
+```
+
+This is useful especially when you have a set of queries that rely on third party influence.
+
+## Hiding columns from results
+
+Sometimes you might want to hide certain columns from the results of a query. For instance, you might want to hide the password column from the results of a query on the users table. Leaf DB provides a `hide()` method that allows you to do this.
+
+```php
+db()
+ ->select('users')
+ ->hide('password')
+ ->all();
+```
+
+Or on a conditional query:
+
+```php
+db()
+ ->select('users')
+ ->where('id', '1')
+ ->hide('remember_token', 'reset_q_id')
+ ->first();
+```
+
+## Adding custom fields to results
+
+Sometimes you might want to add custom fields to the results of a query. For instance, you might want to add a `full_name` field to the results of a query on the users table. Leaf DB provides a `add()` method that allows you to do this.
+
+```php
+db()
+ ->select('users')
+ ->add('full_name', 'Something Here')
+ ->all();
+```
+
+This will add a `full_name` field to the results of the query with the value "Something Here". You can also do this for single results:
+
+```php
+db()
+ ->select('users')
+ ->where('id', '1')
+ ->add('full_name', 'Something Here')
+ ->first();
+```
+
+## Ordering results
+
+You can order the results of a query using the `orderBy()` method. This method takes the column you want to order by as its first argument and the direction you want to order in as its second argument.
+
+```php
+db()
+ ->select('users')
+ ->orderBy('created_at', 'DESC')
+ ->all();
+```
+
+`DESC` is the default order, so you can leave it out if you want to order in descending order.
+
+```php
+db()
+ ->select('users')
+ ->orderBy('created_at')
+ ->all();
+```
+
+## Limiting results
+
+You can limit the number of results returned by a query using the `limit()` method. This method takes the number of results you want to limit to as its argument.
+
+```php
+db()
+ ->select('users')
+ ->limit(10)
+ ->all();
+```
+
+It works even better when combined with the `orderBy()` method.
+
+```php
+db()
+ ->select('users')
+ ->orderBy('created_at')
+ ->limit(10)
+ ->all();
+```
+
+## Error Handling
+
+There are lots of times where your query might fail. This could be because of a syntax error, a missing table, or a missing column. Leaf DB provides an `errors()` method that allows you to get the error message if your query fails.
+
+```php
+$res = db()
+ ->insert('users')
+ ->params('username', 'mychi')
+ ->unique('username')
+ ->execute();
+
+if ($res === false) {
+ response()->exit(db()->errors());
+}
+```
+
+You will get an error like this:
+
+```php
+[
+ "username" => "username already exists",
+]
+```
+
+We get this error because we set the `username` column to be unique, and we tried to insert a duplicate value.
diff --git a/src/docs/database/factories.md b/src/docs/database/factories.md
new file mode 100644
index 00000000..0b1a4c7a
--- /dev/null
+++ b/src/docs/database/factories.md
@@ -0,0 +1,101 @@
+# DB Factories
+
+Factories are a way to conveniently generate large amounts of database records. Instead of manually specifying the attributes for each model seed, you can use factories to define the attributes for each model. This way, you can easily generate a large number of records with random data.
+
+## Creating a Factory
+
+To create a factory, you can use the `g:factory` command. This command will create a new factory class in the `app/database/factories` directory.
+
+```bash
+php leaf g:factory UserFactory
+```
+
+This will create a new factory class in the `app/database/factories` directory. The factory class will contain a `definition` method that returns an array of attributes for the model. You can define the attributes for the model in this method.
+
+```php
+ strtolower($this->faker->firstName),
+ 'name' => $this->faker->name,
+ 'email' => $this->faker->unique()->safeEmail,
+ 'email_verified_at' => \Leaf\Date::now(),
+ 'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
+ 'remember_token' => 'random string',
+ ];
+ }
+}
+```
+
+This factory class defines the attributes for the `User` model. The `definition` method returns an array of attributes for the model. You can use the `faker` property to generate random data for the attributes.
+
+## Using a Factory
+
+To use a factory to generate records, you can use the `create` method on the factory class. This method will create a new record in the database using the attributes defined in the factory.
+
+```php
+(new UserFactory)->create(20)->save();
+```
+
+You would usually do this in your seeders to generate records for your database. You can use the `create` method to generate a single record or pass in the number of records you want to generate.
+
+```php
+create(20)->save();
+ }
+}
+```
+
+This will generate 20 records in the `users` table using the attributes defined in the `UserFactory` class.
+
+## Getting Faker Data
+
+In some cases, you may not want to save the generated records to the database. You can use the `get()` method to get the generated data without saving it to the database.
+
+```php
+$users = (new UserFactory)->create(20)->get();
+```
+
+## Running Factories
+
+You don't need to run factories manually. You can use the `db:seed` command to run your seeders, which will in turn run your factories.
+
+```bash
+php leaf db:seed
+```
diff --git a/src/docs/database/index.md b/src/docs/database/index.md
new file mode 100644
index 00000000..4e56e945
--- /dev/null
+++ b/src/docs/database/index.md
@@ -0,0 +1,168 @@
+# Leaf DB
+
+
+
+
+
+A database is an organized storage system for managing data like your users' profiles or product details. Leaf offers a lightweight module that simplifies database interaction and supports five major database systems.
+
+- MariaDB
+- MySQL
+- PostgreSQL
+- SQLite
+- SQL Server
+
+You can install the Leaf database module using the following command:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install db
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/database
+```
+
+:::
+
+::: details New to databases?
+
+Databases are essential for most applications, as they help you store and retrieve data efficiently. Check out this video from Linux Academy to learn more about databases and the different types available:
+
+
+
+
+
+:::
+
+## Connecting to a database
+
+The first step to using a database is to create a connection. It's like opening a door to the database, allowing you to interact with it. Here's how you can connect to a database using Leaf:
+
+```php
+db()->connect([
+ 'dbtype' => '...',
+ 'charset' => '...',
+ 'port' => '...',
+ 'unixSocket' => '...',
+ 'host' => '...',
+ 'username' => '...',
+ 'password' => '...',
+ 'dbname' => '...',
+]);
+```
+
+The `connect()` method takes an array of connection details for your database as its argument. Depending on the database system you're using, you'll need to provide different connection details. For example, here's how you can connect to a SQLite database:
+
+```php
+db()->connect([
+ 'dbtype' => 'sqlite',
+ 'dbname' => 'db.sqlite',
+]);
+```
+
+If you have a environment file, you can use it to store your database connection details. Here's an example of how you can connect to a MySQL database using an environment file:
+
+```txt
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=LeafMVC
+DB_USERNAME=root
+DB_PASSWORD=
+```
+
+Using the environment file, you can connect to the database like this:
+
+```php
+db()->autoConnect();
+```
+
+## Writing simple queries
+
+Once you've connected to a database, you can start writing queries to interact with it. Queries are the commands you run on your database to get, insert, update or delete data. Leaf DB provides a simple way to run queries using the query builder, but also allows you to run raw SQL queries.
+
+We can run queries using the `query()` method. This method takes in a query string and returns a query builder instance. This means that you can run queries like this:
+
+```php
+$users = db()->query('SELECT * FROM users')->all();
+```
+
+The `query()` method takes an SQL query that you want to execute as its argument. You can then use the query builder methods to modify your query. For example, you can bind values to your query using the `bind()` method:
+
+```php
+db()
+ ->query('SELECT * FROM users WHERE id = ?')
+ ->bind('1')
+ ->fetchObj();
+```
+
+This provides a more secure and dynamic way to write SQL if you need to.
+
+## Running queries
+
+There are different kinds of database commands: some give you results (like data) and some don’t. Leaf Db makes it easy to handle both types without any hassle.
+
+You can use `execute()` to run queries that don't return values. This method returns `true` if the query was successful and `false` if it wasn't. You can run a query like this:
+
+```php
+db()->query('CREATE DATABASE dbname')->execute();
+```
+
+If you want to run a query that returns data, you can use the `all()` method to get all the results. For example, you can run a query like this:
+
+```php
+$users = db()->query('SELECT * FROM users')->all();
+```
+
+This will return an array of all the users in the database that match the query.
+
+If you only want to get one result, you can use the `fetchObj()` or `fetchAssoc()` method. For example, you can run a query like this:
+
+```php
+$user = db()
+ ->query('SELECT * FROM users WHERE id = ?')
+ ->bind('1')
+ ->fetchObj();
+```
+
+This will return the matched user as an object.
+
+There may be times when you want to get a single value from a query that returns multiple rows. In such cases, you can use the `first()` method. For example, you can run a query like this:
+
+```php
+$user = db()->query('SELECT * FROM users')->first();
+```
+
+## Leaf DB + MVC
+
+Leaf MVC comes with a more structured way to work with databases. You can use models to interact with your database. This makes it easier to manage your database operations and keep your code clean. However, you can still use the query builder to run raw queries if you need to.
+
+To get started, you need to set up your database connection in your environment file.
+
+```txt
+DB_CONNECTION=mysql
+DB_HOST=127.0.0.1
+DB_PORT=3306
+DB_DATABASE=LeafMVC
+DB_USERNAME=root
+DB_PASSWORD=
+```
+
+From there, you just need to head over to `public/index.php` and uncomment the line that says `\Leaf\Database::initDb();`. This will automatically connect to your database using the details in your environment file.
+
+If you have multiple databases, Leaf DB will connect to your database which has been labelled as your default database. Leaf DB does not yet support multiple database connections, but of course, you can manually create multiple instances of Leaf DB.
diff --git a/src/docs/mvc/migrations.md b/src/docs/database/migrations.md
similarity index 66%
rename from src/docs/mvc/migrations.md
rename to src/docs/database/migrations.md
index 371fa6bc..f264676f 100644
--- a/src/docs/mvc/migrations.md
+++ b/src/docs/database/migrations.md
@@ -1,19 +1,18 @@
# Migrations
-
+Laravel database migrations are like version control for your database. They allow you to easily create, modify, or delete tables and columns in your database in a structured way, without having to manually write SQL queries.
-Database migrations are a technique used in software development to manage changes to a database schema over time. A database schema is the structure of a database that defines the tables, columns, relationships, and constraints that make up the data model.
-
-When changes are made to the database schema, such as adding a new table or column, modifying an existing column's data type, or changing a relationship between tables, database migrations allow developers to update the schema and propagate those changes to all instances of the database.
+When you make changes to your database like adding a new table or column, modifying an existing column's data type, or changing a relationship between tables, database migrations allow you to propagate those changes to all instances of your database.
## Generating Migrations
-You can quickly generate migrations using the `g:migration` command:
+Leaf MVC provides a simple way to generate migrations using the `g:migration` command:
```bash
php leaf g:migration
# example
+
php leaf g:migration flights
```
@@ -64,7 +63,7 @@ class CreateUsers extends Database {
```
::: tip Note
-Instead of building your migrations from scratch, you can use Leaf's schema builder to generate migrations from JSON data. [Learn more](/docs/mvc/schema).
+Instead of building your migrations from scratch, you can use Leaf's schema builder to generate migrations from JSON data. [Learn more](/docs/database/schema).
:::
## Running migrations
@@ -128,22 +127,3 @@ If you want to prevent seeds from running, you can use the `--noSeed` option:
```bash
php leaf db:reset --noSeed
```
-
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf MVC.
-
-
diff --git a/src/docs/database/models.md b/src/docs/database/models.md
new file mode 100644
index 00000000..6011c5f0
--- /dev/null
+++ b/src/docs/database/models.md
@@ -0,0 +1,293 @@
+# Models
+
+A model is a class that represents your app's data. It acts like the middle-man between your database and your app, allowing you work with the data in your database without writing complicated database code. Models have some advantages over using raw SQL queries and even using a query builder like Leaf DB, some of these advantages include:
+
+- Organization: Models keep your code organized by separating the database logic from other parts of your application (like views or controllers). This makes your code cleaner and easier to maintain.
+
+- Reusability: Once a model is set up, you can reuse it throughout your app to handle database interactions without duplicating code.
+
+- Consistency: Models enforce a consistent way of working with your data, reducing the chances of errors when interacting with the database.
+
+On top of all that, a single model corresponds to a single database table. This makes your data more organized and easier to work with.
+
+## Creating a model
+
+You can generate a model using the Aloe Console:
+
+```bash:no-line-numbers
+php leaf g:model flight
+```
+
+This will create a model at `app/models/Flight.php` which looks like this:
+
+```php
+name;
+}
+```
+
+This code will retrieve all rows from the `flights` table and then loop through each row, echoing the `name` attribute of each row.
+
+### Adding Additional Constraints
+
+The Leaf all method will return all of the results in the model's table. Since each Leaf model serves as a query builder, you may also add constraints to queries, and then use the get method to retrieve the results:
+
+```php
+$flights = Flight::where('active', 1)->orderBy('name', 'desc')->take(10)->get();
+```
+
+> **You can check [here](https://laravel.com/docs/10.x/queries) for available queries on your models.**
+
+### Refreshing Models
+
+You can refresh models using the `fresh` and `refresh` methods. The `fresh` method will re-retrieve the model from the database. The existing model instance will not be affected:
+
+```php
+$flight = Flight::where('number', 'FR 900')->first();
+
+$freshFlight = $flight->fresh();
+```
+
+The `refresh` method will re-hydrate the existing model using fresh data from the database. In addition, all of its loaded relationships will be refreshed as well:
+
+```php
+$flight = Flight::where('number', 'FR 900')->first();
+
+$flight->number = 'FR 456';
+
+$flight->refresh();
+
+$flight->number; // "FR 900"
+```
+
+## Inserting data using models
+
+Inserting data using your models involves creating a new instance of a model, setting its attributes, and saving it to the database.
+
+```php
+name = $this->request->name;
+
+ $flight->save();
+ }
+}
+```
+
+In this example, we assign the name parameter from the incoming HTTP request to the name attribute of the `Flight` model instance. When we call the save method, a record will be inserted into the database. The created_at and updated_at timestamps will automatically be set when the save method is called, so there is no need to set them manually.
+
+## Updating data using models
+
+To update data using a model, you retrieve the record you want to update, change its attributes, and then save it back to the database. Here's the step-by-step process:
+
+```php
+$flight = Flight::find(1); // Find the flight with an ID of 1
+
+$flight->name = 'New Flight Name'; // Change the name attribute
+
+$flight->save(); // Save the changes
+```
+
+In this example, we find the flight with an ID of 1, change its name attribute, and then save the changes. The updated_at timestamp will automatically be updated, so there is no need to manually set its value.
+
+## Deleting data using models
+
+Before we talk about how to delete data using models, let's talk about two ways to delete data using Leaf models. You can either use soft deletes or hard deletes.
+
+### Hard deletes
+
+A hard delete permanently removes a record from the database. Once deleted, the data is gone and cannot be recovered unless you have backups. This is the default behavior of Leaf models.
+
+```php
+$flight = Flight::find(1); // Find the flight with an ID of 1
+
+$flight->delete(); // Delete the flight
+```
+
+### Soft deletes
+
+A soft delete marks a record as deleted without actually removing it from the database. Instead, a `deleted_at` timestamp is set, and the record is hidden from query results. The data is still in the database, allowing you to restore it later if needed. To get started with soft deletes, add a `deleted_at` column to your table. You can do this by adding the following line to your [migration file](/docs/database/migrations):
+
+```php
+$table->timestamp('deleted_at')->nullable();
+```
+
+After that, we can add the `SoftDeletes` trait to our model. This is a trait provided by Eloquent that will automatically handle soft deletes for us:
+
+```php
+use Illuminate\Database\Eloquent\SoftDeletes;
+
+class Flight extends Model
+{
+ use SoftDeletes;
+}
+```
+
+Now, when you run the `delete()` method on the Flight model, the flight record will not be removed from the database but instead marked with a `deleted_at` timestamp.
+
+```php
+$flight = Flight::find(1); // Find the flight with an ID of 1
+
+$flight->delete(); // Soft delete the flight
+```
+
+## Model conventions
+
+Leaf models are built on top of [Laravel's Eloquent ORM](https://laravel.com/docs/11.x/eloquent), so everything you know about Eloquent applies to Leaf models. If you've never used Eloquent before, don't worry, we'll go over everything you need to get started.
+
+Every model corresponds to a database table, which is usually the snake_case, plural form of the model name. For example, a `Flight` model corresponds to a `flights` table. If this is not the case, you can specify the table name in your model like this:
+
+```php
+ false,
+ ];
+}
+```
+
+There's a lot more you can do with models, but this should be enough to get you started. You can check out the [Eloquent documentation](https://laravel.com/docs/11.x/eloquent) for more information on what you can do with models.
diff --git a/src/docs/database/other.md b/src/docs/database/other.md
new file mode 100644
index 00000000..fbaa4151
--- /dev/null
+++ b/src/docs/database/other.md
@@ -0,0 +1 @@
+# Other DB Engines
diff --git a/src/docs/database/redis.md b/src/docs/database/redis.md
new file mode 100644
index 00000000..532d3caa
--- /dev/null
+++ b/src/docs/database/redis.md
@@ -0,0 +1,250 @@
+# Leaf Redis
+
+
+
+
+
+Redis is like a powerful database, but instead of storing data on a hard drive like other databases, Redis keeps everything in memory (RAM), making it much super-fast. It's often used for things that need to be accessed really fast, like caching (storing temporary data), session management, or tracking real-time data.
+
+Leaf includes a Redis module that allows you to easily integrate Redis into your Leaf application.
+
+::: details New to Redis?
+
+We've included this amazing video by TechWorld with Nana to help you get started with Redis.
+
+
+
+:::
+
+## Setting Up Leaf Redis
+
+To get started with Leaf Redis, you need to have Redis installed on your machine. You can install Redis PHP extension by following the instructions [here](https://github.com/phpredis/phpredis/blob/develop/INSTALL.md).
+
+After that, we can install Leaf Redis through composer or the leaf cli.
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install redis
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/redis
+```
+
+:::
+
+Once that's done, we can start using Leaf Redis in our Leaf application. Just like any other database, we need to initialize a connection to Redis before we can start using it.
+
+```php
+redis()->connect();
+```
+
+This will initialize a new Redis connection. From there, you can start storing and retrieving data from Redis.
+
+## Usage with Leaf MVC
+
+If you're using Leaf MVC, you can add on some extra features to your setup. Leaf Redis comes with a few commands that you can attach to your Aloe CLI. You can do this by heading over to the `app/console/Commands.php` file in your Leaf MVC app and adding the following line to the return array.
+
+```php
+register([
+ ExampleCommand::class,
+ \Leaf\Redis::commands() // [!code ++]
+ ]);
+ }
+}
+```
+
+Once you've done that, you should have access to a bunch of new commands from Leaf Redis. The available commands are:
+
+```bash
+redis
+ redis:install Create leaf redis config and .env variables
+ redis:server Start redis server
+```
+
+You can then run `php leaf redis:install` to install the redis config and environment variables, and then `php leaf redis:server` to start the redis server.
+
+## Configuring Leaf Redis
+
+The `connect` method takes in an array for configuration. Below is the default config for `connect`.
+
+```php
+/*
+|--------------------------------------------------------------------------
+| Redis host
+|--------------------------------------------------------------------------
+|
+| Set the host for redis connection
+|
+*/
+'host' => '127.0.0.1',
+
+/*
+|--------------------------------------------------------------------------
+| Redis host port
+|--------------------------------------------------------------------------
+|
+| Set the port for redis host
+|
+*/
+'port' => 6379,
+
+/*
+|--------------------------------------------------------------------------
+| Redis auth
+|--------------------------------------------------------------------------
+|
+| Set the password for redis connection
+|
+*/
+'password' => null,
+
+/*
+|--------------------------------------------------------------------------
+| Redis session handler
+|--------------------------------------------------------------------------
+|
+| Set redis as session save handler
+|
+*/
+'session' => false,
+
+/*
+|--------------------------------------------------------------------------
+| Redis connection timeout
+|--------------------------------------------------------------------------
+|
+| Value in seconds (optional, default is 0.0 meaning unlimited)
+|
+*/
+'connection.timeout' => 0.0,
+
+/*
+|--------------------------------------------------------------------------
+| Redis connection reserved
+|--------------------------------------------------------------------------
+|
+| should be null if $retryInterval is specified
+|
+*/
+'connection.reserved' => null,
+
+/*
+|--------------------------------------------------------------------------
+| Redis session handler
+|--------------------------------------------------------------------------
+|
+| Connection retry interval in milliseconds.
+|
+*/
+'connection.retryInterval' => 0,
+
+/*
+|--------------------------------------------------------------------------
+| Redis connection read timeout
+|--------------------------------------------------------------------------
+|
+| Value in seconds (optional, default is 0 meaning unlimited
+|
+*/
+'connection.readTimeout' => 0.0,
+
+/*
+|--------------------------------------------------------------------------
+| Redis session save_path
+|--------------------------------------------------------------------------
+|
+| Save path for redis session. Leave null to automatically
+| generate the session save path. You can also use multiple save urls
+| by passing in an array.
+|
+*/
+'session.savePath' => null,
+
+/*
+|--------------------------------------------------------------------------
+| Redis session save_path options
+|--------------------------------------------------------------------------
+|
+| Options for session save path. You can pass in multiple options in
+| the order of the save path above.
+|
+*/
+'session.saveOptions' => [],
+```
+
+You can pick and choose which configuration options you want to set. You can set these configurations by passing an array to the `connect` method.
+
+```php
+redis()->connect([
+ // you can use multiple hosts
+ 'session.savePath' => ['tcp://host1:6379', 'tcp://host2:6379'],
+
+ // the first array is for the first host, second for the second host
+ 'session.saveOptions' => [['weight' => 1], ['weight' => 2]],
+]);
+```
+
+## Ping Pong
+
+You can check if your Redis connection is working by using the `ping()` method. The `ping()` method returns a string with the message "PONG" if the connection is successful.
+
+```php
+echo redis()->ping();
+```
+
+## Setting values
+
+You can set values in Redis using the `set()` method. The `set()` method takes in a key and a value.
+
+```php
+redis()->set('name', 'Michael');
+```
+
+You can also set multiple values at once by passing in an array.
+
+```php
+redis()->set([
+ 'name' => 'Michael',
+ 'age' => 22
+]);
+```
+
+## Getting values
+
+You can get values from Redis using the `get()` method. The `get()` method takes in a key and returns the value.
+
+```php
+$name = redis()->get('name');
+```
+
+You can also get multiple values at once by passing in an array.
+
+```php
+$values = redis()->get(['name', 'age']);
+
+// $values => ['name' => 'Michael', 'age' => 22]
+```
diff --git a/src/docs/mvc/schema.md b/src/docs/database/schema.md
similarity index 99%
rename from src/docs/mvc/schema.md
rename to src/docs/database/schema.md
index 52e91494..94cb22e8 100644
--- a/src/docs/mvc/schema.md
+++ b/src/docs/database/schema.md
@@ -57,7 +57,7 @@ In the example above, the `users` schema will be used to generate the migration.
php leaf db:migrate
```
-Read more about [migrations](/docs/mvc/migrations).
+Read more about [migrations](/docs/database/migrations).
## Data Types
@@ -98,7 +98,7 @@ Leaf Schema supports all the types supported by Laravel's Schema Builder. You ca
In the example above, the `username` field will be set to `$table->text` in the migration. This is the same as using `$table->text('username')` in your migration.
-
+
diff --git a/src/docs/docker.md b/src/docs/docker.md
new file mode 100644
index 00000000..010daaf7
--- /dev/null
+++ b/src/docs/docker.md
@@ -0,0 +1,203 @@
+# Docker + Leaf
+
+
+
+
+
+Docker allows developers to package their applications and dependencies into lightweight and portable containers, which can be easily deployed and run on any environment, making it easier to develop and deploy applications consistently. This means you don't have to worry about configuring or setting up complicated development tools such as web servers and databases on your local machine.
+
+::: details New to Docker?
+
+This video by Mosh Hamedani will walk you through the basics of Docker.
+
+
+
+:::
+
+This guide will walk you through how to set up your Leaf application using Docker from scratch. To get started, you need to install [Docker Desktop](https://www.docker.com/products/docker-desktop/). After this, you can either use the Leaf CLI or manually create your application.
+
+## Using the Leaf CLI
+
+The easiest way to get started with Docker in your Leaf applications is to use the Leaf CLI. The `create` command has a `--docker` option that allows you to create a new Dockerized Leaf app:
+
+```bash:no-line-numbers
+leaf create my-app --docker
+```
+
+It also works with the `--custom` option and the `gui` command:
+
+```bash:no-line-numbers
+leaf create my-app --custom # or
+leaf gui
+```
+
+Either one of these commands will ask you if you want to use Docker in your project. Once you confirm, Leaf will set up a new Leaf application with Docker support. Although your app is dockerized, Leaf CLI still allows you to use the `serve` command to start your application. This command will automatically start your application using Docker instead of the built-in server.
+
+```bash:no-line-numbers
+leaf serve
+```
+
+## Adding Docker to existing projects
+
+If you already have an existing Leaf application and you want to add Docker support to it, you will need to do so manually. We have provided a sample below that you can use as a reference. This section requires you to have a basic understanding of Docker and how it works and interacts with your application. We recommend checking out the [Docker documentation](https://docs.docker.com/) if you are new to Docker.
+
+We have provided two examples below, one for Apache and one for Nginx. You can choose the one that best suits your needs.
+
+### Dockerfile
+
+To build your Docker image, you'll use a `Dockerfile`. You can adjust this file to meet your specific requirements. We have example files for both Apache and Nginx running on PHP 8.3. To get started, create a docker directory in the root of your project and place the Dockerfile there.
+
+::: code-group
+
+```dockerfile [Dockerfile Apache]
+FROM php:8.3-apache
+
+COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
+
+RUN a2enmod rewrite
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ libzip-dev \
+ wget \
+ git \
+ unzip
+
+RUN docker-php-ext-install zip pdo pdo_mysql
+
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
+
+RUN composer global require leafs/cli
+
+RUN ln -s /root/.composer/vendor/bin/leaf /usr/local/bin/leaf
+
+# If you have a custom PHP ini file you can uncomment this line
+# COPY ./php.ini /usr/local/etc/php/php.ini
+
+RUN apt-get purge -y g++ \
+ && apt-get autoremove -y \
+ && rm -rf /var/lib/apt/lists/* \
+ && rm -rf /tmp/*
+
+WORKDIR /var/www
+
+RUN chown -R www-data:www-data /var/www
+
+CMD ["apache2-foreground"]
+```
+
+```dockerfile [Dockerfile Nginx]
+FROM php:8.3-fpm
+
+COPY default.conf /etc/nginx/conf.d/default.conf
+
+RUN apt-get update && apt-get install -y --no-install-recommends \
+ libzip-dev \
+ wget \
+ git \
+ unzip
+
+RUN docker-php-ext-install zip pdo pdo_mysql
+
+RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
+
+RUN composer global require leafs/cli
+
+RUN ln -s /root/.composer/vendor/bin/leaf /usr/local/bin/leaf
+
+# If you have a custom PHP ini file you can uncomment this line
+# COPY ./php.ini /usr/local/etc/php/php.ini
+
+RUN apt-get purge -y g++ \
+ && apt-get autoremove -y \
+ && rm -rf /var/lib/apt/lists/* \
+ && rm -rf /tmp/*
+
+WORKDIR /var/www
+
+RUN chown -R www-data:www-data /var/www
+
+CMD ["php-fpm"]
+```
+
+:::
+
+### docker-compose.yml
+
+The `docker-compose.yml` file is used to define and run multi-container Docker applications. You can use this file to define your application's services, networks, and volumes. Create a `docker-compose.yml` file in the root of your project and add the following content:
+
+```yml
+version: '3.1'
+services:
+ application:
+ build: ./docker
+ image: leafphp/docker
+ ports:
+ - '8080:80'
+ volumes:
+ - .:/var/www
+```
+
+### Server config
+
+The final piece of the puzzle is the server configuration file. You can use the following examples for Apache and Nginx. Depending on the web server you are using, create a configuration file in the `docker` directory.
+
+::: code-group
+
+```apache [Apache - 000-default.conf]
+
+ ServerAdmin webmaster@localhost
+ DocumentRoot /var/www
+
+
+ Options Indexes FollowSymLinks
+ AllowOverride All
+ Require all granted
+
+
+```
+
+```nginx [Nginx - default.conf]
+server {
+ listen 80;
+ index index.php index.html;
+ server_name localhost;
+ error_log /var/log/nginx/error.log;
+ access_log /var/log/nginx/access.log;
+ root /var/www/public;
+
+ location / {
+ try_files $uri $uri/ /index.php?$query_string;
+ }
+
+ location ~ \.php$ {
+ include fastcgi_params;
+ fastcgi_pass php:9000;
+ fastcgi_index index.php;
+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
+ fastcgi_param PATH_INFO $fastcgi_path_info;
+ }
+}
+```
+
+:::
+
+After adding these files, you can start your application using Docker by running the following command:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf serve
+```
+
+```bash:no-line-numbers [Docker Compose]
+docker compose up
+```
+
+:::
diff --git a/src/docs/frontend/bareui.md b/src/docs/frontend/bareui.md
new file mode 100644
index 00000000..5152d2fe
--- /dev/null
+++ b/src/docs/frontend/bareui.md
@@ -0,0 +1,220 @@
+# BareUI
+
+
+
+
+
+BareUI is a simple, lightweight, and barebones templating engine focused on speed, speed, and more speed! Most templating engines out there ship with a nice syntax, handy ways to use expressions, layouts and code blocks, however, there's one problem: they are slow!
+
+BareUI takes advantage of PHP's innate templating capabilities so it's syntax is PHP's syntax. It lacks all the syntactic sugar added in other engines like blade, but it also requires no compiling, no caching, just speed!
+
+::: details New to template engines?
+
+Learn how using a template engine can improve your view files with "dumb" templates that are easy to read and understand in this video by LaraCasts.
+
+
+
+:::
+
+## Setting Up
+
+You can install BareUI through the Leaf CLI:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install bareui
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/bareui
+```
+
+:::
+
+Once installed, BareUI will be available in your Leaf app on the `bareui()` method. This makes it easy to use BareUI from anywhere in your app.
+
+```php
+app()->bareui()->render('welcome');
+```
+
+## Configuring BareUI
+
+BareUI doesn't require any real configuration to work, but you need to tell it where to look for your templates. You can do this using the `config()` method. If you are using Leaf MVC, this has already been done for you in the `config/view.php` file, so you can skip this step.
+
+```php
+app()->bareui()->config('path', './views');
+```
+
+This will tell BareUI to look for templates in the `views` directory in your project. Now that BareUI knows where to look for templates, you can start writing your templates.
+
+## Writing Templates
+
+BareUI templates are regular PHP files, so you can create your templates using PHP without learning any new syntax or special language. These template files have a .view.php extension, making it easy to identify them separately from other files in your project. This approach keeps things simple and familiar for PHP developers.
+
+::: code-group
+
+```html [welcome.view.php]
+
+
+
+
+
+
+
Document
+
+
+ Hello World
+
+
+```
+
+:::
+
+## Rendering Templates
+
+Once you have your template, you can render it using the `render` method. This method takes in the name of the template to render and an array of data to pass to the template.
+
+```php
+echo app()->bareui()->render('welcome');
+```
+
+When rendering a template, you don't need to include the `.view.php` extension in the template name. BareUI automatically adds it for you when it looks for the template file. So, you only need to pass the name of the template without the extension, and BareUI will handle the rest!
+
+## Passing Data to Templates
+
+Passing data into a template file means sending information from your main code to a template so it can be displayed or used there. Template files are pretty dumb on their own; they don't know anything about the outside world. They just display whatever data you pass to them.
+
+Let's look at a simple template:
+
+::: code-group
+
+```blade [welcome.view.php]
+
+
+
+
+
+
+
Document
+
+
+ Hello
+
+
+```
+
+:::
+
+This is an empty HTML page with a PHP tag that echoes a variable. On its own, this template doesn't do much. But when we fill in the `$name` variable, it will display the value of that variable on the page.
+
+To pass data to this `$name` variable, you can pass an array of data as the second argument to the `render()` method. This array should contain the same keys as the variables you want to use in the template.
+
+```php
+echo app()->bareui()->render('welcome', [
+ 'name' => 'Something',
+]);
+```
+
+This will render the template and replace the `$name` variable with the value `'Something'`. You can pass as many variables as you want to the template, and they will all be available in the template file. These values can be anything from strings to arrays, objects, or even functions.
+
+```php [app.php]
+echo app()->template->render('products', [
+ 'items' => [
+ ['name' => 'Item 1'],
+ ['name' => 'Item 2'],
+ ],
+]);
+```
+
+And in your template file:
+
+::: code-group
+
+```blade [app.view.php]
+
+
+
+
+
+
+
Document
+
+
+ 0) : ?>
+
+
+
There are no items
+
+
+
+```
+
+:::
+
+This will render a list of items if there are any items in the array, or display a message if there are no items. You can use this approach to pass any data you want to your templates and display it however you like.
+
+## What about Security?
+
+Lots of templating engines shun PHP's native templating capabilities because they don't encode output by default. This can lead to security vulnerabilities if you're not careful. While BareUI doesn't come with any built-in encoding, Leaf takes care of this for you. Leaf automatically encodes all data in your app to prevent XSS attacks. This means you can safely echo data in your templates without worrying about encoding it yourself.
+
+## Control Structures
+
+BareUI supports all the control structures you'd expect in a templating engine. This includes `if`, `else`, `elseif`, `foreach`, `for`, and `while` loops. You can use these control structures to conditionally display content, loop over arrays, and more.
+
+```blade
+
+ 1) : ?>
+
+
+
+
+
There is only one item
+
+
There are no items
+
+
+```
+
+As you guessed, any valid PHP code can be used in BareUI templates. This means you can use any PHP function, class, or method in your templates. This makes BareUI a powerful templating engine that can handle any task you throw at it.
+
+## Sub-templates
+
+Sub-templates are templates that are included in other templates. This allows you to break your templates into smaller, more manageable pieces that can be reused across multiple templates. This is a great way to keep your templates DRY and avoid repeating yourself.
+
+To include a sub-template in a template, you can use the `$template->render()` method with the name of the sub-template you want to include.
+
+```blade
+
+ render('partials/header'); ?>
+
+
Welcome to my site
+
+ render('partials/footer', [
+ 'year' => date('Y'),
+ ]);
+ ?>
+
+```
+
+All BareUI templates have access to the `$template` variable, which is an instance of the BareUI engine. Calling the `render()` method on this variable will include the specified sub-template in the current template.
diff --git a/src/docs/frontend/blade.md b/src/docs/frontend/blade.md
new file mode 100644
index 00000000..87bbb1d2
--- /dev/null
+++ b/src/docs/frontend/blade.md
@@ -0,0 +1,116 @@
+# Leaf + Blade
+
+
+
+
+
+Blade is a templating engine included with Laravel that helps you create dynamic views easily. Unlike other templating engines, Blade allows you to use regular PHP code inside your templates together with all the goodness it offers you. Behind the scenes, Blade templates are turned into plain PHP and cached, so they run quickly without slowing down your app. Blade files use the `.blade.php` extension to distinguish them from regular PHP files.
+
+Leaf Blade is a port of the [jenssegers/blade](https://github.com/jenssegers/blade) package that allows you to use blade templates in your Leaf PHP projects.
+
+::: details New to Blade?
+
+This video by The Net Ninja will help you get started with blade.
+
+
+
+:::
+
+## Setting Up
+
+Blade comes with Leaf MVC out of the box, fully configured and ready to use. However, if you're using Leaf Core, you'll need to set up Blade yourself. Don't worry, it's pretty easy. All you need to do is install Blade, configure it to match your project's setup, and you're good to go.
+
+You can install Leaf Blade with the Leaf CLI:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install blade
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/blade
+```
+
+:::
+
+After this, you just need to inform Leaf of Blade's existence:
+
+```php
+app()->attachView(Leaf\Blade::class);
+```
+
+This will magically set up Blade for you and pop up a `blade()` function you can use to render your Blade views.
+
+```php
+app()->blade()->configure([
+ 'views' => 'views',
+ 'cache' => 'storage/cache'
+]);
+```
+
+Magic! You can now use Blade to create and render your views.
+
+## Creating Blade Views
+
+Blade views are a pretty sweet mixture of HTML, PHP, and clean syntax. You can create a new Blade view by creating a new file with the `.blade.php` extension in your "views" folder. Here's an example of a simple Blade view:
+
+::: code-group
+
+```blade [hello.blade.php]
+
+
+
+
+
+
+
Document
+
+
+
Hello, {{ $name }}
+
+
+```
+
+:::
+
+This should look pretty familiar if you know HTML (of course you do). The only difference is the `{{ $name }}` part. This is Blade's way of creating a variable in your view. When you render this view, Blade will allow you pass in a variable called `$name` and it will be displayed in place of `{{ $name }}`. Let's see how you can render this view.
+
+## Rendering Blade Views
+
+Remember we set up Blade earlier? Now we can use it to render our Blade views. Here's how you can render the `hello.blade.php` view we created earlier:
+
+```php
+echo app()->blade()->render('hello', ['name' => 'Michael']);
+```
+
+This will render the `hello.blade.php` view and pass in a variable called `name` with the value `Michael`. When you open the view in your browser, you should see a big "Hello, Michael" on your screen.
+
+## Extending Blade Views
+
+Blade allows you to define custom directives using the `directive()` method. When the Blade compiler encounters the custom directive, it will call the provided callback with the expression that the directive contains. The callback is free to return the value of its contents however you like:
+
+```php
+app()->blade()->directive('datetime', function ($expression) {
+ return "format('F d, Y g:i a'); ?>";
+});
+```
+
+Which allows you to use the following in your blade template:
+
+```html
+Current date: @datetime($date)
+```
+
+This will output the current date in the format `F d, Y g:i a`. You can define as many custom directives as you want to make your Blade views more powerful.
+
+## Conclusion
+
+This is just the beginning of what you can do with Blade. Blade is a powerful templating engine that allows you to create dynamic views with ease. You can use Blade to create complex views with loops, conditions, and even include other views. As this is just an adapter for the original Blade package, you can check out the [Blade documentation](https://laravel.com/docs/8.x/blade) for more information on what you can do with Blade.
diff --git a/src/docs/frontend/index.md b/src/docs/frontend/index.md
new file mode 100644
index 00000000..c41dffef
--- /dev/null
+++ b/src/docs/frontend/index.md
@@ -0,0 +1,41 @@
+# Frontend
+
+
+
+Both Leaf and Leaf MVC offer first-class support for frontend tooling and libraries. This includes support for different templating engines, CSS preprocessors, and JavaScript libraries.
+
+## Templating Engines
+
+Leaf is modular and allows you to use any templating engine you want, however, it comes with 2 first-class templating engines:
+
+- Leaf's BareUI engine
+- Laravel's Blade engine
+
+While both of these engines are great, they both have their own strengths and weaknesses. Leaf's BareUI engine is a simple, lightweight, and fast engine but it's not as feature-rich as Blade. Blade, on the other hand, is a feature-rich engine with a lot of features but it's not as fast as BareUI since it has to compile and cache views.
+
+BareUI relies on PHP's innate templating capabilities so it's syntax is PHP's syntax. Blade, on the other hand, has its own syntax using `@` directives. They are both great engines and the choice of which to use is up to you.
+
+| Engine | Speed | Cool Magic | Lightweight | Editor Support |
+| -------------------------------- | :-----: | :----------: | :-----------: | :------------: |
+| [bareui](/docs/frontend/bareui) | ⚡️ | ❌ | ⚡️ | ⚡️ |
+| [blade](/docs/frontend/blade) | ❌ | ⚡️ | ❌ | ⚡️ |
+
+## Asset Bundling
+
+Leaf provides first-class support for asset bundling using [Vite](https://vite.dev/). Vite is a modern build tool for frontend applications which aims to provide a faster and leaner development experience for modern web projects. Vite and Leaf make the perfect pair for building modern web applications since they are both fast and lightweight.
+
+
+
+Bundling assets allows you to write your frontend code in a modular way and then bundle it into a single file for production. This makes your frontend code more maintainable and easier to work with. Vite also allows you to use modern JavaScript features like ES6 modules, JSX, and even TypeScript.
+
+The Vite + Leaf stack unlocks a lot of possibilities for building modern web applications with Leaf and your favorite frontend tooling. You can find the full documentation on the [Vite module page](/docs/frontend/vite)
+
+## Frontend Frameworks
+
+Modern web apps are built on the backs of powerful UI libraries like React, Vue, and Svelte. Leaf provides an easy way to integrate these libraries into your Leaf applications using [Inertia.js](https://inertiajs.com/).
+
+
+
+Inertia acts as a bridge between your Leaf backend and your frontend UI library that allows them to communicate seamlessly. This allows you to build modern web applications with Leaf and your favorite frontend library without much of the complexity that comes with modern SPAs.
+
+You can find the full documentation on the [Inertia module page](/docs/frontend/inertia)
diff --git a/src/modules/views/inertia/index.md b/src/docs/frontend/inertia.md
similarity index 60%
rename from src/modules/views/inertia/index.md
rename to src/docs/frontend/inertia.md
index 02d7aa35..f1e343c1 100644
--- a/src/modules/views/inertia/index.md
+++ b/src/docs/frontend/inertia.md
@@ -1,28 +1,31 @@
-# Inertia JS
+# Inertia + Leaf
-[Inertia](https://inertiajs.com/) is a new approach to building classic server-driven web apps. It allows you to create fully client-side rendered, single-page apps, without the complexity that comes with modern SPAs. It does this by leveraging existing server-side patterns that you already love.
+[Inertia](https://inertiajs.com/) is a new approach to building classic server-driven web apps. It allows you to create fully client-side rendered, single-page apps, without the complexity that comes with modern SPAs.
-## Usage with Leaf MVC
+In short, Inertia let's you use your favourite frontend framework together with Leaf, reaping the benefits of both. While it's still more popular to build completely separate frontend and backends, combining them lets you have your code in one place.
-Leaf MVC and Leaf API come with built-in support for Inertia.js. This means you can build amazing frontend applications using Inertia.js and Leaf right out of the box without any extra configuration.
+## Setting Up
-Leaf CLI comes with a `view:install` command to help you get on your way as fast as possible. Since inertia provides support for a variety of frontend frameworks, this command will help you install and setup inertia for your preferred frontend framework.
+We've simplified the whole setup process into one command for you. Whether you are using Leaf MVC or just Leaf, you can use the CLI to scaffold a basic UI integration using your preferred frontend tooling.
-To get started, run:
+To get started, you can run:
-```bash
-php leaf view:install
-```
-
-Or with the Leaf CLI:
+::: code-group
-```bash
+```bash:no-line-numbers [Leaf CLI]
leaf view:install
```
+```bash:no-line-numbers [Leaf MVC CLI]
+php leaf view:install
+```
+
+:::
+
This will prompt you to select your preferred frontend framework. You can choose from Vue, React, and Svelte. There is also support for styling with Tailwind/Bootstrap. After selecting your preferred framework, Leaf will automatically install and setup inertia for you, including examples for you to get started with.
::: tip view:install
+
If you know the specific frontend framework you want to use, you can pass the `--{framework}` flag to the `view:install` command. For example, to install inertia for Vue, you can run:
```bash
@@ -31,89 +34,141 @@ php leaf view:install --vue
:::
-To run your app, you should start the server for both your frontend and backend. To start the backend server, run:
+To run your app, you'll need to start two servers. One to actively bundle your frontend dependencies (your framework, styles, ...):
-```bash
-php leaf serve
+::: code-group
-# or with the Leaf CLI
+```bash:no-line-numbers [Leaf CLI]
+leaf view:dev
+```
-leaf serve
+```bash:no-line-numbers [npm]
+npm i && npm run dev
```
-To start the frontend server, run:
+```bash:no-line-numbers [pnpm]
+pnpm i && pnpm run dev
+```
-```bash
-npm run dev
+```bash:no-line-numbers [yarn]
+yarn && yarn dev
+```
-# or with the Leaf CLI
+:::
-php leaf view:dev
-leaf view:dev
-```
+And then your main Leaf server which will run your app:
-## Usage with Leaf Core
+::: code-group
-Inertia has been fine-tuned to work with Leaf MVC and Leaf API. However, you can still use inertia with Leaf Core, however, you'll need to install and setup inertia yourself. There are 2 ways to do this:
+```bash:no-line-numbers [Leaf CLI]
+leaf serve
+```
-- [Using the Leaf CLI](#using-the-leaf-cli)
-- [Manually setting up inertia](#manually-setting-up-inertia)
+```bash:no-line-numbers [Leaf MVC CLI]
+php leaf serve
+```
-::: tip This guide
-This guide also applies to using Inertia outside of Leaf applications. You can use this guide to setup inertia for any PHP application.
:::
-### Using the Leaf CLI
+If you want to read more on why 2 servers are necessary, you can check out the [Leaf + Vite documentation](/docs/frontend/vite#vite-other-frameworks)
-The Leaf CLI comes with a `view:install` command to help you get on your way as fast as possible. Since inertia provides support for a variety of frontend frameworks, this command will help you install and setup inertia for your preferred frontend framework.
+## Setting up your routes
-To get started, run:
+Adding Inertia to your Leaf app doesn't change the way you handle routing, it just replaces your PHP views with your frontend framework. This means you are still going to use Leaf's routing system to handle your routes:
-```bash
-leaf view:install
+```php
+app()->get('/', function () {
+ echo 'This is a route';
+});
```
-This will prompt you to select your preferred frontend framework. You can choose from Vue, React, and Svelte. There is also support for styling with Tailwind/Bootstrap. After selecting your preferred framework, Leaf will automatically install and setup inertia for you, including examples for you to get started with.
-
-::: tip view:install
-If you know the specific frontend framework you want to use, you can pass the `--{framework}` flag to the `view:install` command. For example, to install inertia for Vue, you can run:
+The only difference is that you need to return an Inertia response instead of a normal response. You can do this by using the `Inertia::render` method:
-```bash
-leaf view:install --vue
+```php
+app()->get('/', function () {
+ Inertia::render('Home');
+});
```
-:::
+The `Home` argument is the name of the file you created in your components directory.
-Using this will install and setup Vite and inertia for you, however, depending on your own setup, you might need to make some changes to the setup. For example, you might need to change the entry-point for Vite. You can do this by changing the `input` option in your vite config file.
+## Passing data to your Views
-```js
-leaf({
- input: ['js/app.jsx'],
- ...
-}),
+You can also pass data from your Leaf app to your frontend framework by passing an array as the second argument to the `Inertia::render` method:
+
+```php
+app()->get('/', function () {
+ return Inertia::render('Home', [
+ 'name' => 'Leaf',
+ ]);
+});
```
-Read more about setting up Vite [here](/modules/views/vite/#vite-config).
+If you have used any templating engine before, this should look really familiar to you.
-To run your app, you should start the server for both your frontend and backend. To start the backend server, run:
+For this example, we're passing a `name` variable to our frontend framework which we can access in our frontend framework as props. You can then access the `name` prop like this:
-```bash
-leaf serve
+::: code-group
+
+```jsx [React]
+import Layout from './Layout';
+import { Head } from '@inertiajs/react';
+
+export default function Home({ name }) {
+ return (
+
+
+
Welcome
+
Hello {name}, welcome to your first Inertia app!
+
+ );
+}
```
-To start the frontend server, run:
+```jsx [Home.vue]
+
+
+
+
+
+ Welcome
+ Hello {{ name }}, welcome to your first Inertia app!
+
+
+```
-```bash
-npm run dev
+```svelte [Home.svelte]
+
+
+
+
+ Welcome
+
+ Welcome
+ Hello {name}, welcome to your first Inertia app!
+
```
-### Manually setting up inertia
+:::
+
+You can find more information on using Inertia with your frontend framework in the [Inertia documentation](https://inertiajs.com/).
+
+## Manually setting up inertia
If you don't want to use the Leaf CLI, you can manually setup inertia. This guide will show you how to setup inertia with Vite and React. You can use this guide to setup inertia with any frontend framework.
### Setting up Vite
-To get started, you need to setup Vite. We have a Leaf plugin that takes care of a lot of the heavy lifting for you. We have a detailed guide on how to setup vite with Leaf [here](/modules/views/vite/#usage-with-leaf-core).
+To get started, you need to setup Vite. We have a Leaf plugin that takes care of a lot of the heavy lifting for you. We have a detailed guide on how to setup vite with Leaf [here](/docs/frontend/vite).
```bash
npm i -D vite @leafphp/vite-plugin
@@ -122,7 +177,7 @@ leaf install vite
### Vite Config
-The [Leaf Vite docs](/modules/views/vite/#vite-config) have a detailed guide on how to setup vite config files. You should however note that for the best developer experience, you should point Vite to your view directory so you can enjoy hot module reloading.
+The [Leaf Vite docs](/docs/frontend/vite#vite-config) have a detailed guide on how to setup vite config files. You should however note that for the best developer experience, you should point Vite to your view directory so you can enjoy hot module reloading.
```js
...
@@ -225,7 +280,7 @@ You should create a base PHP file that will be used to render your app. By defau
Inertia::setRoot('myfiles/_base');
```
-Since the Leaf Inertia PHP adapter is built using the [Bare UI engine](/modules/views/bareui/), your base file needs to maintain the `.view.php` extension. For example, if you're using React, your base PHP file should look like this:
+Since the Leaf Inertia PHP adapter is built using the [Bare UI engine](/docs/frontend/bareui), your base file needs to maintain the `.view.php` extension. For example, if you're using React, your base PHP file should look like this:
```php
@@ -288,45 +343,3 @@ const Home = () => {
export default Home;
```
-
-## Setting up your routes
-
-Your routing does not change when using Inertia. You can use the same routing you use for your backend. For example, if you're using Leaf, define your routes the same way:
-
-```php
-app()->get('/', function () {
- echo 'This is a route';
-});
-```
-
-The only difference is that you need to return an Inertia response instead of a normal response. You can do this by using the `Inertia::render` method:
-
-```php
-app()->get('/', function () {
- Inertia::render('Home');
-});
-```
-
-The `Home` argument is the name of the file you created in `./DIRECTORYFORCOMPONENTS/`. You can also pass data to your frontend framework by passing an array as the second argument to the `Inertia::render` method:
-
-```php
-app()->get('/', function () {
- return Inertia::render('Home', [
- 'name' => 'Leaf',
- ]);
-});
-```
-
-You can then access this data in your frontend framework as props. For example, if you're using React, you can access the `name` prop like this:
-
-```jsx
-const Home = ({ name }) => {
- return (
-
-
Hello {name}
-
- );
-};
-
-export default Home;
-```
diff --git a/src/docs/frontend/tailwind.md b/src/docs/frontend/tailwind.md
new file mode 100644
index 00000000..5b25a139
--- /dev/null
+++ b/src/docs/frontend/tailwind.md
@@ -0,0 +1,108 @@
+# Tailwind + Leaf
+
+Tailwind is a utility-first CSS framework that provides a set of utility classes to help you build your UI. Leaf has first-class support for Tailwind CSS, and it's the recommended way to style your Inertia apps. This guide will show you how to set up Tailwind CSS in your Leaf project with minimal configuration.
+
+## Using the CLI
+
+You can set up Tailwind CSS in your Leaf project using the Leaf CLI. To do this, run the following command:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf view:install --tailwind
+```
+
+```bash:no-line-numbers [Leaf MVC CLI]
+php leaf view:install --tailwind
+```
+
+:::
+
+This command will install Tailwind CSS and its dependencies, create a Tailwind configuration file, and set up your CSS file to import Tailwind CSS. It will also add your CSS file to Vite as an entry point.
+
+## Using Tailwind
+
+Once setup, Leaf will include all the Tailwind imports which means you can jump into your UI and start writing your components with Tailwind. It also includes the tailwind config in the root of your application. This allows you to define all the configuration for your project if it does not match what Leaf has generated for you.
+
+You can then go ahead to test out that your Tailwind install works fine:
+
+```html
+
+
Welcome to Tailwind
+
Leaf is amazing!
+
+```
+
+## Manual Installation
+
+Leaf MVC comes with Vite out of the box, which is a modern build tool that supports Tailwind CSS out of the box. To get started, you need to install Tailwind CSS and its dependencies:
+
+```bash:no-line-numbers
+npm install tailwindcss@latest postcss@latest autoprefixer@latest
+```
+
+Next, you need to create a Tailwind configuration file. You can do this by running the following command:
+
+```bash:no-line-numbers
+npx tailwindcss init
+```
+
+This will create a `tailwind.config.js` file in the root of your project. You can customize this file to suit your needs.
+
+Next, you need to create a PostCSS configuration file. You can do this by running the following command:
+
+```bash:no-line-numbers
+touch postcss.config.js
+```
+
+Add the following code to your `postcss.config.js` file:
+
+```javascript
+module.exports = {
+ plugins: {
+ tailwindcss: {},
+ autoprefixer: {},
+ },
+}
+```
+
+Next, you need to create a CSS file that imports Tailwind CSS. You can do this by running the following command:
+
+```bash:no-line-numbers
+touch app/views/css/app.css
+```
+
+Add the following code to your `app/views/css/app.css` file:
+
+```css
+@tailwind base;
+@tailwind components;
+@tailwind utilities;
+```
+
+Next, you need to add your CSS file to vite as an entry point. You can do this by adding the following code to your `vite.config.js` file:
+
+```javascript
+defineConfig({
+```
+
+The final step is to import your CSS file in your root layout file so that it gets included in your HTML.
+
+```blade{7}
+
+
+
+
+
+
Leaf
+ {{ vite('css/app.css') }}
+ ...
+```
+
+That's it! You now have Tailwind CSS set up in your Leaf project. You can start using Tailwind utility classes in your views to style your UI.
+
+Be sure to start your vite server by running:
+
+```bash:no-line-numbers
+npm run dev
+```
diff --git a/src/docs/frontend/third-party.md b/src/docs/frontend/third-party.md
new file mode 100644
index 00000000..ccc4411b
--- /dev/null
+++ b/src/docs/frontend/third-party.md
@@ -0,0 +1,106 @@
+# Using third-party Engines
+
+Leaf provides first-class support for [BareUI](/docs/frontend/bareui) and [Blade](/docs/frontend/blade). However, you can use any template engine you want with the framework. In this section, we will show you how to use the [Smarty](https://www.smarty.net/) template engine with Leaf.
+
+## Install your engine
+
+To install Smarty, run the following command in your terminal:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install smarty/smarty
+```
+
+```bash:no-line-numbers [Composer]
+composer require smarty/smarty
+```
+
+:::
+
+Once installed, you need to tell Leaf about your engine. Leaf will try to cache your engine for future use. You can do this using the `attachView()` method on the app instance:
+
+```php
+app()->attachView(Smarty::class);
+```
+
+This will attach your engine to Leaf and make it available in your app directly from the app instance. Here's how you can use it with our Smarty example:
+
+```php
+app()->smarty()->setTemplateDir('/some/template/dir');
+app()->smarty()->setConfigDir('/some/config/dir');
+app()->smarty()->setCompileDir('/some/compile/dir');
+app()->smarty()->setCacheDir('/some/cache/dir');
+```
+
+This will configure your engine, basically telling it where to look for templates, configs, compiled files, and cache files. You can now use your engine to render your views:
+
+```php
+app()->smarty()->assign('name', 'Michael');
+app()->smarty()->display('index.tpl');
+```
+
+That's it! Pretty simple, right? You can follow this same pattern to use any other template engine with Leaf.
+
+## Using with Leaf MVC
+
+Unlike Leaf Core, Leaf MVC comes with a view manager that makes Leaf aware of any template engine you want to use. This gives you pretty handy functions like the global `view()` function. To make our Smarty engine available in Leaf MVC, we need to let Leaf know about it and also let Leaf MVC know it's supposed to use it when you call the global `view()` function.
+
+The first step is to head over to your `public/index.php` file and attach Smarty to Leaf:
+
+```php
+app()->attachView(Smarty::class);
+```
+
+This will immediately make Smarty available in Leaf, but there's one more thing we need to do. We need to let Leaf MVC know that Smarty is the engine we want to use. We can do this by setting the `engine` key in the `config/view.php` file:
+
+```php
+ Smarty::class,
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom config method
+ |--------------------------------------------------------------------------
+ |
+ | Configuration for your templating engine.
+ |
+ */
+ 'config' => function ($config) {
+ app()->smarty()->setTemplateDir($config['views']);
+ app()->smarty()->setConfigDir('/some/config/dir');
+ app()->smarty()->setCompileDir('/some/compile/dir');
+ app()->smarty()->setCacheDir($config['cache']);
+ },
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom render method
+ |--------------------------------------------------------------------------
+ |
+ | This render method is triggered whenever render() is called
+ | in your app if you're using a custom view engine.
+ |
+ */
+ 'render' => function ($view, $data) {
+ foreach ($data as $key => $value) {
+ app()->smarty()->assign($key, $value);
+ }
+
+ app()->smarty()->display($view);
+ }),
+];
+```
diff --git a/src/docs/frontend/viewi.md b/src/docs/frontend/viewi.md
new file mode 100644
index 00000000..8742acc3
--- /dev/null
+++ b/src/docs/frontend/viewi.md
@@ -0,0 +1 @@
+# Viewi + Leaf
diff --git a/src/docs/frontend/vite.md b/src/docs/frontend/vite.md
new file mode 100644
index 00000000..7b7ac8a0
--- /dev/null
+++ b/src/docs/frontend/vite.md
@@ -0,0 +1,178 @@
+# Vite + Leaf
+
+
+
+Vite is a modern build tool for frontend applications. It aims to provide a faster and leaner development experience for modern web projects.
+
+Leaf provides a Vite integration which you can use to seamlessly bundle your CSS and JS assets. This allows you to have more complex frontend setups without the need for extra configuration.
+
+::: details New to bundling?
+
+Check out these articles from SitePoint and Next JS:
+
+- [JavaScript Modules: Bundling & Transpiling](https://www.sitepoint.com/javascript-modules-bundling-transpiling)
+
+- [How Next.js Works](https://nextjs.org/learn/foundations/how-nextjs-works/bundling)
+
+:::
+
+## Setting Up
+
+You can install the Vite module with the Leaf CLI:
+
+```bash:no-line-numbers
+leaf view:install --vite
+```
+
+This command will install vite and the vite-leaf plugin, and will also install the vite module which will be used to load your assets on the server side. It will also create a vite config file at the root of your project. This config file can be used to configure vite, add plugins and more.
+
+If you are using Leaf MVC, all of this is done for you automatically. You just need to start your Vite server and add your assets.
+
+## Manually Installing Vite
+
+If you don't have the Leaf CLI installed, you can manually install Vite although it's a bit more complex. First, you need to install all the JavaScript dependencies:
+
+::: code-group
+
+```bash:no-line-numbers [npm]
+npm i -D vite @leafphp/vite-plugin
+```
+
+```bash:no-line-numbers [pnpm]
+pnpm i -D vite @leafphp/vite-plugin
+```
+
+```bash:no-line-numbers [yarn]
+yarn add -D vite @leafphp/vite-plugin
+```
+
+:::
+
+After that, you need to install the server component for Vite. This will allow you to load your assets on the server side using PHP. You can install this by running:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install vite
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/vite
+```
+
+:::
+
+Finally, Vite requires a configuration file to run. You can create a `vite.config.js` file at the root of your project and add your configuration there. You can learn more about Vite configuration files [here](#vite-config).
+
+## Loading your assets
+
+Once you've installed Vite, you can start loading your assets using the the `vite()` helper function. This function takes in 2 parameters:
+
+- The path to your asset
+- The folder to load the asset from (optional, defaults to the assets path in leaf config or `app/views` if not set)
+
+Here's an example of how you can load a CSS file:
+
+```php
+
+```
+
+You can also load multiple assets at once by passing in an array of assets:
+
+```php
+
+```
+
+The `vite()` helper function will automatically load the correct assets depending on the environment. In development, it will load the assets from the vite server with Hot Module Replacement, while in production, it will load the assets from the build folder.
+
+## Vite Config
+
+Vite uses a `vite.config.js` file to configure your Vite setup. This file can be used to configure Vite, add plugins and more. Here's an example of a Vite config file:
+
+```js [vite.config.js]
+import { defineConfig } from 'vite';
+import leaf from '@leafphp/vite-plugin';
+
+export default defineConfig({
+ plugins: [
+ leaf({
+ input: [
+ 'path/to/entrypoint.css',
+ 'path/to/entrypoint.js'
+ ],
+ refresh: true
+ })
+ ]
+});
+```
+
+The Leaf Vite plugin requires an array of entry points for your application. These may be JavaScript or CSS files, and include preprocessed languages such as TypeScript, JSX, and Sass. You don't need to pass all your assets here, just the entry points.
+
+Besides the Vite config file, you can also configure the server component for Vite. With this, you can set a couple of defaults for your assets.
+
+```php
+\Leaf\Vite::config([
+ 'assets' => 'app/views',
+ 'build' => 'public/build'
+]);
+```
+
+Unlike the `vite.config.js` file, this configuration is done in PHP and is completely optional.
+
+Once again if you're using Leaf MVC or if you installed Vite using the `view:install` command, this is done for you automatically.
+
+## Running Vite
+
+Vite comes with a development server that you can use to serve your assets. This is true for the Leaf Vite integration as well. This is a bit different from the traditional way of serving assets with PHP because you need to run a separate server for your assets. You can start your Vite server by running:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf view:dev
+```
+
+```bash:no-line-numbers [npm]
+npm i && npm run dev
+```
+
+```bash:no-line-numbers [pnpm]
+pnpm i && pnpm run dev
+```
+
+```bash:no-line-numbers [yarn]
+yarn && yarn dev
+```
+
+:::
+
+This will install the necessary dependencies and start your Vite server. You don't need to do anything with the Vite server, just keep it running in the background and Leaf will take care of the rest.
+
+## Adding Aliases
+
+Vite allows you to set up aliases for your assets. This can be done by adding an `alias` key to your vite config. For example, to set up an alias for the `@` symbol, you can do:
+
+```js{14-18}
+import { defineConfig } from 'vite';
+import leaf from '@leafphp/vite-plugin';
+
+export default defineConfig({
+ plugins: [
+ leaf({
+ input: [
+ 'path/to/entrypoint.css',
+ 'path/to/entrypoint.js'
+ ],
+ refresh: true
+ })
+ ],
+ resolve: {
+ alias: {
+ '@': '/path/to/folder',
+ }
+ }
+});
+```
+
+## Vite + other frameworks
+
+Using a combination of Leaf and Vite, you can use React with your favourite frontend technologies like React, Vue and Svelte. We've added a guide to setting up frontend frameworks using Inertia [over here](/docs/frontend/inertia).
diff --git a/src/docs/http/caching.md b/src/docs/http/caching.md
new file mode 100644
index 00000000..aa5b8f2a
--- /dev/null
+++ b/src/docs/http/caching.md
@@ -0,0 +1,101 @@
+# Http Cache
+
+
+
+
+
+HTTP caching is a way to store copies of web resources (like images, CSS files, or API responses) so they can be quickly accessed later without re-downloading them from the server every time. This speeds up loading times of your application and reduces the load on servers.
+
+Leaf provides a clean interface for caching resources and instructing the client on how to cache them.
+
+::: details New to HTTP Caching?
+
+This video by @roadmapsh will help you understand everything you need to know about HTTP Caching and Cache-Control headers.
+
+
+
+:::
+
+This documentation is a bit more technical and assumes you have a basic understanding of HTTP caching. If you're new to caching, you can watch the video above or [read this article](https://www.keycdn.com/blog/http-cache-headers) to get a better understanding.
+
+## etag
+
+An ETag is a unique identifier for a resource URI. After setting the Etag headers, the HTTP client will send an `If-None-Match` header with each subsequent HTTP request of the same resource URI. If the ETag value for the resource URI matches the `If-None-Match` HTTP request header, GET and HEAD requests will return a `304 Not Modified` HTTP response while all others return a `421 Precondition Failed` that will prompt the HTTP client to continue using its cache; this also prevents Leaf from serving the entire markup for the resource URI, saving bandwidth and response time.
+
+Setting an ETag with Leaf is very simple. Invoke Leaf’s etag method in your route callback, passing it a unique ID as the first and only argument.
+
+```php
+use Leaf\Http\Cache;
+
+app()->get('/', function () {
+ Cache::etag('unique-tag');
+
+ echo 'This will be cached after the initial request!';
+});
+```
+
+That’s it. Make sure the ETag ID is unique for the given resource. Also make sure the ETag ID changes as your resource changes; otherwise, the HTTP client will continue serving its outdated cache.
+
+## expires
+
+Used in conjunction with the Leaf application’s etag or lastModified methods, the expires method sets an Expires header on the HTTP response informing the HTTP client when its client-side cache for the current resource should be considered stale. The HTTP client will continue serving from its client-side cache until the expiration date is reached, at which time the HTTP client will send a conditional GET request to the Leaf application.
+
+The expires method accepts one argument: an integer UNIX timestamp, or a string to be parsed with `strtotime()`.
+
+```php
+use Leaf\Http\Cache;
+
+app()->get('/', function () {
+ Cache::etag('unique-tag');
+ Cache::expires('+1 week');
+
+ echo 'This will be cached client-side for one week';
+});
+```
+
+## lastModified
+
+A Leaf provides built-in support for HTTP caching using the resource’s last modified date. When you specify a last modified date, Leaf tells the HTTP client the date and time the current resource was last modified. The HTTP client will then send a If-Modified-Since header with each subsequent HTTP request for the given resource URI. If the last modification date you specify matches the If-Modified-Since HTTP request header, the Leaf will return a 304 Not Modified HTTP response that will prompt the HTTP client to use its cache; this also prevents the Leaf from serving the entire markup for the resource URI saving bandwidth and response time.
+
+Setting a last modified date with Leaf is very simple. You only need to invoke the Leaf’s lastModified() method in your route callback passing in a UNIX timestamp of the last modification date for the given resource. Be sure the lastModified() method’s timestamp updates along with the resource’s last modification date; otherwise, the browser client will continue serving its outdated cache.
+
+```php
+use Leaf\Http\Cache;
+
+app()->get('/', function () {
+ Cache::lastModified(1617383991);
+
+ echo 'This will be cached after the initial request!';
+});
+```
+
+## Other Headers
+
+There are other cache-related headers that Leaf doesn't provide direct methods for. You can set these headers directly using Leaf's Headers::set() method.
+
+```php
+use Leaf\Http\Headers;
+
+app()->get('/', function () {
+ Headers::set('Cache-Control', 'public, max-age=3600');
+
+ echo 'This will be cached for 1 hour';
+});
+```
+
+## Watch out
+
+There are a few things to keep in mind when using these methods:
+
+- It is best to use one of `etag()` or `lastModified()` - in conjunction with `expires()` - per route; never use both `etag()` and `lastModified()` together in the same route callback.
+
+- The `etag()` and `lastModified()` methods should be invoked in a route callback before other code; this allows Leaf to check conditional GET requests before processing the route callback’s remaining code.
+
+- Both `etag()` and `lastModified()` instruct the HTTP client to store the resource response in a client-side cache. The `expires()` method indicates to the HTTP client when the client-side cache should be considered stale.
diff --git a/src/docs/http/cookies.md b/src/docs/http/cookies.md
new file mode 100644
index 00000000..f828aba8
--- /dev/null
+++ b/src/docs/http/cookies.md
@@ -0,0 +1,114 @@
+# Cookies
+
+Cookies are small pieces of text sent to a client's browser by your application. They help your app remember information about users' visits, which can both make it easier to visit your app and make it more useful to your users.
+
+Leaf provides a lightweight cookie module that helps you create, delete, and interact with cookies.
+
+## Getting Started
+
+You can install Leaf's cookie module using composer or the Leaf CLI.
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install cookie
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/cookie
+```
+
+:::
+
+## Setting Cookies
+
+Since cookies are sent to the client's browser as part of the response, Leaf provides a direct way to set cookies on your response. You can directly call `withCookie()` on your response object to set a cookie.
+
+```php
+response()->withCookie('name', 'Fullname');
+```
+
+Using this method, you can even chain multiple cookies together with your response like this:
+
+```php
+response()
+ ->withCookie('name', 'Fullname')
+ ->withCookie('age', 20)
+ ->json([
+ 'message' => 'Cookies set'
+ ]);
+```
+
+The `withCookie()` method takes in 3 parameters:
+
+- cookie name
+- cookie value
+- cookie expiration time (optional)
+
+## Setting Cookies with Options
+
+`response()->withCookie()` is a simple way to set cookies, but it only works for the most basic use cases. If you need a more powerful way to set cookies, you can use the `set()` method. It takes in 3 parameters:
+
+- cookie name
+- cookie value
+- cookie options
+
+```php
+cookie()->set('name', 'Fullname', [
+ 'expire' => time() + 3600,
+ 'path' => '/',
+ 'domain' => 'example.com',
+ 'secure' => true,
+ 'httponly' => true,
+ 'samesite' => 'None'
+]);
+```
+
+The `set()` method allows you to set cookies with more advanced options like expiration time, path, domain, secure, httponly, and samesite which are all optional.
+
+## Reading Cookies
+
+When you send cookies to the client, they are stored in your users' browser and automatically sent back to your app on every request. You can read these cookies using the `get()` method.
+
+```php
+$name = cookie()->get('name');
+```
+
+This method takes in the cookie name and returns the cookie value. If the cookie doesn't exist, it returns `null`.
+
+You can also get all cookies at once using the `all()` method.
+
+```php
+$cookies = cookie()->all();
+```
+
+This method returns an array of all cookies sent to your app. Be careful when using this method as it can return a lot of data.
+
+## Deleting Cookies
+
+Deleting cookies works by letting your user's browser know that the cookie should be deleted. Once this is done, the cookie is removed from the user's browser and won't be sent back to your app. You can delete cookies using either the `delete()` method or `withoutCookie()` on your response object.
+
+::: code-group
+
+```php [Response Object]
+response()->withoutCookie('name');
+
+// It is also chainable with your response
+response()
+ ->withoutCookie('name')
+ ->json([
+ 'message' => 'Cookie deleted'
+ ]);
+```
+
+```php [Cookie Object]
+cookie()->delete('name');
+```
+
+:::
+
+You may also choose to delete all your cookies, for instance if you detect an authentication or authorization breech in your application. You can do this using the `deleteAll()` method on Leaf cookies.
+
+```php
+cookie()->deteleAll();
+```
diff --git a/src/docs/http/cors.md b/src/docs/http/cors.md
new file mode 100644
index 00000000..15d2cf57
--- /dev/null
+++ b/src/docs/http/cors.md
@@ -0,0 +1,119 @@
+# Cors
+
+
+
+
+
+From Wikipedia, Cross-origin resource sharing (CORS) is a mechanism that allows restricted resources on a web page to be accessed from another domain outside the domain from which the first resource was served.
+
+::: details What is CORS?
+
+Cross-Origin Resource Sharing or CORS is a mechanism that allows browsers to request data from 3rd party URLs (or origins) and is a common pain point for web developers. Learn the basics of CORS in 100 seconds from Fireship.io.
+
+
+
+:::
+
+Since CORS is a common pain point for web developers, Leaf provides a first-party integration that takes care of all the heavy lifting for you.
+
+## Setting Up
+
+You can install the CORS module through the Leaf CLI or with composer.
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install cors
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/cors
+```
+
+:::
+
+## Enabling CORS
+
+After installing the cors module, Leaf automatically links it to your app, so it can be used directly on the Leaf instance as the `cors()` method.
+
+::: code-group
+
+```php [Functional Mode]
+app()->cors();
+
+// ... your app
+```
+
+```php [Class Mode]
+$app = new Leaf\App();
+$app->cors();
+
+// ... your app
+```
+
+:::
+
+This will allow all users from any website to access your app, even if they are on a website you didn't explicitly allow. If you want to restrict access to your app, you can pass in an array of options to the `cors()` method.
+
+```php
+app()->cors([
+ 'origin' => ['http://example.com', 'http://example.org'],
+ 'methods' => ['GET', 'POST'],
+]);
+```
+
+This will only allow users from `http://example.com` and `http://example.org` to access your app using the `GET` and `POST` methods. You can find a list of all available options below.
+
+If you want to allow access to all subdomains of a domain, you can use just the website domain as the origin without the `http://` or `https://`.
+
+```php
+app()->cors([
+ 'origin' => 'example.com',
+]);
+```
+
+This will allow `http://example.com`, `https://example.com`, `http://www.example.com`, and `https://some-subdomain.example.com` to access your app. Of course, you can also use a regular expression to match multiple domains. You can find a full list of options below.
+
+## Configuration Options
+
+The `cors()` method takes in an array of options. Here are the available options:
+
+- `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Possible values:
+ * `String` - set `origin` to a specific origin. For example if you set it to `"http://example.com"` only requests from "http://example.com" will be allowed.
+ * `RegExp` - set `origin` to a regular expression pattern which will be used to test the request origin. If it's a match, the request origin will be reflected. For example the pattern `/example\.com$/` will reflect any request that is coming from an origin ending with "example.com".
+ * `Array` - set `origin` to an array of valid origins. Each origin can be a `String` or a `RegExp`. For example `["http://example1.com", /\.example2\.com$/]` will accept any request from "http://example1.com" or from a subdomain of "example2.com".
+ * `Function` - set `origin` to a function implementing some custom logic. The function takes the request origin as the first parameter and a callback (called as `callback(err, origin)`, where `origin` is a non-function value of the `origin` option) as the second.
+
+- `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
+
+- `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
+
+- `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
+
+- `credentials`: Configures the **Access-Control-Allow-Credentials** CORS header. Set to `true` to pass the header, otherwise it is omitted.
+
+- `maxAge`: Configures the **Access-Control-Max-Age** CORS header. Set to an integer to pass the header, otherwise it is omitted.
+
+- `preflightContinue`: Pass the CORS preflight response to the next handler.
+
+- `optionsSuccessStatus`: Provides a status code to use for successful `OPTIONS` requests, since some legacy browsers (IE11, various SmartTVs) choke on `204`.
+
+The default configuration is the equivalent of:
+
+```json
+{
+ "origin": "*",
+ "methods": "GET,HEAD,PUT,PATCH,POST,DELETE",
+ "allowedHeaders": "*",
+ "exposedHeaders": "",
+ "credentials": false,
+ "maxAge": null,
+ "preflightContinue": false,
+ "optionsSuccessStatus": 204,
+}
+```
diff --git a/src/docs/http/flash.md b/src/docs/http/flash.md
new file mode 100644
index 00000000..9cc41a22
--- /dev/null
+++ b/src/docs/http/flash.md
@@ -0,0 +1,51 @@
+# Session Flash
+
+Session flash allows you to store data in the session for a single request. This is useful for scenarios like displaying a message after a form submission. Leaf provides a straightforward way to work with flash messages.
+
+## Adding a new flash
+
+You can set a new flash item using the `set()` method. It method accepts two arguments:
+
+- The item to flash
+- The key to save it under. The key is optional and defaults to `message`.
+
+```php
+flash()->set('This is my message');
+flash()->set('This is my message', 'info');
+```
+
+You are not limited to strings. You can flash different types of data:
+
+```php
+flash()->set($userObject);
+flash()->set($userArray);
+flash()->set($userString);
+flash()->set($userInt);
+```
+
+## Display a flash item
+
+To display a flash item, you can use the `display()` method. This method accepts the key of the item to get. If the key is not provided, it defaults to `message`.
+
+```php
+echo flash()->display();
+```
+
+If you set a flash item with a key, you can pass the key to the `display()` method to get the item.
+
+```php
+flash()->set('This is my message', 'info');
+...
+
+echo flash()->display('info');
+```
+
+The item will be removed from the session after it has been displayed.
+
+## Manually removing a flash item
+
+You may choose to remove a flash item manually using the `remove()` method. This method accepts the key of the item to remove.
+
+```php
+flash()->remove('info');
+```
diff --git a/src/docs/http/headers.md b/src/docs/http/headers.md
new file mode 100644
index 00000000..5c3eba65
--- /dev/null
+++ b/src/docs/http/headers.md
@@ -0,0 +1,189 @@
+# Headers
+
+Headers are a very important part of HTTP requests and responses. They contain information about the request/response, like the content type, the server, the date, and more.
+
+## Getting request headers
+
+You can get all headers from a request using the `all()` method on the headers object or the `headers()` method on the request object.
+
+::: code-group
+
+```php:no-line-numbers [Request Class]
+$allHeaders = request()->headers();
+```
+
+```php:no-line-numbers [Headers Class]
+$headers = Leaf\Http\Headers::all();
+```
+
+:::
+
+Note that all headers are automatically sanitized by default. If you want to get the raw headers, you can pass `false` as the first argument to the `all()` method.
+
+::: code-group
+
+```php:no-line-numbers [Request Class]
+$allHeaders = request()->headers(safeHeaders: false);
+```
+
+```php:no-line-numbers [Headers Class]
+$headers = Leaf\Http\Headers::all(false);
+```
+
+:::
+
+## Getting a single header
+
+You can also grab a single item from the headers using the `get()` method.
+
+::: code-group
+
+```php:no-line-numbers [Request Class]
+$contentType = request()->headers('Content-Type');
+```
+
+```php:no-line-numbers [Headers Class]
+$contentType = Leaf\Http\Headers::get('Content-Type');
+```
+
+:::
+
+These headers are automatically sanitized by default. If you want to get the raw headers, you can pass `false` as the second argument to the `get()` method.
+
+::: code-group
+
+```php:no-line-numbers [Request Class]
+$contentType = request()->headers('Content-Type', false);
+```
+
+```php:no-line-numbers [Headers Class]
+$contentType = Leaf\Http\Headers::get('Content-Type', false);
+```
+
+:::
+
+## Setting response headers
+
+The most straightforward way to set headers is to use the Leaf's response object. It has a `withHeader()` method that allows you to set headers.
+
+```php
+response()
+ ->withHeader('X-Custom-Header', 'value')
+ ->json([
+ 'message' => 'Hello, world!'
+ ]);
+```
+
+You can find the full documentation [here](/docs/http/response#headers).
+
+## Setting headers using the Headers class
+
+You can also set headers using the `Leaf\Http\Headers::set()` class. This method gives you finer control over the headers you set. It takes in 4 parameters:
+
+- The header to to set
+- Value for header (optional if you pass an array to the first parameter)
+- Replace similar header? (optional)
+- An http status code (optional)
+
+```php
+Leaf\Http\Headers::set('location', '/home', true, 302);
+
+// multiple headers
+Leaf\Http\Headers::set([
+ 'location' => '/home',
+ 'something' => 'here'
+]);
+```
+
+If you want multiple headers with the same name, you can set replace to `false`. This will force multiple headers of the same type.
+
+```php
+Leaf\Http\Headers::set(
+ [
+ 'location' => '/home',
+ 'location' => '/here'
+ ],
+ replace: false
+);
+```
+
+## Removing headers
+
+You can remove headers using the `Leaf\Http\Headers::remove()` method. This method takes in a single parameter, the header to remove.
+
+```php
+Leaf\Http\Headers::remove('WWW-Authenticate');
+
+// remove multiple headers
+Leaf\Http\Headers::remove(['WWW-Authenticate', 'Authorization']);
+```
+
+## Checking if a header exists
+
+You can check if a header exists using the `Leaf\Http\Headers::has()` method. This method takes in a single parameter, the header to check and returns a boolean.
+
+```php
+$exists = Leaf\Http\Headers::has('Content-Type');
+```
+
+## Utility Header methods
+
+Some shortcut methods have been prepared for the most used headers, so you won't need to stress yourself writing a bunch of stuff for simple tasks.
+
+### contentPlain
+
+This method set's the content type of the response to `text/plain`, it also takes in an HTTP status code.
+
+```php
+Leaf\Http\Headers::contentPlain(200);
+
+echo 'plain text here';
+```
+
+### contentHtml
+
+This method set's the content type of the response to `text/html`, it also takes in an HTTP status code.
+
+```php
+Leaf\Http\Headers::contentHtml(200);
+
+echo 'html here';
+```
+
+### contentXml
+
+This method set's the content type of the response to `application/xml`, it also takes in an HTTP status code.
+
+```php
+Leaf\Http\Headers::contentXml(200);
+
+echo 'Xml here';
+```
+
+### contentJSON
+
+This method set's the content type of the response to `application/json`, it also takes in an HTTP status code.
+
+```php
+Leaf\Http\Headers::contentJSON(200);
+
+echo 'json here';
+```
+
+### accessControl
+
+This method allows you to quickly set `Access-Control` headers in your app. It takes in 3 parameters:
+
+- The header to set
+- The value to set
+- A status code (optional)
+
+```php:no-line-numbers
+Leaf\Http\Headers::accessControl('Allow-Origin', 'https://example.com', 200);
+```
+
+You can set mutiple access control headers at once:
+
+```php:no-line-numbers
+Leaf\Http\Headers::accessControl(['Allow-Origin' => '*', 'Allow-Headers' => '*']);
+```
diff --git a/src/docs/http/request.md b/src/docs/http/request.md
new file mode 100644
index 00000000..f2e2afc4
--- /dev/null
+++ b/src/docs/http/request.md
@@ -0,0 +1,412 @@
+# Requests
+
+Whenever a user accesses your application, a request is made from the user's machine to your application. This request contains information about the user, the user's system, and what the user is trying to access.
+
+A request looks something like this:
+
+```http:no-line-numbers
+GET /route?name=John&age=25 HTTP/1.1
+Host: example.com
+User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36
+```
+
+PHP provides a couple of superglobals and methods that you can use to access this information, but they're a bit all over the place and can be hard to use. Leaf provides a unified interface to access this information in a more structured way no matter the type of request you're working with.
+
+This section covers the methods you'll most likely use in your everyday applications.
+
+## Getting request data
+
+As mentioned earlier, a request contains information about the user, whatever they're trying to access, and any additional data they're sending. The additional data is usually sent in the form of query parameters, form data, or JSON data and is normally used for things like search queries, form submissions, and API requests. Most of the time, you'll want to access this data to make decisions in your application.
+
+Leaf provides a `get()` method on the request object that you can use to access this data. The `get()` method takes a key as an argument and returns the value associated with that key. If the key doesn't exist, the method returns `null`.
+
+::: code-group
+
+```php [Functional Mode]
+$item = request()->get('item');
+```
+
+```php [Class Mode]
+use Leaf\Http\Request;
+
+...
+
+$item = Request::get('item');
+```
+
+```php [on Leaf instance]
+$app = new Leaf\App;
+
+...
+
+$item = $app->request()->get('item');
+```
+
+:::
+
+The `get()` method works for all types of request data, including query parameters, form data, files, and JSON data so there's no need to worry about the type of data you're working with. You can also get multiple values at once by passing an array of keys to the `get()` method. This is especially useful when you're working with form data or JSON data where users can send any random data they want. In such cases, you can use the `get()` method to get only the data you're interested in.
+
+```php
+$data = request()->get(['name', 'email']);
+
+// $data = ['name' => '...', 'email' => '...']
+```
+
+### Data Sanitization
+
+Leaf automatically sanitizes all data coming into your application. This means that you don't have to worry about users sending malicious data to your application since Leaf will automatically clean it up for you. This lets you focus on building your application without worrying about security. There are some cases where you might want to disable this behavior, such as when you're working with raw data or when you're building an API that needs to accept any kind of data. In such cases, you can disable data sanitization by passing `false` as a second parameter to the `get()` method.
+
+```php
+$data = request()->get('data', false);
+```
+
+::: error Watch out!
+Disabling data sanitization can expose your application to security vulnerabilities. Only disable data sanitization when you're sure that the data you're working with is safe.
+:::
+
+## Conditionally getting request data
+
+Sometimes you might want to get a value from the request only if it exists. You can use the `try()` method to do this. The `try()` method takes an array of keys as an argument and returns only the values that exist in the request.
+
+```php
+$data = request()->try(['name', 'email']);
+
+// $data = ['name' => '...']
+```
+
+In the example above, the `try()` method only returns the value of the `name` key since the `email` key doesn't exist in the request. Just as with the `get()` method, you can disable data sanitization by passing `false` as a second parameter to the `try()` method.
+
+```php
+$data = request()->try(['name', 'email'], false);
+```
+
+`try()` sees empty strings as existing values and will return them. If you want to get only non-empty values, you can pass `true` as a third parameter to the `try()` method.
+
+```php
+$data = request()->try(['name', 'email'], false, true);
+```
+
+## Getting request data with a default value
+
+There are many situations where you might want to make sure that a value exists in the request before using it, but also want to keep it an optional value for users. You can use the `getOrDefault()` method to do this. The `getOrDefault()` method takes a key and a default value as arguments and returns the value associated with the key if it exists, or the default value if it doesn't.
+
+```php
+$data = request()->getOrDefault('name', 'John Doe');
+```
+
+## Getting all request data
+
+You can use the `all()` method to get all the data in the request. It returns an array of all the data in the request.
+
+```php
+$data = request()->all();
+
+// $data = ['name' => '...', 'email' => '...']
+```
+
+Every time you call the `all()` method, Leaf will sanitize the data in the request. If you want to disable data sanitization, you can pass `false` as a parameter to the `all()` method.
+
+```php
+$data = request()->all(false);
+```
+
+## Request type specific methods
+
+We mentioned earlier that there are different types of HTTP requests, such as `GET`, `POST`, `PUT`, `DELETE`, and more. Leaf provides methods that you can use to access data specific to each type of request. We'll cover the most common ones here.
+
+### GET requests
+
+GET requests are the most common type of request and are used to access web pages, images, and other resources. Unlike other types of requests, GET requests send data in the URL as query parameters. You've probably seen URLs like `https://example.com/route?name=John&age=25`. In this case, the query parameters are `name` and `age`. We can get these query parameters using the `query()` method. It takes in 2 parameters:
+
+- The key of the query parameter
+- A default value to return if the query parameter doesn't exist (optional)
+
+```php
+$name = request()->query('name', 'John Doe');
+```
+
+### POST/PUT/PATCH requests
+
+These requests are used to handle form submissions, API requests, and other types of requests where users send data to your application. This data is usually sent in the form of form data or JSON data. You can use the `postData()` method to get this data. The `postData()` method takes in 2 parameters:
+
+- The key of the data
+- A default value to return if the data doesn't exist (optional)
+
+```php
+$name = request()->postData('name', 'John Doe');
+```
+
+You can also use `rawData()` to get the raw data sent if the request is an `AJAX`/`XMLHttpRequest` request.
+
+```php
+$data = request()->rawData('name', 'John Doe');
+```
+
+In Case of files, you can use the `files()` method to get the file data.
+
+```php
+$file = request()->files('file');
+```
+
+## Saving files from the request
+
+When a user uploads a file to your application, like a profile picture, you can save the file to your server for later use. In Leaf, there's an `upload()` on Leaf's request object that helps you easily manage file uploads. This method lets you move the file to the correct folder on your server, ensuring it's stored properly. It takes in 3 parameters:
+
+- The name of the file in the request
+- The directory to save the file to
+- Options to save the file with (optional)
+
+```php
+$uploadInfo = request()->upload('profile_pic', './uploads');
+```
+
+This requires the Leaf FS module. If you are not using Leaf MVC, you will have to install it manually:
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install fs
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/fs
+```
+
+:::
+
+If you want to save the file using a different name, you can pass in the name as the third parameter:
+
+```php
+$uploadInfo = request()->upload('profile_pic', './uploads', [
+ 'name' => 'new_name',
+ 'rename' => true
+]);
+```
+
+## Request Headers
+
+Headers are a very important part of HTTP requests. They contain information about the request that can be used to make decisions in your application. You can use the `headers()` method to get a specific header from the request.
+
+```php
+$allHeaders = request()->headers();
+```
+
+You can also use the `header()` method to get a specific header from the request.
+
+```php
+$contentType = request()->header('Content-Type');
+```
+
+One thing to note is that all headers are sanitized automatically by Leaf. If you want to disable this behavior, you can pass `false` as a parameter to the `headers()` or `header()` method.
+
+```php
+$allHeaders = request()->headers(
+ safeHeaders: false
+);
+
+$contentType = request()->header(
+ 'Content-Type',
+ false
+);
+```
+
+## Validating Request Data
+
+When building user-facing applications, there's no guarantee that users will always send the correct data to your application. In most cases, users will send incorrect data, either by mistake or on purpose. This can lead to errors in your application and can even expose your application to security vulnerabilities. To prevent this, you can use Leaf's built-in validation library to validate the data coming into your application. Let's see how it works:
+
+```php{2-6}
+app()->post('/example/register', function() {
+ $success = request()->validate([
+ 'name' => 'text',
+ 'email' => 'email',
+ 'password' => 'min:8',
+ ]);
+
+ if (!$success) {
+ $errors = request()->errors();
+ }
+});
+```
+
+In the example above, we're validating the data coming into our application. We're checking if the `name` field is a text, if the `email` field is a valid email, and if the `password` field is at least 8 characters long. If any of these validations fail, the `validate()` method will return `false` and you can get the errors using the `errors()` method. You can find the full list of validation rules [here](/docs/data/validation).
+
+## Request Object Methods
+
+The request object comes with other methods for doing things like interacting with the request headers, cookies, checking request types, and even user data. Here are some of the most common functionality you'll use:
+
+### `typeIs`
+
+This method allows you to check what method type a request uses.
+
+```php
+$isGetRequest = request()->typeIs('GET');
+$isPostRequest = request()->typeIs('post');
+$isDeleteRequest = request()->typeIs('Delete');
+
+if ($isGetRequest) response()->exit('GET method not allowed');
+```
+
+Here are some other functions you can use relating to the request method.
+
+```php
+/**
+ * What is the request method?
+ * @return string (e.g. GET, POST, PUT, DELETE)
+ */
+request()->getMethod();
+```
+
+### XHR
+
+When using a Javascript framework like MooTools or jQuery to execute an XMLHttpRequest, the XMLHttpRequest will usually be sent with a **`X-Requested-With`** HTTP header. The Leaf application will detect the HTTP request’s **`X-Requested-With`** header and flag the request as such. If for some reason an XMLHttpRequest cannot be sent with the **`X-Requested-With`** HTTP header, you can force the Leaf application to assume an HTTP request is an XMLHttpRequest by setting a GET, POST, or PUT parameter in the HTTP request named “isajax” with a truthy value.
+
+Use the request object’s `isAjax()` or `isXhr()` method to tell if the current request is an XHR/Ajax request:
+
+```php
+$isXHR = request()->isAjax();
+$isXHR = request()->isXhr();
+```
+
+### `isFormData`
+
+This method allows you to check if the request body contains parsed form data, or if the request is a form data request.
+
+```php:no-line-numbers
+$isXHR = request()->isFormData();
+```
+
+## Request Path, Host & Client
+
+This section contains methods which allow you to retrieve information about the request path, host and client.
+
+### Host
+
+Fetch the request’s host (e.g. “leafphp.dev”):
+
+```php:no-line-numbers
+$app->request()->getHost();
+```
+
+### Host with Port
+
+Fetch the request’s host with port (e.g. “leafphp.dev:80”):
+
+```php:no-line-numbers
+request()->getHostWithPort();
+```
+
+### Port
+
+Fetch the request’s port (e.g. 80):
+
+```php:no-line-numbers
+request()->getPort();
+```
+
+### Scheme
+
+Fetch the request’s scheme (e.g. “http” or “https”):
+
+```php:no-line-numbers
+request()->getScheme();
+```
+
+### Path
+
+Fetch the request’s path (root URI + resource URI):
+
+```php:no-line-numbers
+request()->getPath();
+```
+
+### URL
+
+Fetch the request’s URL (scheme + host [ + port if non-standard ]):
+
+```php:no-line-numbers
+request()->getUrl();
+```
+
+### IP Address
+
+Fetch the request’s IP address:
+
+```php:no-line-numbers
+request()->getIp();
+```
+
+### Referer
+
+Fetch the request’s referrer:
+
+```php:no-line-numbers
+request()->getReferrer();
+```
+
+### User Agent
+
+Fetch the request’s user agent string:
+
+```php:no-line-numbers
+request()->getUserAgent();
+```
+
+### Paths
+
+Every HTTP request received by a Leaf application will have a root URI and a resource URI.
+
+#### Root URI
+
+The root URI is the physical URL path of the directory in which the Leaf application is instantiated and run. If a Leaf application is instantiated in **index.php** within the top-most directory of the virtual host’s document root, the root URI will be an empty string. If a Leaf application is instantiated and run in **index.php** within a physical subdirectory of the virtual host’s document root, the root URI will be the path to that subdirectory with a leading slash and without a trailing slash.
+
+#### Resource URI
+
+The resource URI is the virtual URI path of an application resource. The resource URI will be matched to the Leaf application’s routes.
+
+Assume the Leaf application is installed in a physical subdirectory **/foo** beneath your virtual host’s document root. Also assume the full HTTP request URL (what you’d see in the browser location bar) is **/foo/books/1**. The root URI is /foo (the path to the physical directory in which the Leaf application is instantiated) and the resource URI is **/books/1** (the path to the application resource).
+
+You can get the HTTP request’s root URI and resource URI with the request object’s `getScriptName()` and `getPathInfo()` methods:
+
+## Content Type Methods
+
+The Leaf application’s request object provides several helper methods for inspecting the content type of the current HTTP request.
+
+### Content Type
+
+Fetch the request’s content type (e.g. “application/json;charset=utf-8”):
+
+```php:no-line-numbers
+request()->getContentType();
+```
+
+### Media Type
+
+Fetch the request’s media type (e.g. “application/json”):
+
+```php:no-line-numbers
+request()->getMediaType();
+```
+
+### Media Type Params
+
+Fetch the request’s media type parameters (e.g. [charset => “utf-8”]):
+
+```php:no-line-numbers
+request()->getMediaTypeParams();
+```
+
+### Content Charset
+
+Fetch the request’s content character set (e.g. “utf-8”):
+
+```php:no-line-numbers
+request()->getContentCharset();
+```
+
+### Content Length
+
+Fetch the request’s content length:
+
+```php:no-line-numbers
+request()->getContentLength();
+```
diff --git a/src/docs/http/response.md b/src/docs/http/response.md
new file mode 100644
index 00000000..3a380131
--- /dev/null
+++ b/src/docs/http/response.md
@@ -0,0 +1,348 @@
+# Response
+
+For each request a user makes to your leaf application, you will need to return some sort of output to the user. The output from your application is bundled together with a little bit more data and is sent all together to the user as a response.
+
+A response looks something like this:
+
+```http
+HTTP/1.1 200 OK
+Server: nginx/1.14.0 (Ubuntu)
+Content-Type: application/json; charset=UTF-8
+Content-Length: 27
+Connection: keep-alive
+
+{"message":"Hello, world!"}
+```
+
+In the above example, the response is a JSON object with a message key and a value of "Hello, world!". We can break down the response into the following parts:
+
+- Status Line: `HTTP/1.1 200 OK`
+- Headers: `Server: nginx/1.14.0 (Ubuntu)`, `Content-Type: application/json; charset=UTF-8`, `Content-Length: 27`, `Connection: keep-alive`
+- Body: `{"message":"Hello, world!"}`
+
+This is true for all responses. They all have a status line, headers, and a body. The status line tells the client if the request was successful or not. The headers provide additional information about the response. The body contains the actual data that the client requested.
+
+## Creating Responses
+
+Leaf provides a clean and straightforward API for creating responses. It allows you to create responses in a variety of formats, including JSON, XML, and plain text and also allows you to set the status code and headers.
+
+You can use the `response()` helper function to create responses in functional mode or use the `response()` method on the Leaf instance to access the response object in Leaf instance mode.
+
+::: code-group
+
+```php [Functional Mode]
+response()->json([
+ 'message' => 'Hello, world!'
+]);
+```
+
+```php [Leaf Instance]
+$app = new Leaf\App;
+
+...
+
+$app->response()->json([
+ 'message' => 'Hello, world!'
+]);
+```
+
+:::
+
+If you're wondering why we don't just use PHP's built-in `echo` function to output responses, it's mainly because Leaf takes care of all the little things you would have to deal with if you were to use `echo` directly. For example, Leaf sets the correct headers for you, so you don't have to worry about mistakenly setting the wrong headers.
+
+Also, Leaf's response object provides a clean and consistent API for creating responses, which makes it easier for you and other developers to understand and maintain your code.
+
+## Plain text responses
+
+Plain text responses can be created using the `text()` method. This method accepts 2 parameters:
+
+- a string as text to output
+- an optional status code (defaults to 200/OK)
+
+::: code-group
+
+```php [Functional Mode]
+response()->text('Hello, world!');
+```
+
+```php [Leaf Instance]
+$app->response()->text('Hello, world!');
+```
+
+:::
+
+## JSON responses
+
+JSON responses can be created using the `json()` method. This method accepts 3 parameters:
+
+- an array or object to be converted to JSON
+- an optional status code (defaults to 200/OK)
+- Option to show status code in response body (defaults to false)
+
+::: code-group
+
+```php [Functional Mode]
+response()->json([
+ 'message' => 'Hello, world!'
+]);
+```
+
+```php [Leaf Instance]
+$app->response()->json([
+ 'message' => 'Hello, world!'
+]);
+```
+
+:::
+
+If you choose to show the status code in the response body, the response will look like this:
+
+```json
+{
+ "data": {
+ "message": "Hello, world!"
+ }, // Your output goes under the data key
+ "status": {
+ "code": 200,
+ "message": "OK"
+ }
+}
+```
+
+## HTML responses
+
+HTML responses can be created using the `markup()` method. This method accepts 2 parameters:
+
+- a string as HTML to output
+- an optional status code (defaults to 200/OK)
+
+::: code-group
+
+```php [Functional Mode]
+response()->markup('
Hello, world! ');
+```
+
+```php [Leaf Instance]
+$app->response()->markup('
Hello, world! ');
+```
+
+:::
+
+If you have a full HTML/PHP file you want to output, you can use the `page()` method. This method accepts 2 parameters:
+
+- a string as the path to the file
+- an optional status code (defaults to 200/OK)
+
+::: code-group
+
+```php [Functional Mode]
+response()->page('path/to/file.html');
+```
+
+```php [Leaf Instance]
+$app->response()->page('path/to/file.html');
+```
+
+:::
+
+**Note that this only works for static files. If you want to output a dynamic file, you should consider using a templating engine instead.**
+
+## Error responses
+
+During production development, you most likely would not want to throw exceptions to the user. Instead, you would want to return a nice error message. Leaf provides a simple way to do this using the `exit()` method. This method outputs an error message and exits your application immediately so that nothing else is executed. It takes in 2 parameters:
+
+- the error message to output
+- an optional status code (defaults to 500/Internal Server Error)
+
+::: code-group
+
+```php [Functional Mode]
+response()->exit('An error occurred', 500);
+
+// code below won't run
+```
+
+```php [Leaf Instance]
+$app->response()->exit('An error occurred', 500);
+
+// code below won't run
+```
+
+:::
+
+If you pass a string as the first parameter, Leaf will automatically convert it to a markup response. If you pass an array, Leaf will automatically convert it to a JSON response.
+
+## Other response types
+
+These are the most common response types you will use in your application. However, Leaf provides a few more response types that you can use if you need them.
+
+### Redirect responses
+
+These responses are used to redirect the user to another URL. You can create a redirect response using the `redirect()` method. This method accepts 2 parameters:
+
+- the URL to redirect to
+- an optional status code (defaults to 301/Moved Permanently)
+
+::: code-group
+
+```php [Functional Mode]
+response()->redirect('https://example.com');
+```
+
+```php [Leaf Instance]
+$app->response()->redirect('https://example.com');
+```
+
+### File download responses
+
+It's not so unusual to want to send a file to the user for download. You can create a file download response using the `download()` method. This method accepts 3 parameters:
+
+- the path to the file to download
+- an optional filename for the file
+- an optional status code (defaults to 200/OK)
+
+::: code-group
+
+```php [Functional Mode]
+response()->download('path/to/file.pdf');
+
+response()->download('path/to/file.pdf', 'new-filename.pdf', 200);
+```
+
+```php [Leaf Instance]
+$app->response()->download('path/to/file.pdf');
+
+$app->response()->download('path/to/file.pdf', 'new-filename.pdf', 200);
+```
+
+:::
+
+### No content responses
+
+These responses are used when you don't want to return any content to the user. You can create a no content response using the `noContent()` method. It also automatically sets the status code to 204/No Content.
+
+::: code-group
+
+```php [Functional Mode]
+response()->noContent();
+```
+
+```php [Leaf Instance]
+$app->response()->noContent();
+```
+
+:::
+
+### XML responses
+
+XML responses can be created using the `xml()` method. This method accepts 2 parameters:
+
+- a string as XML to output
+- an optional status code (defaults to 200/OK)
+
+::: code-group
+
+```php [Functional Mode]
+response()->xml('
');
+```
+
+```php [Leaf Instance]
+$app->response()->xml('
');
+```
+
+:::
+
+## Headers
+
+Headers are a way for your server to send additional information along with your request. This information can be anything from the type of content you're sending back, to the status code of your response, to the type of server you're using.
+
+Leaf allows you to set headers for your response directly from the response object using the `withHeader()` method. It takes in 4 parameters:
+
+- The header name or an array of headers (key-value pairs)
+- The header value if header key is a string (optional if header key is an array)
+- A boolean on whether to replace the header if it's already set (optional)
+- An Http status code to associate to header. (optional)
+
+::: code-group
+
+```php [Functional Mode]
+response()->withHeader('Content-Type', 'application/json');
+response()->withHeader([
+ 'Content-Type' => 'application/json',
+ 'X-Custom-Header' => 'Custom Value'
+]);
+```
+
+```php [Leaf Instance]
+$app->response()->withHeader('Content-Type', 'application/json');
+$app->response()->withHeader([
+ 'Content-Type' => 'application/json',
+ 'X-Custom-Header' => 'Custom Value'
+]);
+```
+
+:::
+
+You won't need to set basic content headers yourself as Leaf does this for you. However, you can set custom headers if you need to. Since headers are set before the response is sent, you can chain `withHeader()` together with your main response methods like this:
+
+```php
+response()
+ ->withHeader('X-Custom-Header', 'value')
+ ->json([
+ 'message' => 'Hello, world!'
+ ]);
+```
+
+If you need more control over your headers, you can check out the [headers documentation](/docs/http/headers).
+
+## Cookies
+
+Cookies are small pieces of data that are stored on the client's computer by the web browser while browsing a website. Cookies were designed to be a reliable mechanism for websites to remember stateful information or to record the user's browsing activity.
+
+Leaf allows you to set cookies for your response using the `withCookie()` method. It takes in 3 parameters:
+
+- The name of the cookie
+- The value of cookie
+- When the cookie expires. Default: 7 days
+
+```php
+response()
+ ->withCookie('name', 'Michael', '1 day')
+ ->json('...');
+```
+
+### `withoutCookie()`
+
+This method allows you to remove existing cookies from your response. So you're basically returning a response without selected cookies.
+
+```php
+response()->withoutCookie('name')->json('...');
+
+// cookie array
+response()->withoutCookie(['name', 'something'])->json('...');
+```
+
+If you need more control over your cookies, you can check out the [cookies documentation](/docs/http/cookies).
+
+## Flash messages
+
+Flash messages are a way to keep a message around for a single request. They're helpful for displaying status messages like "Item deleted successfully" or "Your changes have been saved."
+
+Leaf allows you to set flash messages for your response using the `withFlash()` method. It takes in 2 parameters:
+
+- The name of the flash message
+- The value of the flash message
+
+```php
+response()->withFlash('message', 'something');
+```
+
+Just like the `withCookie()` method, you can chain the `withFlash()` method with your main response methods.
+
+```php
+response()
+ ->withFlash('message', 'something')
+ ->json('...');
+```
+
+You can check out the [flash messages documentation](/docs/http/flash) for more information on how to use flash messages.
diff --git a/src/docs/http/session.md b/src/docs/http/session.md
new file mode 100644
index 00000000..eff93d5c
--- /dev/null
+++ b/src/docs/http/session.md
@@ -0,0 +1,189 @@
+# Session
+
+Normally, when you visit a website, each time you click on something, the website treats it like a new visit. This is because HTTP is stateless. This means that the website doesn't remember anything about you and other users from one request to the next. This is where sessions come in.
+
+Sessions fix this problem by allowing the website to "remember" things about you, like if you're logged in or what's in your shopping cart.
+
+Leaf makes it easy to work with sessions by handling all the heavy lifting for you. You can easily set, get and delete session data with Leaf in a few lines of code.
+
+## Setting up
+
+To start using sessions in Leaf, you need to install the Leaf Session module. It contains tons of helper methods to make working with sessions easier.
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install session
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/session
+```
+
+:::
+
+Once this is done, you can start using sessions in your Leaf app.
+
+## Setting session data
+
+To set session data, you can use the `set()` method. This method takes two parameters:
+
+- The key to save the data under
+- The data to save
+
+```php
+session()->set('firstName', 'John');
+session()->set('user', [
+ 'name' => 'John Doe',
+ 'email' => 'john@example.com'
+]);
+```
+
+If you have multiple items to save, you can pass an array to the `set()` method.
+
+```php
+session()->set([
+ 'firstName' => 'John',
+ 'lastName' => 'Doe'
+]);
+```
+
+## Checking if a session key exists
+
+You can check if a session key exists using the `has()` method. It returns `true` if the key exists and `false` if it doesn't.
+
+```php
+session()->has('firstName');
+
+/// or
+
+if (session()->has('firstName')) {
+ echo 'First name exists';
+} else {
+ echo 'First name does not exist';
+}
+```
+
+
+
+## Getting session data
+
+To get session data, you can use the `get()` method. This method takes three parameters:
+
+- the key to get the data from
+- a default value to return if the key doesn't exist
+- a boolean to determine if the data should be sanitized (default is `true`)
+
+```php
+$firstName = session()->get('firstName');
+$firstName = session()->get('firstName', 'John');
+$firstName = session()->get('firstName', 'John', false);
+
+// PHP 8+
+$firstName = session()->get(param: 'firstName', sanitize: false);
+```
+
+You can also select multiple items by passing an array of keys to the `get()` method.
+
+```php
+$names = session()->get(['firstName', 'lastName']);
+
+$fistName = $names['firstName'];
+$lastName = $names['lastName'];
+```
+
+## Getting session data once
+
+There are situations where you want to get session data only once. You can use the `retrieve()` method to get session data once. After the data is retrieved, it is removed from the session so it returns `null` if you try to get it again.
+
+```php
+$firstName = session()->retrieve('firstName');
+
+// $firstName is 'John'
+
+$firstName = session()->retrieve('firstName');
+
+// $firstName is null
+```
+
+You can also pass a default value to the `retrieve()` method.
+
+```php
+$firstName = session()->retrieve('firstName', 'John');
+```
+
+::: tip Flash messages
+`retrieve()` is useful for basic implementations of flash messages, but for more advanced flash messages, you should use the `flash()` method. You can find more information about flash messages in the [Flash Messages](/docs/http/flash) section.
+:::
+
+## Getting all session data
+
+To get all session data, you can use the `all()` method. This method returns all session data as an array.
+
+```php
+$sessionData = session()->all();
+```
+
+## Deleting session data
+
+When you're done with session data, you can delete it using the `delete()` method. This method takes the key to delete as a parameter.
+
+```php
+session()->delete('firstName');
+```
+
+You can also delete multiple items by passing an array of keys to the `delete()` method.
+
+```php
+session()->delete(['firstName', 'lastName']);
+```
+
+## Clearing all session data
+
+There are situations where you want to delete all session data without stopping the session. In those cases, you can use the `clear()` method.
+
+```php
+session()->clear();
+```
+
+## Working with arrays
+
+The Session module has one last trick up its sleeve. It provides a cleaner way of working with arrays in the session without having to deal with multiple `get()` and `set()` calls.
+
+Let's say you have an array in the session like this:
+
+```php
+session()->set('user', [
+ 'name' => 'John Doe',
+ 'email' => 'john@example.com',
+]);
+```
+
+You can easily add a new item to the array using the same `set()` method:
+
+```php
+session()->set('user.location', 'Everywhere');
+```
+
+This will add a location key to the user array in the session. This saves you from having to get the user array, adding the location key, and setting it back to the session.
+
+It also works for the other methods like `get()`, `has()` and `delete()`.
+
+```php
+if (session()->has('user.username')) {
+ // do something
+}
+
+$location = session()->get('user.location');
+$email = session()->retrieve('user.email');
+
+session()->delete('user.location');
+```
diff --git a/src/docs/index.md b/src/docs/index.md
new file mode 100644
index 00000000..9aeb55dd
--- /dev/null
+++ b/src/docs/index.md
@@ -0,0 +1,269 @@
+# Hello there 👋
+
+
+
+
+
+Leaf is a slim and lightweight PHP framework focused on developer experience, usability, and high-performance code. It is a modern PHP framework built to be simple and elegant, yet extremely powerful.
+
+```php
+get('/', function () {
+ response()->json(['message' => 'Hello World!']);
+});
+
+app()->run();
+```
+
+Writing code should be simple and fun, and that's what Leaf is all about.
+
+## Why Leaf?
+
+PHP frameworks often come with a steep learning curve, performance overhead, and strict conventions, which can complicate maintenance and limit flexibility amongst other issues like bloat. Leaf addresses these challenges by offering a range of features designed to make web development easier and more enjoyable:
+
+- Leaf is beginner-friendly, enabling PHP newcomers to build powerful apps within minutes. All you need is basic PHP knowledge and, optionally, some backend web dev familiarity.
+
+- Leaf is lightweight and blazing fast with a minimal core and a load of optional modules for building full apps and APIs efficiently, offering high performance and low memory usage.
+
+- Leaf is built to enhance developer focus, offering features like class-free initializers and global functions for easy access to classes across your app, creating an optimized PHP developer experience.
+
+- Leaf is designed for seamless integration with other libraries and frameworks, prioritizing simplicity over complex setups like providers needed by other frameworks.
+
+- Leaf is highly scalable, and grows with your project. Its core and ecosystem of libraries make it ideal for projects of any size.
+
+
+
+## How to Use These Docs
+
+On the left side of the screen, you'll find the docs navbar. The pages of the docs are organized sequentially, from basic to advanced, so you can follow them step-by-step when building your application. However, you can read them in any order or skip to the pages that apply to your use case.
+
+On the right side of the screen, you'll see a table of contents that makes it easier to navigate between sections of a page. If you need to quickly find a page, you can use the search bar at the top, or the search shortcut (Ctrl+K or Cmd+K).
+
+To get started, check out the [Installation guide](/docs/installation).
+
+## Pre-Requisite Knowledge
+
+Although our docs are designed to be beginner-friendly, we need to establish a baseline so that the docs can stay focused on Leaf's functionality. We assume you have a basic understanding of PHP and it's syntax, as well as a little familiarity with web development concepts like HTTP, routing, and middleware.
+
+Don't worry if you're not familiar with these concepts, we'll provide videos and links to relevant documentation whenever we introduce a new concept like the one below:
+
+
+
+## Functions vs Class Mode
+
+Leaf is built with many classes and components, but for simpler apps or APIs, it also offers a functional mode. This lets you use Leaf and its modules without class imports, instantiation, or lengthy namespaces—keeping things simple and streamlined.
+
+Of course, you can still use Leaf in class mode if you prefer that. Here's an example of a simple Leaf app in functional mode:
+
+```php
+get('/', function () use ($app) {
+ $app->response()->json(['message' => 'Leaf is amazing!']);
+});
+
+$app->run();
+```
+
+The documentation will usually show you how to use modules in functional mode as this is the default mode for Leaf. However, if you are migrating from another framework or you prefer to use Leaf in class mode, you can always instantiate the classes and use them as you would in any other framework.
+
+## Getting Started
+
+Ready to get started? Check out the [installation guide](/docs/installation) to get Leaf up and running in no time. You can also check out the [interactive tutorial](/tutorial/) to learn more about Leaf's core concepts and features.
+
+
+
+ Hello Leaf 🍃
+ Let's get you up and running
+
+
+
+
+
+ Learning to walk 🚶
+ Learn the core concepts of Leaf
+
+
+
+
+
+ Pro walking now 🏃♂️
+ Beginner concepts that make you feel like pro
+
+
+
+
+
+## Config & Deployment
+
+
+
+ Configuring Leaf ⚙️
+ Setting up Leaf
+
+
+
+
+
+ Deployment 🚀
+ Deploying your Leaf app
+
+
+
+
+
+## Data Handling
+
+
+
+ Databases 🔐
+ Store and Retrieve data on the fly
+
+
+
+
+
+ Using Data 🗄️
+ Play around with data in your app
+
+
+
+
+
+ Validation 🛡️
+ Make sure your data isn't exploitable
+
+
+
+
+
+## Digging Deeper
+
+
+
+ Frontend 🎨
+ Frontend development with Leaf
+
+
+
+
+
+ Utilities 🧹
+ Everyday necessities for your apps
+
+
+
+
+
+## MVC
+
+
+
+ Leaf MVC 🌿
+ Building apps with Leaf MVC
+
+
+
+
+
+ Database 🗄️
+ Database operations in Leaf MVC
+
+
+
+
+
+ Other Helpers 🖥️
+ Make building MVC apps even easier
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/docs/installation.md b/src/docs/installation.md
new file mode 100644
index 00000000..548e4541
--- /dev/null
+++ b/src/docs/installation.md
@@ -0,0 +1,100 @@
+# Installation
+
+
+
+
+
+Leaf is built by design to be incrementally adoptable. This means that it can be integrated into a project multiple ways depending on the requirements. You can use Leaf on its own which is generally recommended for small/medium sized projects, or you can use it with an additional structure like [Leaf MVC](/docs/mvc/) for more complex applications.
+
+## Technical Requirements
+
+Before you create your first Leaf application, you need to make sure you meet the following requirements:
+
+- Leaf currently supports PHP 7.4 and higher, but we are in the process of changing the minimum required version to PHP 8.1
+- Leaf requires these PHP extensions (which are installed and enabled by default in most PHP installations): json, zip;
+- [Install Composer](https://getcomposer.org/download/), which is used to install PHP packages.
+- Optionally, you can also install [Leaf CLI](/docs/cli/). This provides all the tools you need to create and manage your Leaf application locally. This is optional but highly recommended.
+
+::: details Not sure where to start?
+
+- Beyond Code released an amazing tool called [Laravel Herd](https://herd.laravel.com/) that provides a quick and easy way to set up a local PHP development environment for Mac and Windows. It's a great way to get started with PHP if you don't have it installed yet.
+
+- Another way to install PHP and Composer without any hassle is to use [php.new](https://php.new/) which was created by Beyond Code. It's a quick way to get started on Windows, Linux and Mac with just one command.
+
+- A more traditional way on Windows, Linux and Mac, you can use [Xampp](https://www.apachefriends.org/), which is a free and open-source cross-platform web server solution stack package developed by Apache Friends, consisting mainly of the Apache HTTP Server, MariaDB database, and interpreters for scripts written in the PHP and Perl programming languages.
+
+Once you have PHP and Composer installed, you can proceed with the installation of Leaf CLI.
+
+:::
+
+## Automatic Installation
+
+We recommend starting a new Leaf app using the Leaf CLI, which sets up everything automatically for you. To create a project, run:
+
+```bash:no-line-numbers
+leaf create
+```
+
+This command will walk you through a quick setup process where you can choose the features you want in your app. There are more options available in the CLI, which you can find in the [CLI documentation](/docs/cli/).
+
+Once your project is generated, you can run it using the `serve` command:
+
+```bash:no-line-numbers
+leaf serve
+```
+
+
+
+## Manual Installation
+
+
+
+Leaf also allows a more traditional approach to installation through [composer](https://getcomposer.org/). We recommend using the Leaf CLI since it provides a more streamlined setup process, but of course, you can use composer if you prefer. The disadvantage of this method is that you don't get a quick-start setup like you do with the leaf cli.
+
+```bash:no-line-numbers
+composer require leafs/leaf
+```
+
+After installing Leaf, you need to create your index.php file which will be the entry point to your application.
+
+::: code-group
+
+```php [Functional Mode]
+get('/', function () {
+ response()->json(['message' => 'Hello World!']);
+});
+
+app()->run();
+```
+
+```php [Class Mode]
+get('/', function () use($app) {
+ $app->response()->json(['message' => 'Hello World!']);
+});
+
+$app->run();
+```
+
+:::
+
+When hosting your application on a webserver, all requests coming into your app must be routed through Leaf. It is really simple to do, and all needed instructions can be found @ [URL rewriting](/docs/routing/url-rewriting).
diff --git a/src/docs/introduction/docker.md b/src/docs/introduction/docker.md
deleted file mode 100644
index 5440efc2..00000000
--- a/src/docs/introduction/docker.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Using Docker
-
-
-
-Docker allows developers to package their applications and dependencies into lightweight and portable containers, which can be easily deployed and run on any environment, making it easier to develop and deploy applications consistently. This means you don't have to worry about configuring or setting up complicated development tools such as web servers and databases on your local machine.
-
-
-
-This guide will walk you through how to set up your Leaf application using Docker from scratch. To get started, you need to install [Docker Desktop](https://www.docker.com/products/docker-desktop/). After this, you can either use the Leaf CLI or manually create your application.
-
-## Using the Leaf CLI
-
-The Leaf CLI provides a simple way to get started with Docker in your Leaf applications. To create a new Dockerized Leaf app using the Leaf CLI, you need to add the `--docker` option to the `leaf create` command:
-
-```bash
-leaf create my-app --docker
-```
-
-This will setup a new Leaf application with Docker support. Although your app is dockerized, Leaf CLI still allows you to use the `serve` command to start your application. This command will automatically start your application using Docker instead of the built-in server.
-
-```bash
-leaf serve
-```
-
-### Docker Files
-
-You will notice a bunch of docker related files in your project. These are added by the Leaf CLI since you used the `--docker` option. You can always customize these files to suit your specific needs.
-
-```bash
-├── docker
-│ ├── 000-default.conf
-│ ├── Dockerfile
-│ └── php.ini
-├── docker-compose.yml
-```
-
-- `000-default.conf` is the Apache configuration file that will be used by the Docker container.
-- `Dockerfile` is the Dockerfile that will be used to build the Docker image.
-- `php.ini` is the PHP configuration file that will be used by the Docker container.
-- `docker-compose.yml` is the Docker Compose file that will be used to start the Docker container.
-
-## Adding to existing projects
-
-If you already have an existing Leaf application and you want to add Docker support to it, you will need to do so manually. We have provided a sample below that you can use as a reference.
-
-**Dockerfile:**
-
-```dockerfile
-FROM php:8.1-apache
-
-COPY 000-default.conf /etc/apache2/sites-available/000-default.conf
-
-RUN a2enmod rewrite
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
- libzip-dev \
- wget \
- git \
- unzip
-
-RUN docker-php-ext-install zip pdo pdo_mysql
-
-RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
-
-RUN composer global require leafs/cli
-
-RUN ln -s /root/.composer/vendor/bin/leaf /usr/local/bin/leaf
-
-# If you have a custom PHP ini file you can uncomment this line
-# COPY ./php.ini /usr/local/etc/php/php.ini
-
-RUN apt-get purge -y g++ \
- && apt-get autoremove -y \
- && rm -rf /var/lib/apt/lists/* \
- && rm -rf /tmp/*
-
-WORKDIR /var/www
-
-RUN chown -R www-data:www-data /var/www
-
-CMD ["apache2-foreground"]
-```
-
-**docker-compose.yml:**
-
-```yaml
-version: '3.1'
-services:
- application:
- build: ./docker
- image: leafphp/docker
- ports:
- - '8080:80'
- volumes:
- - .:/var/www
-```
-
-**000-default.conf:**
-
-```apacheconf
-
- ServerAdmin webmaster@localhost
- DocumentRoot /var/www
-
-
- Options Indexes FollowSymLinks
- AllowOverride All
- Require all granted
-
-
-```
-
-After adding these files, you can start your application using Docker by running the following command:
-
-```bash
-leaf serve
-```
-
-Or with the docker compose command:
-
-```bash
-docker compose up
-```
diff --git a/src/docs/introduction/features.md b/src/docs/introduction/features.md
deleted file mode 100644
index 6b052b2c..00000000
--- a/src/docs/introduction/features.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-aside: none
----
-
-# Features
-
-Leaf has a ton of features which help provide the best developer experience without sacrificing any power. Leaf 3 makes these features even more usable. These are some of leaf's features:
-
-## Low barrier to entry
-
-Leaf is the easiest framework to learn with PHP newbies building powerful leaf apps in a few minutes of reading the docs/watching out tutorial videos. All you truly need to get started with Leaf is basic PHP knowledge and optional but recommended knowledge on some backend concepts like JWT auth and more.
-
-## Lightweight
-
-Leaf 2 was lightweight and fast enough to be considered one of the most lightweight but powerful frameworks around, and Leaf 3 makes leaf 2 look like a joke. Leaf 3 can now be considered the most lightweight PHP framework with a source of about 30kb and allows you to build full apps and APIs which end up less than 20mb including user dependencies (leaf api). This is a big haul compared to other frameworks which require dependencies and tons of files which end up more than 100mb.
-
-![image](https://user-images.githubusercontent.com/26604242/146754044-4c71c4ec-7b37-4c85-9c8b-56e8c2b54831.png)
-
-> a comparism with slim - slim (left) - leaf (right)
-
-## Enables high developer productivity
-
-A whole lot of research and testing has been done to build amazing features which allow developers to focus on only what they need: their apps. Leaf 3 has put tons of strategies together to create the best developer experience known to PHP. From things like removing class initializers and creating global functions which allow you call classes from anywhere in your application, modules and other amazing leaf features.
-
-## Powered by [modules](/modules/)
-
-Leaf 3 and its ecosystem are heavily powered by modules, which are simply pieces of leaf's functionality shipped into independently installable libraries. Modules help make leaf even more lightweight and help developers only deal with features which they need in their applications. This means that you only install what you need.
-
-## Easy to use features
-
-As mentioned above, a lot of research has gone into the developer experience for leaf 3 and one aspect was to make our existing features more performant and easier to use. We employed various strategies like modeling some features after popular libraries in other languages and frameworks. For instance, the API for leaf cors is almost an exact replica of the expressjs cors middleware.
-
-## Library/Framework compatibility
-
-Since the beginning of Leaf, we've set out to create code which could easily be integrated with other libraries and frameworks. No matter how powerful leaf is, we try to base of everything we do on simple concepts as opposed to other frameworks which need things like providers in order to access framework features in libraries.
-
-## Scalability
-
-One of the most beautiful things about leaf is that, no matter what package you're using with leaf, if it works in development, it will definitely work in production with near zero config, unless you want some special features. Leaf provides a core and other frameworks/libraries that build around leaf. This makes leaf appropriate for almost any project no matter it's size.
diff --git a/src/docs/introduction/first-app.md b/src/docs/introduction/first-app.md
deleted file mode 100644
index 6c48606f..00000000
--- a/src/docs/introduction/first-app.md
+++ /dev/null
@@ -1,469 +0,0 @@
-# Your first app
-
-::: tip Pre-requisites
-
-- Basic PHP knowledge
-
-:::
-
-This is an interactive tutorial to help you get started with leaf, right from installation to building your first leaf 3 app. This tutorial will require basic PHP knowledge with an optional knowledge on APIs.
-
-## Getting started
-
-::: tip Leaf CLI
-We recommend using the [Leaf CLI](/docs/cli/) for creating and managing your Leaf projects.
-:::
-
-To get started, we will need to generate a leaf application. We can do this simply with Leaf CLI:
-
-```bash
-leaf create --basic
-```
-
-
-
-Or with composer:
-
-```bash
-composer require leafs/leaf
-```
-
-After this, you will need to create an `index.php` file. *This is already done for you if you used Leaf CLI.*
-
-## Your app starter
-
-Now that leaf is installed, you will need a file which will serve as the root of your project. Leaf uses a single root file, to which all routes are sent to. Leaf then takes the route and calls the related handler for it. You can read more in the [routing docs](/docs/routing/).
-
-Your starter file will import leaf and hold your routes.
-
-```php
-
-
-Let's define a dummy route.
-
-```php{3-5}
-$app = new Leaf\App();
-
-$app->get('/', function () {
- echo 'something';
-});
-
-// don't forget to call `run`
-$app->run();
-```
-
-
-
-
-
-We would normally need to initialize leaf, however, with with the introduction of functional mode, we don't need to do this. We can go straight to building our app.
-
-Let's define a dummy route.
-
-```php{1-3}
-app()->get('/', function () {
- echo 'something';
-});
-
-// don't forget to call `run`
-app()->run();
-```
-
-
-
-Defining a route is that simple with leaf. In this case, we just defined the `GET /` route. We can simply run this with `leaf serve` if you use the leaf CLI or `php -S localhost:[PORT]`.
-
-## Our app
-
-Now that we've gotten our hello world setup complete, we can get started with our application. We will build a simple note taking app which will allow us create and fetch notes from a database.
-
-## Modules
-
-Modules are pieces of leaf's functionality which are served as installable plugins. They were created in an attempt to stop leaf from bloating like other frameworks. This means that you can have only what you need in your app, and always extend Leaf's power on demand.
-
-As you will see, modules are installed using the Leaf CLI or composer. For this app, we'll be using the `db` module to access our database.
-
-## Getting our notes
-
-### Creating our route
-
-To get started with this step, we need to create a GET route which will return all the notes in our database. Since we already know how to create routes like the one above, this step is pretty simple.
-
-
-
-```php
-$app->get('/notes', function () {
- // fetch all notes from the database
- // output notes as JSON
- echo 'all notes';
-});
-```
-
-
-
-
-
-```php
-app()->get('/notes', function () {
- // fetch all notes from the database
- // output notes as JSON
- echo 'all notes';
-});
-```
-
-
-
-### Fetching notes
-
-As mentioned above, we will use the db module to access our database. Leaf DB has made database operations really simple and accessible to everyone. You don't even need knowledge on SQL to use Leaf DB.
-
-#### Installing leaf db
-
-To install the db module, we can use the Leaf CLI.
-
-```bash
-leaf install db
-```
-
-You can also use composer:
-
-```bash
-composer require leafs/db
-```
-
-#### Connecting to our db
-
-From there, we can head back inside our app and connect to our database.
-
-
-
-```php
-$db = new Leaf\Db;
-$db->connect('127.0.0.1', 'dbname', 'username', 'password');
-```
-
-
-
-
-
-```php
-db()->connect('127.0.0.1', 'dbname', 'username', 'password');
-```
-
-
-
-We can place this before before our routes so we can use the `$db` variable everywhere.
-
-#### Using the db module
-
-Back in our route, we can pass the `$db` variable into scope and get started with it. You can check the [db module docs](/modules/db/) for more info.
-
-What we want to do here is retrieve all the data from our notes table, we can do this simply using `select`. This is a method provided by leaf db which allows us run the SQL `Select` command.
-
-
-
-```php
-$app = new Leaf\App;
-$db = new Leaf\Db;
-
-$db->connect('127.0.0.1', 'dbname', 'username', 'password');
-
-// pass db into the callback using `use`
-$app->get('/notes', function () use($db) {
- // fetch all notes from the database
- $notes = $db->select('notes')->all();
-
- // output notes as JSON
- echo 'all notes';
-});
-```
-
-
-
-
-
-```php
-db()->connect('127.0.0.1', 'dbname', 'username', 'password');
-
-app()->get('/notes', function () {
- // fetch all notes from the database
- $notes = db()->select('notes')->all();
-
- // output notes as JSON
- echo 'all notes';
-});
-```
-
-
-
-Now that we've been able to retrieve our data from the database, let's see how we can output this data.
-
-### The response object
-
-The response object is leaf's library for handling the way data flows out of your application. It has a very simple and easy to use interface , and with functional mode, it can be used from anywhere in your app without initilaizing it .
-
-In the lines above, we retrieved our data from the database. Now all that's left is to output this data as JSON. We can do this simply by calling `json` on the response object.
-
-
-
-```php
-$app->get('/notes', function () use($app, $db) {
- $notes = $db->select('notes')->all();
-
- $app->response()->json([
- 'status' => 'success',
- 'data' => $notes,
- ]);
-});
-```
-
-
-
-
-```php
-app()->get('/notes', function () {
- $notes = db()->select('notes')->all();
-
- response()->json([
- 'status' => 'success',
- 'data' => $notes,
- ]);
-});
-```
-
-
-
-This will output JSON
-
-```json
-{
- "status": "success",
- "data": [...]
-}
-```
-
-## Saving our notes
-
-We need to create another route to handle adding new notes. In this case, we will create a POST route, meaning you will need to create a POST request to access it. This can be done using an HTTP client of some sort.
-
-This new route will take some data into our application and then select only what we need to be saved in the database, and finally return a message.
-
-
-
-```php
-$app->post('/notes/new', function () use($db) {
- // get data from request
- // save items
- // return success message
-});
-```
-
-
-
-
-```php
-app()->post('/notes/new', function () {
- // get data from request
- // save items
- // return success message
-});
-```
-
-
-
-### The request object
-
-Just as we saw with the response object, Leaf also provides a request object which allows us to quickly and securely get data which flows into our application.
-
-
-
-```php
-$item = $app->request()->get('item');
-```
-
-
-
-
-```php
-$item = request()->get('item');
-```
-
-
-
-This line will get data with the key `item` passed into the app from a form, url or any other data and save it in the `$item` variable. In this case, our app will accept `title`, `body` and `date` which we will save in the database.
-
-To do this, we can retrieve them one by one as we did above, but leaf provides an easier way.
-
-
-
-```php
-$data = $app->request()->get(['title', 'body', 'date']);
-```
-
-
-
-
-```php
-$data = request()->get(['title', 'body', 'date']);
-```
-
-
-
-With this, all other data passed in our app will be ignored, but will still be available for use.
-
-### Saving data in the db
-
-To save the data in the database, we will use leaf db as we did above. This time, the `insert` method instead.
-
-
-
-```php
-$db->insert('notes')->params($data)->execute();
-```
-
-
-
-
-```php
-db()->insert('notes')->params($data)->execute();
-```
-
-
-
-`execute` is used on commands which don't return any value like `insert` and `update`.
-
-Putting it all together, we'll have this:
-
-
-
-```php
-$app->post('/notes/new', function () use($app, $db) {
- // get data from request
- $data = $app->request()->get(['title', 'body', 'date']);
-
- // save items
- $db->insert('notes')->params($data)->execute();
-
- // return success message
- $app->response()->json([
- 'status' => 'success',
- 'message' => 'Notes saved'
- ]);
-});
-```
-
-
-
-
-```php
-app()->post('/notes/new', function () {
- // get data from request
- $data = request()->get(['title', 'body', 'date']);
-
- // save items
- db()->insert('notes')->params($data)->execute();
-
- // return success message
- response()->json([
- 'status' => 'success',
- 'message' => 'Notes saved'
- ]);
-});
-```
-
-
-
-## Putting it all together
-
-
-
-```php
-connect('127.0.0.1', 'dbname', 'username', 'password');
-
-$app->get('/notes', function () use($app, $db) {
- $notes = $db->select('notes')->all();
-
- $app->response()->json([
- 'status' => 'success',
- 'data' => $notes,
- ]);
-});
-
-$app->post('/notes/new', function () use($app, $db) {
- $data = $app->request()->get(['title', 'body', 'date']);
-
- $db->insert('notes')->params($data)->execute();
-
- $app->response()->json([
- 'status' => 'success',
- 'message' => 'Notes saved'
- ]);
-});
-
-$app->run();
-```
-
-
-
-
-```php
-connect('127.0.0.1', 'dbname', 'username', 'password');
-
-app()->get('/notes', function () {
- $notes = db()->select('notes')->all();
-
- response()->json([
- 'status' => 'success',
- 'data' => $notes,
- ]);
-});
-
-app()->post('/notes/new', function () {
- $data = request()->get(['title', 'body', 'date']);
-
- db()->insert('notes')->params($data)->execute();
-
- response()->json([
- 'status' => 'success',
- 'message' => 'Notes saved'
- ]);
-});
-
-app()->run();
-```
-
-
-
-Building is this simple with leaf, as you can see, we've built a note taking app in less than 30 lines of code.
diff --git a/src/docs/introduction/index.md b/src/docs/introduction/index.md
deleted file mode 100644
index 2bcc10b1..00000000
--- a/src/docs/introduction/index.md
+++ /dev/null
@@ -1,156 +0,0 @@
-# Introduction
-
-
-
-
-
-Leaf is a slim and lightweight PHP framework focused on developer experience, usability, and high-performance code. It is a modern PHP framework built to be simple and elegant, yet extremely powerful.
-
-Here's an example:
-
-```php
-get('/', function () {
- response()->json(['message' => 'Hello World!']);
-});
-
-app()->run();
-```
-
-## Features
-
-Leaf has a ton of features that make it a great choice for building your next project. Here are some of the features that make Leaf stand out:
-
-- Lightweight
-- Super performant
-- Easy to learn
-- Easy to use
-
-For an in-depth look at Leaf's features, check out the [features page](/docs/introduction/why.html).
-
-## Getting Started
-
-The official guide assumes **basic** level knowledge of PHP.
-
-::: tip Down to the basics
-
-
-😵💫 Don't know PHP?
-If you are not familiar with PHP, we recommend that you check out the W3Schools PHP Tutorial before continuing or use the video below. This is because you will basically be writing PHP code when using Leaf (or any other framework).
-
-
-
-
-
-What's a PHP Framework?
-If you are not familiar with the concept of PHP frameworks, you can check out the video below by Kinsta .
-
-
-
-
-:::
-
-### Installation
-
-
-
-To quickly get started with Leaf, check out our [installation guide](/docs/introduction/installation.html). This gives you an in-depth explanation of how to set up leaf using various methods.
-
-## Classes vs Functions
-
-Leaf supports two different ways of writing your code:
-
-- Using functional mode which you saw above
-- Using class mode which is building your app using Leaf's classes
-
-### Class Mode
-
-If you are familiar with PHP frameworks, you've probably spent a lot of time writing code using classes. Leaf comes with a ton of powerful classes that you can use to build your app. Let's take a look at the code above in class mode.
-
-```php
-get('/', function () use ($app) {
- $app->response()->json(['message' => 'Hello World!']);
-});
-
-$app->run();
-```
-
-### Functional Mode
-
-Classes can become annoying and very repetitive, especially because of namespaces. You also sometimes need to worry about variable scoping and re-initializing classes.
-
-For these and many more reasons, Leaf allows you to build your apps entirely using functions. Let's take a look at the code above in functional mode.
-
-```php
-get('/', function () {
- response()->json(['message' => 'Hello World!']);
-});
-
-app()->run();
-```
-
-Besides the benefits functional mode gives you on a surface level, it also does a lot of work behind the scenes to make your code more efficient and faster.
-
-## Modes in the docs
-
-The docs are written in both functional and class mode. You can switch between the two modes using the switcher at the top of the page.
-
-![Switcher](https://user-images.githubusercontent.com/26604242/178108346-c9c22a19-6a82-4786-ac3e-00cbfe69cba8.png)
-
-## Leaf modules
-
-Modules are pieces of Leaf's functionality that are available as separate packages. These packages can be installed and used with Leaf to extend its functionality. Most modules are framework agnostic and can be used with other frameworks and libraries, but they are built to work best with Leaf.
-
-You can check out the [modules page](/modules/) to see a list of all the modules available for Leaf.
-
-## Ready for More?
-
-We've briefly introduced the most basic features of Leaf 3 - the rest of this guide will cover them and other advanced features in much finer detail, so make sure to read through it!
-
-## Next Steps
-
-If you are new to Leaf, we strongly recommend reading this page before moving on to the rest of the documentation. It will provide you with a solid foundation on which to build your Leaf knowledge. If you are already familiar with Leaf, feel free to check out the rest of the documentation.
-
-
diff --git a/src/docs/introduction/installation.md b/src/docs/introduction/installation.md
deleted file mode 100644
index efb95098..00000000
--- a/src/docs/introduction/installation.md
+++ /dev/null
@@ -1,199 +0,0 @@
-# Installation
-
-
-
-
-
-Leaf 3 is built by design to be incrementally adoptable. This means that it can be integrated into a project multiple ways depending on the requirements.
-
-There are four primary ways of adding Leaf PHP to a project:
-
-1. [Use the Leaf CLI to scaffold a project [RECOMMENDED]](#leaf-cli).
-2. [Download leaf through composer](#composer)
-3. [Scaffold a Leaf MVC or Leaf API project](#mvc-setup)
-
-## Technical Requirements
-
-Before creating your first Leaf application you must:
-
-- Install PHP 7.4 or higher and these PHP extensions (which are installed and enabled by default in most PHP installations): json, zip;
-- [Install Composer](https://getcomposer.org/download/), which is used to install PHP packages.
-- Optionally, you can also install [Leaf CLI](/docs/cli/). This provides all the tools you need to create and manage your Leaf application locally. This is optional but highly recommended.
-
-
-Not sure where to start?
-
-- Laravel released an amazing tool called [Laravel Herd](https://herd.laravel.com/) that provides a quick and easy way to set up a local PHP development environment for Mac. It's a great way to get started with PHP and Leaf.
-
-- On Windows and Mac, you can use [Xampp](https://www.apachefriends.org/), which is a free and open-source cross-platform web server solution stack package developed by Apache Friends, consisting mainly of the Apache HTTP Server, MariaDB database, and interpreters for scripts written in the PHP and Perl programming languages.
-
-
-
-## Leaf CLI
-
-
-
-Leaf provides an [official CLI](https://github.com/leafsphp/cli) for quickly creating and managing your Leaf applications. It takes just a few seconds to get up and running with your leaf app. See [the Leaf CLI docs](/docs/cli/) for more details.
-
-Using the CLI, you can quickly scaffold a new Leaf 3 project with:
-
-```bash
-leaf create
-```
-
-Besides the core of the framework, Leaf also ships with a ton of installable functionality. We call these independent libraries modules. You can install modules using the `install` command:
-
-```bash
-leaf install
-```
-
-The CLI also allows you to completely customize the installation you wish to create. You can choose different features like database, authentication, etc. This is done using the `--custom` flag:
-
-```bash
-leaf create --custom
-```
-
-You can then run your app using the `serve` command:
-
-```bash
-leaf serve
-```
-
-## Composer
-
-
-
-Leaf also allows a more traditional approach to installation. You can install leaf through composer. You can use this method if you don't want to use the leaf cli or if you want to use leaf as a dependency in your project. The disadvantage of this method is that you don't get a quick-start setup like you do with the leaf cli.
-
-```bash
-composer require leafs/leaf
-```
-
-After insalling Leaf, you need to create your index.php file which will be the entry point to your application.
-
-
-
-```php
-get('/', function () use($app) {
- $app->response()->json(['message' => 'Hello World!']);
-});
-
-$app->run();
-```
-
-
-
-
-
-```php
-get('/', function () {
- response()->json(['message' => 'Hello World!']);
-});
-
-app()->run();
-```
-
-
-
-When hosting your application on a webserver, all requests coming into your app must be routed through Leaf. It is really simple to do, and all needed instructions can be found @ [URL rewriting](/docs/introduction/url-rewriting.html).
-
-## MVC Setup
-
-Although Leaf allows you to select exactly what you want to install, some applications go beyond the basic setup. Leaf MVC is a full but ridiculously light-weight MVC framework that allows you to build complex applications with Leaf. It comes with a lot of features like authentication, database, http related functionality and a powerful CLI. To get started with Leaf's MVC setup, you can check out the [MVC docs](/docs/mvc/).
-
-## Hello world example
-
-Below is a "hello world" example which takes you through the core of Leaf. Other parts of the docs cover deeper examples. You can also refer to our [codelab experiments](/codelabs/) for real world examples and use-cases.
-
-A base Leaf app that outputs hello world in your browser looks like this:
-
-
-
-```php
-get('/', function () {
- echo 'Hello world';
-});
-
-$app->run();
-```
-
-
-
-
-
-```php
-get('/', function () {
- echo 'Hello world';
-});
-
-app()->run();
-```
-
-
-
-You might have noticed that we used `echo` to output our data. Using `echo` is not a bad thing, but it can be confusing when you're trying to output data of a different type. For example, if we wanted to output JSON data, we would have to use `echo json_encode($data)`. This can be confusing because we're not sure if the content type is set to JSON or not.
-
-To simplify this, Leaf comes with a `Response` object that automatically handles content the right way for us. Let's look at an example below.
-
-
-
-```php
-get('/', function () use($app) {
- $app->response()->markup('Hello world');
-});
-
-$app->run();
-```
-
-
-
-
-```php
-get('/', function () {
- response()->markup('Hello world');
-});
-
-app()->run();
-```
-
-
diff --git a/src/docs/introduction/url-rewriting.md b/src/docs/introduction/url-rewriting.md
deleted file mode 100755
index 61012de7..00000000
--- a/src/docs/introduction/url-rewriting.md
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-# URL Rewriting
-
-
-
-Basically, we're trying to push all the requests made to the server to a single root file, so a request made to `/home.php` will be directed to the root file of our choice....usually `index.php`.
-
-This complex sounding feature can be achieved by adding a web server configuration depending on your server of choice.
-
-
-
-## Apache - .htaccess
-
-This is a basic example of an htaccess file. It basically re-routes all requests to our index.php file.
-
-```htaccess
-RewriteEngine on
-RewriteCond %{REQUEST_FILENAME} !-d
-RewriteCond %{REQUEST_FILENAME} !-f
-RewriteRule . index.php [L]
-```
-
-Save as `.htaccess` in your the same directory as your "root file"
-
-## Nginx - nginx.conf
-
-A basic example with nginx web server
-
-```nginx
-try_files $uri /index.php;
-```
-
-You can read below for an overview of url rewriting.
-
-- [Intro to URL rewriting](https://www.smashingmagazine.com/2011/11/introduction-to-url-rewriting/)
-- [.htaccess and nginx.conf variations](https://gist.github.com/bramus/5332525)
diff --git a/src/docs/introduction/why.md b/src/docs/introduction/why.md
deleted file mode 100644
index fa00d0f1..00000000
--- a/src/docs/introduction/why.md
+++ /dev/null
@@ -1,55 +0,0 @@
-# Why Leaf
-
-When it comes to building web applications, there are numerous tools and frameworks at your disposal. Nevertheless, we are convinced that Leaf is the optimal selection for developing powerful, web applications and APIs.
-
-## The problems
-
-While PHP frameworks can make web development faster and more efficient, there are some potential challenges or drawbacks to using them, including:
-
-- ***Learning curve***: Most PHP frameworks have a steep learning curve, especially for developers who are new to the language or the framework's conventions.
-
-- ***Performance overhead***: Some PHP frameworks can add unnecessary performance overhead, due to the additional abstraction layers and features they provide.
-
-- ***Code maintenance***: Most frameworks require adhering to specific coding standards and conventions, which can make maintenance and updates more challenging if you are not already familiar with those standards.
-
-- ***Limited flexibility***: PHP frameworks can be more rigid than writing code from scratch, as they may require you to adhere to specific coding standards and conventions. This can limit your flexibility in terms of how you structure your code and handle specific use cases.
-
-- ***Compatibility with other systems***: Most PHP frameworks are bound to a particular ecosystem and make it difficult to randomly pick and use packages which don't have support for the framework you are using.
-
-- ***Packing a ton of unused code/packages***: Just about every PHP framework out there adds a ton of complexity to your applications in the form of unused code, classes and packages. This in turn leads to bloat and ultimately a drop in performance
-
-## How Leaf tackles these
-
-Leaf 3 provides a bunch of features that aim to tackle these common problems found in just about every PHP framework out there.
-
-### Low barrier to entry
-
-Leaf is the easiest framework to learn with PHP newbies building powerful leaf apps in a few minutes of reading the docs/watching out tutorial videos. All you truly need to get started with Leaf is basic PHP knowledge and optional but recommended knowledge on some backend concepts like JWT auth and more.
-
-### Lightweight
-
-Leaf 2 was lightweight and fast enough to be considered one of the most lightweight but powerful frameworks around, and Leaf 3 makes leaf 2 look like a joke. Leaf 3 can now be considered the most lightweight PHP framework with a source of about 30kb and allows you to build full apps and APIs which end up less than 20mb including user dependencies (leaf api). This is a big haul compared to other frameworks which require dependencies and tons of files which end up more than 100mb.
-
-![image](https://user-images.githubusercontent.com/26604242/146754044-4c71c4ec-7b37-4c85-9c8b-56e8c2b54831.png)
-
-> a comparison with slim - slim (left) - leaf (right)
-
-### Enables high developer productivity
-
-A whole lot of research and testing has been done to build amazing features which allow developers to focus on only what they need: their apps. Leaf 3 has put tons of strategies together to create the best developer experience known to PHP. From things like removing class initializers and creating global functions which allow you call classes from anywhere in your application, modules and other amazing leaf features.
-
-### Powered by [modules](/modules/)
-
-Leaf 3 and its ecosystem are heavily powered by modules, which are simply pieces of leaf's functionality shipped into independently installable libraries. Modules help make leaf even more lightweight and help developers only deal with features which they need in their applications. This means that you only install what you need.
-
-### Easy to use features
-
-As mentioned above, a lot of research has gone into the developer experience for leaf 3 and one aspect was to make our existing features more performant and easier to use. We employed various strategies like modeling some features after popular libraries in other languages and frameworks. For instance, the API for leaf cors is almost an exact replica of the expressjs cors middleware.
-
-### Library/Framework compatibility
-
-Since the beginning of Leaf, we've set out to create code which could easily be integrated with other libraries and frameworks. No matter how powerful leaf is, we try to base of everything we do on simple concepts as opposed to other frameworks which need things like providers in order to access framework features in libraries.
-
-### Scalability
-
-One of the most beautiful things about leaf is that, no matter what package you're using with leaf, if it works in development, it will definitely work in production with near zero config, unless you want some special features. Leaf provides a core and other frameworks/libraries that build around leaf. This makes leaf appropriate for almost any project no matter it's size.
diff --git a/src/docs/leafapi/index.md b/src/docs/leafapi/index.md
deleted file mode 100644
index 28158c87..00000000
--- a/src/docs/leafapi/index.md
+++ /dev/null
@@ -1,121 +0,0 @@
-# Leaf API
-
-
-
-Leaf API is a minimal but powerful PHP MVC framework. It's designed to be simple, fast and easy to use. Leaf by default doesn't give you a lot of structure, and that's where Leaf API comes in.
-
-Leaf API is a setup that gives you a good starting point for building APIs using the MVC pattern. It's built on top of Leaf, and comes with additional tooling that make building with Leaf even faster.
-
-## Installation
-
-The easiest way to setup Leaf MVC is to use the [Leaf CLI](/docs/cli/):
-
-```bash
-leaf create --api
-```
-
-You can also setup a Leaf API app by using [Composer](https://getcomposer.org/):
-
-```bash
-composer create-project leafs/api
-```
-
-This command will set up a Leaf API app in the `` directory. You can then run the app using the Leaf CLI:
-
-```bash
-cd
-leaf serve
-```
-
-Or the [built-in PHP server](https://www.php.net/manual/en/features.commandline.webserver.php):
-
-```bash
-cd
-php -S localhost:8000
-```
-
-You should then see the welcome page in your browser.
-
-![Leaf API Welcome Page](https://user-images.githubusercontent.com/26604242/224507412-4cb10731-84f2-49a6-a6b8-b9ab5ca7c7b8.png)
-
-## Directory Structure
-
-The Leaf API directory structure is inspired by [Ruby on Rails](https://rubyonrails.org/) and [Laravel](https://laravel.com/). It takes a lot of inspiration from these frameworks, but it's not a clone of either of them. It is meant to be a starting point for building your own applications, and is fully customizable. You can completely change the directory structure to suit your needs, just be sure to update the paths in the `config.php` file.
-
-For a fresh Leaf API app, the directory structure looks like this:
-
-```bash
-C:.
-├───app
-│ ├── console
-│ ├── controllers
-│ ├── database
-│ │ ├── factories
-│ │ ├── migrations
-│ │ ├── schema
-│ │ └── seeds
-│ ├── helpers
-│ ├── models
-│ ├── routes
-│ └── views
-├───config
-├───public
-├───storage
-│ ├───app
-│ │ └───public
-│ ├───framework
-│ │ └───views
-│ └───logs
-└───vendor
-```
-
-- ### The `app` directory
-
- The `app` directory contains the core code of your application. It's divided into a few sub-directories:
-
- - `console` - Contains the console commands for your application. These are used to perform tasks on the command line.
- - `controllers` - Contains the controllers for your application. These are used to handle HTTP requests.
- - `database` - Contains the database related code for your application. This includes migrations, seeds, factories and schema.
- - `helpers` - Contains the helper functions for your application.
- - `models` - Contains the models for your application. These are used to interact with the database.
- - `routes` - Contains the routes for your application. These are used to map HTTP requests to controllers.
- - `views` - Contains the views for your application. These are used to render HTML responses.
-
-- ### The `config` directory
-
- The `config` directory contains the configuration files for your application. These are used to configure how Leaf and it's modules interact with your application. You can find more information about the configuration files in the [Configuration](/docs/mvc/config) section.
-
-- ### The `public` directory
-
- The `public` directory contains the entry point for your application, and it's also used to serve static assets. The `index.php` file is the entry point for your application. All requests are routed through this file by the web server. This file doesn't contain any application logic, but it does load the Composer autoloader, the application config and all your routes.
-
-- ### The `storage` directory
-
- The `storage` directory contains the compiled views, logs and other files generated by your application. It's divided into a few sub-directories:
-
- - `app` - Contains the files generated by your application. This includes the compiled views and the files uploaded by users.
- - `framework` - Contains the framework generated files for your application.
- - `logs` - Contains the log files generated by your application.
-
-- ### The `vendor` directory
-
- The `vendor` directory contains all the dependencies installed by Composer. It's automatically generated when you install the dependencies using Composer.
-
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf API.
-
-
diff --git a/src/docs/leafmvc/index.md b/src/docs/leafmvc/index.md
deleted file mode 100644
index 4cbaf7cd..00000000
--- a/src/docs/leafmvc/index.md
+++ /dev/null
@@ -1,127 +0,0 @@
-# Leaf MVC
-
-
-
-Leaf MVC is a minimal but powerful PHP MVC framework. It's designed to be simple, fast and easy to use. Leaf by default doesn't give you a lot of structure, and that's where Leaf MVC comes in.
-
-Leaf MVC is a setup that gives you a good starting point for building applications using the MVC pattern. It's built on top of Leaf, and comes with additional tooling that make building with Leaf even faster.
-
-## Installation
-
-The easiest way to setup Leaf MVC is to use the [Leaf CLI](/docs/cli/):
-
-```bash
-leaf create --mvc
-```
-
-You can also setup a Leaf MVC app by using [Composer](https://getcomposer.org/):
-
-```bash
-composer create-project leafs/mvc
-```
-
-This command will set up a Leaf MVC app in the `` directory. You can then run the app using the Leaf CLI:
-
-```bash
-cd
-leaf serve
-```
-
-Or the [built-in PHP server](https://www.php.net/manual/en/features.commandline.webserver.php):
-
-```bash
-cd
-php -S localhost:8000
-```
-
-You should then see the welcome page in your browser.
-
-![Leaf MVC Welcome Page](https://user-images.githubusercontent.com/26604242/223189921-d5da1555-bc29-4f99-a3ec-d6cbfdc5350b.png)
-
-## Directory Structure
-
-The Leaf MVC directory structure is inspired by [Ruby on Rails](https://rubyonrails.org/) and [Laravel](https://laravel.com/). It takes a lot of inspiration from these frameworks, but it's not a clone of either of them. It is meant to be a starting point for building your own applications, and is fully customizable. You can completely change the directory structure to suit your needs, just be sure to update the paths in the `config.php` file.
-
-For a fresh Leaf MVC app, the directory structure looks like this:
-
-```bash
-C:.
-├───app
-│ ├── console
-│ ├── controllers
-│ ├── database
-│ │ ├── factories
-│ │ ├── migrations
-│ │ ├── schema
-│ │ └── seeds
-│ ├── helpers
-│ ├── models
-│ ├── routes
-│ └── views
-│ └── errors
-├───config
-├───public
-│ └───assets
-│ ├── css
-│ └── img
-├───storage
-│ ├───app
-│ │ └───public
-│ ├───framework
-│ │ └───views
-│ └───logs
-└───vendor
-```
-
-- ### The `app` directory
-
- The `app` directory contains the core code of your application. It's divided into a few sub-directories:
-
- - `console` - Contains the console commands for your application. These are used to perform tasks on the command line.
- - `controllers` - Contains the controllers for your application. These are used to handle HTTP requests.
- - `database` - Contains the database related code for your application. This includes migrations, seeds, factories and schema.
- - `helpers` - Contains the helper functions for your application.
- - `models` - Contains the models for your application. These are used to interact with the database.
- - `routes` - Contains the routes for your application. These are used to map HTTP requests to controllers.
- - `views` - Contains the views for your application. These are used to render HTML responses.
-
-- ### The `config` directory
-
- The `config` directory contains the configuration files for your application. These are used to configure how Leaf and it's modules interact with your application. You can find more information about the configuration files in the [Configuration](/docs/mvc/config) section.
-
-- ### The `public` directory
-
- The `public` directory contains the entry point for your application, and it's also used to serve static assets. The `index.php` file is the entry point for your application. All requests are routed through this file by the web server. This file doesn't contain any application logic, but it does load the Composer autoloader, the application config and all your routes.
-
- There is also an `assets` directory found in the `public` directory. It contains the static assets for your application. These are served by the web server and are accessible to users.
-
-- ### The `storage` directory
-
- The `storage` directory contains the compiled views, logs and other files generated by your application. It's divided into a few sub-directories:
-
- - `app` - Contains the files generated by your application. This includes the compiled views and the files uploaded by users.
- - `framework` - Contains the framework generated files for your application.
- - `logs` - Contains the log files generated by your application.
-
-- ### The `vendor` directory
-
- The `vendor` directory contains all the dependencies installed by Composer. It's automatically generated when you install the dependencies using Composer.
-
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf MVC.
-
-
diff --git a/src/docs/migrating.md b/src/docs/migrating.md
new file mode 100644
index 00000000..8435fde4
--- /dev/null
+++ b/src/docs/migrating.md
@@ -0,0 +1,159 @@
+# Migrating from other frameworks
+
+This page contains a guide for developers who have a working application in another framework and want to port over to Leaf. Since Leaf is modular, you can pick different pieces and incrementally add them to your existing application. This way, you can gradually rewrite your application without breaking any code.
+
+Before you go on, we just want to say
+
+![image](https://github.com/user-attachments/assets/e324cb25-2fa6-4c03-b490-499173992f99)
+
+## Why Migrate to Leaf?
+
+Depending on the framework you're coming from, you might have different reasons for migrating to Leaf. Leaf is lightweight, modular, and has a simple API. It offers better performance and flexibility compared to many other frameworks. Leaf also allows you to integrate other libraries seamlessly into your Leaf apps with no conflicts or complexities.
+
+We are still in the process of creating migration guides for different frameworks. If you have a specific framework you'd like to migrate from, please let us know by creating an issue on our GitHub repository. For now, you can follow the general guide below.
+
+## Quickstart
+
+Since you can pick and choose different modules in Leaf, you can start by finding the feature you want to use and installing it. Below is an example of a Slim PHP 4 application that we want to use Leaf in:
+
+```php
+get('/', function (Request $request, Response $response, $args) {
+ $name = $args['name'];
+ $response->getBody()->write("Hello, $name");
+ return $response;
+});
+
+$app->run();
+```
+
+Slim and Leaf are both micro-frameworks, so the migration process is relatively straightforward. You can install Leaf in your Slim application and start using Leaf's features.
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf install leaf
+```
+
+```bash:no-line-numbers [Composer]
+composer require leafs/leaf
+```
+
+:::
+
+We can start off by swapping out the Slim request and response objects with Leaf's. Since this is a little change, we installed the `leaf` module which contains Leaf's core features, including the request and response objects. In more complex applications, you can install specific modules that you need like Auth, Database, etc.
+
+## Replacing HTTP Interfaces
+
+Now, we can replace Slim's request and response objects with Leaf's. What makes this process easy is that Leaf's request and response objects are not tied to any specific framework. This means you can use them in any PHP application. They use PHP's internal methods which makes them compatible with any PHP application.
+
+```php
+get('/', function (Request $request, Response $response, $args) { // [!code --]
+$app->get('/', function () use ($leaf) { // [!code ++]
+ $name = $args['name']; // [!code --]
+ $name = $leaf->request()->get('name'); // [!code ++]
+
+ $response->getBody()->write("Hello, $name"); // [!code --]
+ return $response; // [!code --]
+ $leaf->response()->markup("Hello, $name"); // [!code ++]
+});
+
+$app->run();
+```
+
+After making these changes, you can run your application and see that it still works as expected. It should look something like this:
+
+```php
+get('/', function () use($leaf) {
+ $name = $leaf->request()->get('name');
+ $leaf->response()->markup("Hello, $name");
+});
+
+$app->run();
+```
+
+## Replacing Router Interfaces
+
+We've replaced the request and response objects, but we still need to replace the router. Leaf's router is an extremely powerful and flexible router that can handle any type of route. Since we already installed the `leaf` module, we can start using Leaf's router.
+
+```php
+get('/', function () use($leaf) { // [!code --]
+$app->get('/', function () use($app) { // [!code ++]
+ $name = $app->request()->get('name');
+ $app->response()->markup("Hello, $name");
+});
+
+$app->run();
+```
+
+After verifying that your application still works, you can remove the Slim framework from your application. You can now start using Leaf's features and modules in your application. The final code should look like this:
+
+```php
+get('/', function () {
+ $name = request()->get('name');
+ response()->markup("Hello, $name");
+});
+
+$app->run();
+```
+
+## Functional Mode
+
+Leaf provides a functional mode that allows you to use Leaf without creating an instance of the `Leaf\App` class or any other Leaf modules. It offers a more functional approach to building applications, but we recommend using this only after you have migrated the core parts of your application.
+
+```php
+get('/', function () {
+ $name = request()->get('name');
+ response()->markup("Hello, $name");
+});
+
+app()->run();
+```
diff --git a/src/docs/migration/introduction.md b/src/docs/migration/introduction.md
deleted file mode 100644
index 86fa8a26..00000000
--- a/src/docs/migration/introduction.md
+++ /dev/null
@@ -1,209 +0,0 @@
-# Migration Guide
-
-
-
-
-
-This guide is primarily for users with prior Leaf 2 experience who want to learn about the new features and changes in Leaf 3. **This is not something you have to read from top to bottom before trying out Leaf 3.** While it looks like a lot has changed, a lot of what you know and love about Leaf is still the same; but we wanted to be as thorough as possible and provide detailed explanations and examples for every documented change.
-
-::: warning Coming from another library
-Migrating from another framework? [READ THIS](/docs/migration/other) to get started.
-:::
-
-- [Quickstart](#quickstart)
-- [Breaking Changes](#breaking-changes)
-- [Notable New Features](#notable-new-features)
-
-
-
-
-## Quickstart
-
-If you want to quickly try out Leaf 3 in a new project, create a folder and run:
-
-```bash
-composer require leafs/leaf
-```
-
-This will quickly setup a leaf 3 with the default modules. From there, create your `index.php` file and add this quickstart.
-
-
-
-When using functional mode:
-
-```php
-get("/", function () {
- response()->json(["name" => "Leaf"]);
-});
-
-app()->run();
-```
-
-
-
-
-When using classes:
-
-```php
-get("/", function () use($app) {
- $app->response()->json(["name" => "Leaf"]);
-});
-
-$app->run();
-```
-
-
-
-You can run this with the built in php server
-
-```bash
-php -S localhost:5500
-```
-
-Alternatively, you can use the Leaf CLI:
-
-```bash
-leaf create
-```
-
-And run the sample app with:
-
-```bash
-leaf serve
-```
-
-### Migrating from leaf 2
-
-As mentioned before, we've made leaf 3 as backwards compatible with Leaf 2.5+ as possible. This means that moving from v2 to v3 will be a breeze or close.
-
-- Install leaf 3
-
-```bash
-composer require leafs/leaf
-```
-
-Or with leaf CLI
-
-```bash
-leaf install leaf
-```
-
-::: tip Watch out
-You should probably delete your `vendor` folder and `package-lock.json` before running the command above to make sure that all the dependencies are accurately reinstalled.
-:::
-
-- After this, it's just a matter of installing the modules required in your project.
-For example, if you use `Leaf\Auth`, you will need to install the auth module. This can be done with:
-
-```bash
-leaf install auth
-```
-
-Or with composer:
-
-```bash
-composer require leafs/auth
-```
-
-Just do this for all other modules in your project. And your app should be back online, working even faster than before.
-
-## Breaking Changes
-
-The following consists a list of breaking changes from 2.x:
-
-### Modules
-
-Leaf 3 only retains the core of the framework with a few utilities, all other features were packaged as modules. This means that you will have errors if you try to use some packages like `Leaf\Auth` or `Leaf\Flash` without installing them first.
-
-This is not really a problem since installing the module will automatically fix any problems that came along with it's abscence.
-
-### CORS
-
-In v2, some basic cors configuration was available on the Leaf object, however, this has been discontinued and replaced with the Cors module. This module contains both basic and advanced CORS configurations and is inspired by the ExpressJS cors package. So if you have any experience with that library, you will have no problems using the leaf cors module.
-
-To fix any problems with cors in your Leaf 2 app, follow these steps:
-
-- Install the cors module
-
-```bash
-composer require leafs/cors
-```
-
-- Replace the original cors configuration with the cors module. (This is done under the hood for you, all you need to do now call the cors method on your leaf app)
-
-
-
-Replace this:
-
-```php
-$app = new Leaf\App;
-
-$app->evadeCors(true);
-
-// ...
-```
-
-with...
-
-```php
-$app = new Leaf\App;
-
-$app->cors();
-
-// ...
-```
-
-
-
-
-Replace this:
-
-```php
-app()->evadeCors(true);
-
-// ...
-```
-
-with...
-
-```php
-app()->cors();
-
-// ...
-```
-
-
-
-The cors method is automatically linked to the cors module by Leaf and so, no extra configuration is needed to make it work. Cors takes in some optional configuration, checkout the [cors module docs](/modules/cors/). Also cors is no longer available on the response object.
-
-### Router
-
-`Leaf\Router::getRequestMethod` has been been moved to `Leaf\Http\Request::getMethod`. This is used in Leaf's core and should not be an issue, but if you do have references to this function, changing it to `Leaf\Http\Request::getMethod` will fix any errors.
-
-## Notable New Features
-
-Some of the new features to keep an eye on in Leaf 3 include:
-
-- [Global functions](/docs/tooling/functions)
-- [CORS module](/modules/cors/)
diff --git a/src/docs/migration/leafapi.md b/src/docs/migration/leafapi.md
deleted file mode 100644
index 152e818d..00000000
--- a/src/docs/migration/leafapi.md
+++ /dev/null
@@ -1,130 +0,0 @@
-# Introduction
-
-::: tip
-Leaf 3 is not yet available with Leaf 3. This means that you need to add Leaf 3 to your project manually.
-:::
-
-This guide is primarily for Leaf API users with prior Leaf 2 experience who want to learn about the new features and changes in Leaf 3.
-
-- [Quickstart](#quickstart)
-- [Breaking Changes](#breaking-changes)
-- [Notable New Features](#notable-new-features)
-- [Supporting Libraries](#supporting-libraries)
-
-
-
-## Quickstart
-
-If you want to quickly try out Leaf 3 in a new project:
-
-```bash
-composer require leafs/leaf v3.x-dev
-```
-
-This will quickly setup leaf 3 with the default modules. From there, create your `index.php` file and add this quickstart.
-
-```php
-get("/", function () {
- app()->response(["name" => "Leaf"]);
-});
-
-app()->run();
-```
-
-You can run this with the built in php server
-
-```bash
-php -S localhost:5500
-```
-
-### Migrating from leaf 2
-
-As mentioned before, we've made leaf 3 as backwards compatible with Leaf 2.5+ as possible. This means that moving from v2 to v3 will be a breeze or close.
-
-::: warning
-Note that leaf 3 is still under active development. We don't recommend switching to Leaf 3 yet for production ready apps. You can go ahead if it's a personal project or just want to try out leaf 3.
-:::
-
-- Install leaf 3
-
-```bash
-composer require leafs/leaf v3.x-dev
-```
-
-> You can delete your vendor folder before running the command above to make sure that all the dependencies are accurately reinstalled.
-
-- After this, it's just a matter of installing the modules required in your project.
-For example, if you use `Leaf\Auth`, you will need to install the auth module. This can be done with:
-
-```bash
-composer require leafs/auth
-```
-
-Just do this for all other modules in your project. And your app should be back online, working even faster than before.
-
-## Breaking Changes
-
-The following consists a list of breaking changes from 2.x:
-
-### Modules
-
-Leaf 3 only retains the core of the framework with a few utilities, all other features were packaged as modules. This means that you will have errors if you try to use some packages like `Leaf\Auth` or `Leaf\Flash` without installing them first.
-
-This is not really a problem since installing the module will automatically fix any problems that came along with it's abscence.
-
-### CORS
-
-In v2, some basic cors configuration was available on the Leaf object, however, this has been discontinued and replaced with the Cors module. This module contains both basic and advanced CORS configurations and is inspired by the ExpressJS cors package. So if you have any experience with that library, you will have no problems using the leaf cors module.
-
-To fix any problems with cors in your Leaf 2 app, follow these steps:
-
-- Install the cors module
-
-```bash
-composer require leafs/cors
-```
-
-- Replace the original cors configuration with the cors module. (This is done under the hood for you, all you need to do now call the cors method on your leaf app)
-
-Replace this:
-
-```php
-$app = new Leaf\App;
-
-$app->evadeCors(true);
-
-// ...
-```
-
-with...
-
-```php
-$app = new Leaf\App;
-
-$app->cors();
-
-// ...
-```
-
-The cors method is automatically linked to the cors module by Leaf and so, no extra configuration is needed to make it work. Cors takes in some optional configuration, checkout the [cors module docs](/modules/cors/). Also cors is no longer available on the response object.
-
-### Router
-
-`Leaf\Router::getRequestMethod` has been been moved to `Leaf\Http\Request::getMethod`. This is used in Leaf's core and should not be an issue, but if you do have references to this function, changing it to `Leaf\Http\Request::getMethod` will fix any errors.
-
-## Notable New Features
-
-Some of the new features to keep an eye on in Leaf 3 include:
-
-
-
-- [CORS module](/modules/cors/)
diff --git a/src/docs/migration/leafmvc.md b/src/docs/migration/leafmvc.md
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/docs/migration/other.md b/src/docs/migration/other.md
deleted file mode 100644
index 8fed725f..00000000
--- a/src/docs/migration/other.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-aside: none
----
-
-# Migrating from other frameworks
-
-
-
-This page is for developers who have a working application in another framework and want to port over to Leaf. As far-fetched as this sounds, Leaf 3 makes it super easy to sprinkle pieces of Leaf into any existing application, gradually rewriting it without breaking any code. Leaf has always allowed users to integrate other libraries seamlessly into their leaf apps with no conflicts or complexities, now Leaf 3 allows you to go the other way: **integrating Leaf seamlessly into any application no matter which libraries or frameworks it was built with.**
-
-
-
-## Quickstart
-
-All of Leaf's features are now available as modules, this means that if there's a particular feature of Leaf you will love to try out, there's no need to pack the whole framework anymore. Just find that feature you want and install it.
-
-Below is a [Slim PHP 4](https://www.slimframework.com/) application which we want to use Leaf 3 in:
-
-```php
-get('/', function (Request $request, Response $response, $args) {
- $name = $args['name'];
- $response->getBody()->write("Hello, $name");
- return $response;
-});
-
-$app->run();
-```
-
-We can start off by swapping out the Slim request and response objects with Leaf's. We can achieve this by replacing only lines 11-13 with Leaf.
-
-```php{2-3,11-13}
-get('/', function (Request $request, Response $response, $args) {
- $name = $args['name'];
- $response->getBody()->write("Hello, $name");
- return $response;
-});
-
-$app->run();
-```
-
-All we have to do now is to install the leaf http module.
-
-```bash
-composer require leafs/http
-```
-
-Now, we replace Slim's http handlers with Leaf's.
-
-
-
-```php{8,11-12}
-get('/', function () use($leaf) {
- $name = $leaf->request()->get('name');
- $leaf->response()->markup("Hello, $name");
-});
-
-$app->run();
-```
-
-
-
-
-```php{9-10}
-get('/', function () {
- $name = request()->get('name');
- response()->markup("Hello, $name");
-});
-
-$app->run();
-```
-
-
-
-In all aspects, this is still a slim 4 app, only using the Leaf request and response objects. Just as with the example above, you can use any Leaf module or Leaf 3 itself with any framework or library. To test the app above, we can use the built in php server
-
-```bash
-php -S localhost:5500
-```
diff --git a/src/docs/migration/skeleton.md b/src/docs/migration/skeleton.md
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/docs/modules.md b/src/docs/modules.md
new file mode 100644
index 00000000..606a08c3
--- /dev/null
+++ b/src/docs/modules.md
@@ -0,0 +1,66 @@
+# Modules
+
+Modules are the building blocks of Leaf. They are independent pieces of Leaf's functionality available for use in your app. They are designed to be simple, easy to use, framework-agnostic, and can be used in any PHP project with nearly zero configuration.
+
+## Installing Modules
+
+Modules are just like regular PHP packages. You can install them using Composer. To install a module, run:
+
+```bash:no-line-numbers
+composer require leafs/
+```
+
+If you're using Leaf CLI, you can install a module without the `leafs/` prefix:
+
+```bash:no-line-numbers
+leaf install
+```
+
+## Using Modules
+
+Most modules integrate directly into Leaf, so you can use them with Leaf's functional mode. This gives you a little more performance and flexibility. The documentation for each module covers everything you need to know about using the module.
+
+## List of Modules
+
+*We update this list regularly. If you have a module you'd like to see here, feel free to [open an issue](https://github.com/leafsphp/docs/issues/new) or create a pull request on our documentation repository. Community created modules are welcome here too ❤️*
+
+| Project | Status | Description |
+| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
+| [alchemy](/docs/utils/testing) | [![Latest Stable Version](https://poser.pugx.org/leafs/alchemy/v/stable)](https://packagist.org/packages/leafs/alchemy) [![Total Downloads](https://poser.pugx.org/leafs/alchemy/downloads)](https://packagist.org/packages/leafs/alchemy) | Setup testing/linting for your PHP apps |
+| [aloe](/docs/mvc/console) | [![Latest Stable Version](https://poser.pugx.org/leafs/aloe/v/stable)](https://packagist.org/packages/leafs/aloe) [![Total Downloads](https://poser.pugx.org/leafs/aloe/downloads)](https://packagist.org/packages/leafs/aloe) | Smart console helper for Leaf MVC |
+| [anchor](/docs/security/anchor) | [![Latest Stable Version](https://poser.pugx.org/leafs/anchor/v/stable)](https://packagist.org/packages/leafs/anchor) [![Total Downloads](https://poser.pugx.org/leafs/anchor/downloads)](https://packagist.org/packages/leafs/anchor) | Built-in protection for your Leaf apps |
+| [auth](/docs/auth/) | [![Latest Stable Version](https://poser.pugx.org/leafs/auth/v/stable)](https://packagist.org/packages/leafs/auth) [![Total Downloads](https://poser.pugx.org/leafs/auth/downloads)](https://packagist.org/packages/leafs/auth) | Simple but powerful authentication system for your apps |
+| [bareui](/docs/frontend/bareui) | [![Latest Stable Version](https://poser.pugx.org/leafs/bareui/v/stable)](https://packagist.org/packages/leafs/bareui) [![Total Downloads](https://poser.pugx.org/leafs/bareui/downloads)](https://packagist.org/packages/leafs/bareui) | Dead simple templating engine with no compilation |
+| [blade](/docs/frontend/blade) | [![Latest Stable Version](https://poser.pugx.org/leafs/blade/v/stable)](https://packagist.org/packages/leafs/blade) [![Total Downloads](https://poser.pugx.org/leafs/blade/downloads)](https://packagist.org/packages/leafs/blade) | Laravel blade port for leaf |
+| [cookie](/docs/http/cookies) | [![Latest Stable Version](https://poser.pugx.org/leafs/cookie/v/stable)](https://packagist.org/packages/leafs/cookie) [![Total Downloads](https://poser.pugx.org/leafs/cookie/downloads)](https://packagist.org/packages/leafs/cookie) | Cookie management for your PHP apps |
+| [cors](/docs/http/cors) | [![Latest Stable Version](https://poser.pugx.org/leafs/cors/v/stable)](https://packagist.org/packages/leafs/cors) [![Total Downloads](https://poser.pugx.org/leafs/cors/downloads)](https://packagist.org/packages/leafs/cors) | CORS operations made simple |
+| [csrf](/docs/security/csrf) | [![Latest Stable Version](https://poser.pugx.org/leafs/csrf/v/stable)](https://packagist.org/packages/leafs/csrf) [![Total Downloads](https://poser.pugx.org/leafs/csrf/downloads)](https://packagist.org/packages/leafs/csrf) | CSRF protection for your Leaf apps |
+| [date](/docs/utils/date) | [![Latest Stable Version](https://poser.pugx.org/leafs/date/v/stable)](https://packagist.org/packages/leafs/date) [![Total Downloads](https://poser.pugx.org/leafs/date/downloads)](https://packagist.org/packages/leafs/date) | Dead simple PHP dates |
+| [db](/docs/database/) | [![Latest Stable Version](https://poser.pugx.org/leafs/db/v/stable)](https://packagist.org/packages/leafs/db) [![Total Downloads](https://poser.pugx.org/leafs/db/downloads)](https://packagist.org/packages/leafs/db) | Lightweight query builder for your PHP apps |
+| [devtools](/docs/config/debugging) | [![Latest Stable Version](https://poser.pugx.org/leafs/devtools/v/stable)](https://packagist.org/packages/leafs/devtools) [![Total Downloads](https://poser.pugx.org/leafs/devtools/downloads)](https://packagist.org/packages/leafs/devtools) | Developer tools for Leaf PHP |
+| [eien](/docs/swoole) | [![Latest Stable Version](https://poser.pugx.org/leafs/eien/v/stable)](https://packagist.org/packages/leafs/eien) [![Total Downloads](https://poser.pugx.org/leafs/eien/downloads)](https://packagist.org/packages/leafs/eien) | High-speed, high-performance server for leaf |
+| [exception](https://github.com/leafsphp/exceptions) | [![Latest Stable Version](https://poser.pugx.org/leafs/exception/v/stable)](https://packagist.org/packages/leafs/exception) [![Total Downloads](https://poser.pugx.org/leafs/exception/downloads)](https://packagist.org/packages/leafs/exception) | Leaf's exception wrapper (fork of whoops) |
+| [fetch](/docs/utils/fetch) | [![Latest Stable Version](https://poser.pugx.org/leafs/fetch/v/stable)](https://packagist.org/packages/leafs/fetch) [![Total Downloads](https://poser.pugx.org/leafs/fetch/downloads)](https://packagist.org/packages/leafs/fetch) | HTTP requests made simple |
+| [form](/docs/data/validation) | [![Latest Stable Version](https://poser.pugx.org/leafs/form/v/stable)](https://packagist.org/packages/leafs/form) [![Total Downloads](https://poser.pugx.org/leafs/form/downloads)](https://packagist.org/packages/leafs/form) | Form processes and validation |
+| [fs](/docs/utils/fs) | [![Latest Stable Version](https://poser.pugx.org/leafs/fs/v/stable)](https://packagist.org/packages/leafs/fs) [![Total Downloads](https://poser.pugx.org/leafs/fs/downloads)](https://packagist.org/packages/leafs/fs) | Awesome filesystem operations + file uploads |
+| [http](/docs/http/request) | [![Latest Stable Version](https://poser.pugx.org/leafs/http/v/stable)](https://packagist.org/packages/leafs/http) [![Total Downloads](https://poser.pugx.org/leafs/http/downloads)](https://packagist.org/packages/leafs/http) | Http operations made simple (request, response, ...) |
+| [inertia](/docs/frontend/inertia) | [![Latest Stable Version](https://poser.pugx.org/leafs/inertia/v/stable)](https://packagist.org/packages/leafs/inertia) [![Total Downloads](https://poser.pugx.org/leafs/inertia/downloads)](https://packagist.org/packages/leafs/inertia) | Leaf adapter for inertia JS |
+| [logger](/docs/config/debugging) | [![Latest Stable Version](https://poser.pugx.org/leafs/logger/v/stable)](https://packagist.org/packages/leafs/logger) [![Total Downloads](https://poser.pugx.org/leafs/logger/downloads)](https://packagist.org/packages/leafs/logger) | leaf logger module |
+| [mail](/docs/utils/mail/) | [![Latest Stable Version](https://poser.pugx.org/leafs/mail/v/stable)](https://packagist.org/packages/leafs/mail) [![Total Downloads](https://poser.pugx.org/leafs/mail/downloads)](https://packagist.org/packages/leafs/mail) | Mailing made easy with leaf |
+| [mvc-core](/docs/mvc/) | [![Latest Stable Version](https://poser.pugx.org/leafs/mvc-core/v/stable)](https://packagist.org/packages/leafs/mvc-core) [![Total Downloads](https://poser.pugx.org/leafs/mvc-core/downloads)](https://packagist.org/packages/leafs/mvc-core) | Brain of Leaf MVC |
+| [password](/docs/data/encryption) | [![Latest Stable Version](https://poser.pugx.org/leafs/password/v/stable)](https://packagist.org/packages/leafs/password) [![Total Downloads](https://poser.pugx.org/leafs/password/downloads)](https://packagist.org/packages/leafs/password) | Password encryption/validation/hashing in one box |
+| [redis](/docs/database/redis) | [![Latest Stable Version](https://poser.pugx.org/leafs/redis/v/stable)](https://packagist.org/packages/leafs/redis) [![Total Downloads](https://poser.pugx.org/leafs/redis/downloads)](https://packagist.org/packages/leafs/redis) | Functionality for Redis |
+| [router](/docs/routing/) | [![Latest Stable Version](https://poser.pugx.org/leafs/router/v/stable)](https://packagist.org/packages/leafs/router) [![Total Downloads](https://poser.pugx.org/leafs/router/downloads)](https://packagist.org/packages/leafs/router) | Leaf Router copy for use outside of Leaf |
+| [session](/docs/http/session) | [![Latest Stable Version](https://poser.pugx.org/leafs/session/v/stable)](https://packagist.org/packages/leafs/session) [![Total Downloads](https://poser.pugx.org/leafs/session/downloads)](https://packagist.org/packages/leafs/session) | PHP sessions made simple |
+| [vite](/docs/frontend/vite) | [![Latest Stable Version](https://poser.pugx.org/leafs/vite/v/stable)](https://packagist.org/packages/leafs/vite) [![Total Downloads](https://poser.pugx.org/leafs/vite/downloads)](https://packagist.org/packages/leafs/vite) | Leaf server component for Vite |
+
+
+
+
+## Community Modules
+
+This is a list of modules created by the Leaf community. These modules are not officially maintained by the Leaf team, but they are welcome here. If you have a module you'd like to see here, feel free to [open an issue](https://github.com/leafsphp/docs/issues/new) or create a pull request on our documentation repository.
+
+| Project | Status | Description |
+| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
+| [devcycle/devcycle-leaf-plugin](https://github.com/DevCycleHQ-Sandbox/devcycle-leaf-plugin) | [![Latest Stable Version](https://poser.pugx.org/devcycle/devcycle-leaf-plugin/v/stable)](https://packagist.org/packages/devcycle/devcycle-leaf-plugin) [![Total Downloads](https://poser.pugx.org/devcycle/devcycle-leaf-plugin/downloads)](https://packagist.org/packages/devcycle/devcycle-leaf-plugin) | Devcycle Leaf Module |
diff --git a/src/docs/mvc/commands.md b/src/docs/mvc/commands.md
index 6382aa8f..d0d30534 100644
--- a/src/docs/mvc/commands.md
+++ b/src/docs/mvc/commands.md
@@ -1,34 +1,18 @@
# Writing Commands
-Leaf MVC and Leaf API come with a [built-in command line](/docs/mvc/console) interface named Aloe. This CLI is used to run commands and perform tasks like creating controllers, models, migrations, seeds, etc.
+Commands offer a way to encapsulate a piece of functionality that can be executed by yourself or other developers. They are a great way to automate repetitive tasks, such as setting up a new project, running tests, or deploying your app.
-In addition to the built-in commands, you can also create your own commands. This is useful if you want to create a command that performs a specific task in your application.
+Leaf MVC comes with a powerful command line interface and a bunch of helpful commands to get you started, however, you can also create your own commands to automate your own tasks.
-## Generating a command
+## Creating a command
-The easiest way to create a command is to use the `g:command` command. This command will create a new command class in your `app/console` directory.
+You can create a new command using the `g:command` command. This command will create a new command class in your `app/console` directory.
-```bash
-php leaf g:command CachePurge
-```
-
-This will create a `CachePurgeCommand` in the `app/console` directory. Instead of using the class name, you can also create commands using the command you want to run in your console like this:
-
-```bash
+```bash:no-line-numbers
php leaf g:command cache:purge
```
-This will create a `CachePurgeCommand` in the `app/console` directory.
-
-Using the `g:command` command also registers the commands in Aloe. This means you can run the command immediately after creating it.
-
-## Manually writing a command
-
-If you don't use the `g:command` command, you can create a command manually. To do this, create a new class in your `app/console` directory and extend the `Aloe\Command` class. The class should also have `$defaultName` and `$description` properties.
-
-The `$defaultName` property is the name of the command that will be used to run the command in the console. The `$description` property is a short description of what the command does.
-
-The class should have a `handle()`. This method is called when the command is run in the console. The `handle` method should return `0` if the command was successful and `1` if it failed.
+This will create a `CachePurgeCommand.php` file in your `app/console` directory. The file will contain a class that extends the `Command` class and implements the `handle()` method.
```php
comment(
- "example command's output {$this->argument('argument')} {$this->option('option')}"
+ "cache:purge command's output {$this->argument('argument')} {$this->option('option')}"
);
return 0;
@@ -61,45 +45,67 @@ class ExampleCommand extends Command
}
```
-Both Leaf MVC and Leaf API ship with an example command. You can find it in the `app/console` directory.
+Leaf MVC's aloe command line tool is built on top of Symfony's console component, so you can use the same methods and properties you would use in a Symfony command. You can read more about Symfony Console [here](https://symfony.com/doc/current/components/console.html).
-::: tip Symfony Console
-Aloe is built on top of Symfony Console. This means you can use all of the features of Symfony Console in your commands. You can read more about Symfony Console [here](https://symfony.com/doc/current/components/console.html).
-:::
+## Manually creating a command
-## Registering Commands
+All commands created through the `g:command` command are stored in the `app/console` directory and are automatically loaded by Leaf MVC. However, you can also create a command manually by creating a new class that extends the `Command` class and implementing the `handle()` method just like the example above.
-By default, aloe cli registers all generated commands, however, if you create a command manually, you'll have to register it manually. There are also situations where a package might need you to register a command, it can also be done using same method.
+```php
+register(\App\Console\ExampleCommand::class);
-```
+use Aloe\Command;
-An example command has already been registered, so you can follow this example. You can call the `register` method on the `$console` variable. The `register` method takes in the command class as a parameter.
+class CachePurgeCommand extends Command
+{
+ protected static $defaultName = 'cache:purge';
+ public $description = 'cache:purge command\'s description';
+ public $help = 'cache:purge command\'s help';
-```php
-$console->register(\App\Console\YourCommand::class);
+ protected function config()
+ {
+ $this
+ ->setArgument('argument', 'optional', 'argument description')
+ ->setOption('option', 'o', 'required', 'option description');
+ }
+
+ protected function handle()
+ {
+ $this->comment(
+ "cache:purge command's output {$this->argument('argument')} {$this->option('option')}"
+ );
+
+ return 0;
+ }
+}
```
-You can also pass in an array of commands to register, as such, a custom package with a couple of commands to register can simply return an array of all those commands.
+You can register this component by heading over to the `app/console/commands.php` file and adding the command to the `register()` method.
```php
-$console->register([
- \App\Console\AppCommand::class,
- \App\Console\AppCommand2::class,
-]);
+register(CustomPackage::commands());
+namespace App\Console;
+
+class Commands
+{
+ /**
+ * Register commands
+ *
+ * @param $console
+ * @return void
+ *
+ */
+ public static function register($console): void
+ {
+ $console->register([
+ ExampleCommand::class,
+ CachePurgeCommand::class
+ ]);
+ }
+}
```
## Command Arguments
@@ -368,33 +374,3 @@ This method asks a question but hides the keystrokes. It takes in 2 parameters:
```php
$password = $this->secret('Confirm your password');
```
-
-## Aloe Installer
-
-Aloe installer allows you to quickly install files and routes from your library into your Leaf MVC or Leaf API project's working directory.
-
-### Magic Copy
-
-This method allows you to auto-magically copy all files and folders from a specified folder into Leaf workspace.
-
-```php
-Aloe\Installer::magicCopy("package/to/install");
-```
-
-Consider the following directory structure:
-
-```bash
-C:.
-└───Auth
- ├───controllers
- ├───routes
- └───views
-```
-
-To copy our controllers, routes and views, we simply need to point `magicCopy` to the auth directory.
-
-```php
-\Aloe\Installer::magicCopy('package/Auth');
-```
-
-This will copy the sub directories in Auth to the `app` folder in the working directory. This is especially useful in team projects where you want to share resources with your team. You can simply create a package with the resources you want to share and then use `magicCopy` to copy them into the working directory.
diff --git a/src/docs/mvc/config.md b/src/docs/mvc/config.md
deleted file mode 100644
index 4c2bb11f..00000000
--- a/src/docs/mvc/config.md
+++ /dev/null
@@ -1,734 +0,0 @@
-# Configuration
-
-
-
-Both Leaf MVC and Leaf API try to maintain a working out-of-the-box configuration as much as possible, so, for the most part, you don't have to configure anything. However, there are some things you may want to customize to match your application's style, and this page will show you how.
-
-## Overview
-
-You can find your application in the `config` directory. This directory contains all the configuration files for you need for different features. You only need to configure the files that you need to configure. If you don't need to configure a file, you can just leave it as is. Each option is documented, so feel free to look through the files and get familiar with the options available to you.
-
-These configuration files allow you to configure things like your database connection information, your mail server information, as well as various other core configuration values such as your application timezone and encryption key.
-
-For the most part, you will only need to set the values in the `.env` file.
-
-## The `.env` file
-
-Having different configuration values based on the environment in which an application is operating is usually pretty helpful. For instance, you may need to use a different database for local development compared to your production server.
-
-The `.env` file allows you to define environment specific configuration values. You can define as many environment variables as you want in this file. The values in this file will be loaded into the `$_ENV` superglobal variable, and will be accessible via the `_env()` helper function.
-
-In a new Leaf installation, the root folder of your application will include an `.env.example` file that specifies numerous typical environment variables. As part of the Leaf installation process, this file will be automatically duplicated to `.env`. You may then modify the `.env` file to suit your needs. The `.env` file is not tracked by Git, so you can safely modify it without worrying about it being overwritten by future updates.
-
-::: tip Managing Environment Variables
-
-If you add new environment variables to a team project, be sure to add the keys to the `.env.example` file so that other developers will know what environment variables are available.
-
-:::
-
-*If you want more info on how Leaf handles your application's environment, you can check out the [environment docs](/docs/config/nsm).*
-
-## Application Config
-
-This configuration basically controls how Leaf works with your application. This file contains the following options by default:
-
-```php
- _env('APP_DOWN', false),
-
- /*
- |--------------------------------------------------------------------------
- | App debugging
- |--------------------------------------------------------------------------
- |
- | If debugging is enabled, Leaf will use its built-in error handler to
- | display diagnostic information for uncaught Exceptions, else it will
- | display a bare error page usable in production. You can set a
- | custom error page to display using `$app->setError`.
- |
- | You might want to turn this off in production.
- |
- */
- 'debug' => _env('APP_DEBUG', true),
-
- /*
- |--------------------------------------------------------------------------
- | Log directory
- |--------------------------------------------------------------------------
- |
- | This tells leaf which directory to save and look for logs.
- |
- */
- 'log.dir' => 'storage/logs/',
-
- /*
- |--------------------------------------------------------------------------
- | Log Enabled
- |--------------------------------------------------------------------------
- |
- | This enables or disables Leaf’s logger. Note that if log.enabled is
- | set to false. Leaf will skip initializing anything related to logs,
- | as such, you won't have access to $app->logger(),
- | $app->log or $app->logWriter.
- |
- */
- 'log.enabled' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Log file
- |--------------------------------------------------------------------------
- |
- | This setting tells leaf which file to write logs to.
- |
- */
- 'log.file' => 'app.log',
-
- /*
- |--------------------------------------------------------------------------
- | Log level
- |--------------------------------------------------------------------------
- |
- | Leaf has these log levels:
- |
- | - \Leaf\Log::EMERGENCY
- | - \Leaf\Log::ALERT
- | - \Leaf\Log::CRITICAL
- | - \Leaf\Log::ERROR
- | - \Leaf\Log::WARN
- | - \Leaf\Log::NOTICE
- | - \Leaf\Log::INFO
- | - \Leaf\Log::DEBUG
- |
- */
- 'log.level' => \Leaf\Log::DEBUG,
-
- /*
- |--------------------------------------------------------------------------
- | Log open
- |--------------------------------------------------------------------------
- |
- | Takes in a boolean and determines whether Leaf should create
- | the specified log file if it doesn't exist.
- |
- */
- 'log.open' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Log writer
- |--------------------------------------------------------------------------
- |
- | Use a custom log writer to direct logged messages
- | to the appropriate output destination.
- |
- */
- 'log.writer' => null,
-
- /*
- |--------------------------------------------------------------------------
- | Mode
- |--------------------------------------------------------------------------
- |
- | This is an identifier for the application’s current mode of operation.
- | The mode does not affect a Leaf application’s internal functionality.
- |
- */
- 'mode' => 'development',
-
- /*
- |--------------------------------------------------------------------------
- | Views path
- |--------------------------------------------------------------------------
- |
- | The relative or absolute path to the filesystem directory that
- | contains your Leaf application’s view files.
- |
- */
- 'views.path' => ViewsPath(null, false),
-
- /*
- |--------------------------------------------------------------------------
- | views cache path
- |--------------------------------------------------------------------------
- |
- | This config tells leaf where to save cached and compiled views.
- |
- */
- 'views.cachePath' => StoragePath('framework/views')
-];
-```
-
-You can find more information about these settings in the [App Config](/docs/config/settings.html) documentation.
-
-## Aloe CLI Config
-
-This configuration file is used to configure the Aloe CLI. This file basically contains a map of paths that directs Aloe where to find framework files. This file contains the following options by default:
-
-```php
-// config for aloe CLI
-return [
- 'paths' => [
- 'controllers_path' => '/app/controllers',
- 'models_path' => '/app/models',
- 'migrations_path' => '/app/database/migrations',
- 'seeds_path' => '/app/database/seeds',
- 'factories_path' => '/app/database/factories',
- 'helpers_path' => '/app/helpers',
- 'views_path' => '/app/views',
- 'config_path' => '/app/config',
- 'storage_path' => '/storage',
- 'commands_path' => '/app/console',
- 'routes_path' => '/app/routes',
- 'lib_path' => '/lib',
- ],
-];
-```
-
-You only need to configure this file if you want to change the default paths.
-
-## Auth Config
-
-This configuration file is used to configure [Leaf Auth](/modules/auth/). You only need to update this config if you want to switch up the way Leaf Auth works out of the box. This file contains the following options by default:
-
-```php
-use Leaf\Helpers\Password;
-
-return [
- /*
- |--------------------------------------------------------------------------
- | Database table
- |--------------------------------------------------------------------------
- |
- | This is the table that leaf auth will perform authentication
- | checks on and edit/retrieve users from.
- |
- */
- 'DB_TABLE' => 'users',
-
- /*
- |--------------------------------------------------------------------------
- | Use session
- |--------------------------------------------------------------------------
- |
- | Use session based authentication instead of the default JWT based auth.
- |
- */
- 'USE_SESSION' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Generate timestamps
- |--------------------------------------------------------------------------
- |
- | Automatically generate created_at/updated_at timestamps for register
- | and update methods
- |
- */
- 'USE_TIMESTAMPS' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Encode password
- |--------------------------------------------------------------------------
- |
- | Password encode is run when leaf wants to encode passwords on register
- | This exact method is used by default in Leaf, so you can set it to null
- | if you want to.
- |
- | You can set your own implementation instead of Password::hash
- |
- */
- 'PASSWORD_ENCODE' => function ($password) {
- return Password::hash($password);
- },
-
- /*
- |--------------------------------------------------------------------------
- | Verify Password
- |--------------------------------------------------------------------------
- |
- | This function is run to verify the password. This implementation is done
- | by default, so you can set it to null, and it will still work fine.
- |
- | You can add your own implementation instead of Password::verify
- |
- */
- 'PASSWORD_VERIFY' => function ($password, $hashedPassword) {
- return Password::verify($password, $hashedPassword);
- },
-
- /*
- |--------------------------------------------------------------------------
- | Password Key
- |--------------------------------------------------------------------------
- |
- | The default password key. Leaf will expect this key to hold passwords
- | in your database.
- |
- */
- 'PASSWORD_KEY' => 'password',
-
- /*
- |--------------------------------------------------------------------------
- | Hide id
- |--------------------------------------------------------------------------
- |
- | Hide id field from user object returned in login, register and update
- |
- */
- 'HIDE_ID' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Hide password
- |--------------------------------------------------------------------------
- |
- | Hide password from user object returned in login, register and update
- |
- */
- 'HIDE_PASSWORD' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Login params error
- |--------------------------------------------------------------------------
- |
- | Error to show when the login params aren't found in db
- |
- */
- 'LOGIN_PARAMS_ERROR' => 'Username not registered!',
-
- /*
- |--------------------------------------------------------------------------
- | Password error
- |--------------------------------------------------------------------------
- |
- | Error to show when the login password is wrong
- |
- */
- 'LOGIN_PASSWORD_ERROR' => 'Password is incorrect!',
-
- /*
- |--------------------------------------------------------------------------
- | Session on register
- |--------------------------------------------------------------------------
- |
- | If true, a session will be created on a successful registration, else
- | you it'll be created on login rather.
- |
- */
- 'SESSION_ON_REGISTER' => false,
-
- /*
- |--------------------------------------------------------------------------
- | Login page route
- |--------------------------------------------------------------------------
- */
- 'GUARD_LOGIN' => '/auth/login',
-
- /*
- |--------------------------------------------------------------------------
- | Register page route
- |--------------------------------------------------------------------------
- */
- 'GUARD_REGISTER' => '/auth/register',
-
- /*
- |--------------------------------------------------------------------------
- | Logout route
- |--------------------------------------------------------------------------
- */
- 'GUARD_LOGOUT' => '/auth/logout',
-
- /*
- |--------------------------------------------------------------------------
- | Home page route
- |--------------------------------------------------------------------------
- */
- 'GUARD_HOME' => '/home',
-
- /*
- |--------------------------------------------------------------------------
- | JWT + Session
- |--------------------------------------------------------------------------
- |
- | Add an auth token to the auth session?
- |
- */
- 'SAVE_SESSION_JWT' => false,
-
- /*
- |--------------------------------------------------------------------------
- | JWT Token Secret
- |--------------------------------------------------------------------------
- |
- | Secret string to encode JWT
- |
- */
- 'TOKEN_SECRET' => '@_leaf$0Secret!',
-
- /*
- |--------------------------------------------------------------------------
- | JWT Lifetime
- |--------------------------------------------------------------------------
- |
- | How long should JWT be valid for?
- |
- */
- 'TOKEN_LIFETIME' => 60 * 60 * 24 * 365
-];
-```
-
-You can find more information about these settings in the [Auth Config](/modules/auth/v/2.1/config.html) documentation.
-
-## CORS config
-
-This config allows you pass options to the [Leaf CORS module](/modules/cors/). The default config looks like this:
-
-```php
-return [
- /*
- |--------------------------------------------------------------------------
- | Configure allowed origins
- |--------------------------------------------------------------------------
- |
- | Configures the Access-Control-Allow-Origin CORS header. Possible values:
- |
- | * String - set origin to a specific origin. For example if
- | you set it to "http://example.com" only requests from
- | "http://example.com" will be allowed.
- |
- | * RegExp - set origin to a regular expression pattern which will be
- | used to test the request origin. If it's a match, the request origin
- | will be reflected. For example the pattern /example\.com$/ will reflect
- | any request that is coming from an origin ending with "example.com".
- |
- | * Array - set origin to an array of valid origins. Each origin can be a String
- | or a RegExp. For example ["http://example1.com", /\.example2\.com$/] will
- | accept any request from "http://example1.com" or from
- | a subdomain of "example2.com".
- |
- | * Function - set origin to a function implementing some custom
- | logic. The function takes the request origin as the first parameter
- | and a callback (called as callback(err, origin), where origin is a
- | non-function value of the origin option) as the second.
- |
- */
- 'origin' => '*',
-
- /*
- |--------------------------------------------------------------------------
- | Configure allowed HTTP methods
- |--------------------------------------------------------------------------
- |
- | Configures the Access-Control-Allow-Methods CORS header.
- | Expects a comma-delimited string (ex: 'GET,PUT,POST') or
- | an array (ex: ['GET', 'PUT', 'POST'])
- |
- */
- 'methods' => 'GET,HEAD,PUT,PATCH,POST,DELETE',
-
- /*
- |--------------------------------------------------------------------------
- | Configure allowed HTTP headers
- |--------------------------------------------------------------------------
- |
- | Configures the Access-Control-Allow-Headers CORS header. Expects a
- | comma-delimited string (ex: 'Content-Type,Authorization') or
- | an array (ex: ['Content-Type', 'Authorization']). If not specified,
- | defaults to reflecting the headers specified in the request's
- | Access-Control-Request-Headers header.
- |
- */
- 'allowedHeaders' => '*',
-
- /*
- |--------------------------------------------------------------------------
- | Configure expose headers
- |--------------------------------------------------------------------------
- |
- | Configures the Access-Control-Expose-Headers CORS header. Expects
- | a comma-delimited string (ex: 'Content-Range,X-Content-Range')
- | or an array (ex: ['Content-Range', 'X-Content-Range']).
- | If not specified, no custom headers are exposed.
- |
- */
- 'exposedHeaders' => '',
-
- /*
- |--------------------------------------------------------------------------
- | Configure credentials
- |--------------------------------------------------------------------------
- |
- | Configures the Access-Control-Allow-Credentials CORS header.
- | Set to true to pass the header, otherwise it is omitted.
- |
- */
- 'credentials' => false,
-
- /*
- |--------------------------------------------------------------------------
- | Configure max age
- |--------------------------------------------------------------------------
- |
- | Configures the Access-Control-Max-Age CORS header. Set to
- | an integer to pass the header, otherwise it is omitted.
- |
- */
- 'maxAge' => null,
-
- /*
- |--------------------------------------------------------------------------
- | Configure preflight continue
- |--------------------------------------------------------------------------
- |
- | Pass the CORS preflight response to the next handler.
- |
- */
- 'preflightContinue' => false,
-
- /*
- |--------------------------------------------------------------------------
- | Log open
- |--------------------------------------------------------------------------
- |
- | Provides a status code to use for successful OPTIONS requests,
- | since some legacy browsers (IE11, various SmartTVs) choke on 204.
- |
- */
- 'optionsSuccessStatus' => 204,
-];
-```
-
-You can find more information on the configuration options on the [cors config docs](/modules/cors/#configuration-options).
-
-## Database config
-
-This config allows you to configure the database connection. The default config looks like this:
-
-```php
-return [
-
- /*
- |--------------------------------------------------------------------------
- | Default Database Connection Name
- |--------------------------------------------------------------------------
- |
- | Here you may specify which of the database connections below you wish
- | to use as your default connection for all database work. Of course
- | you may use many connections at once using the Database library.
- |
- */
-
- 'default' => _env('DB_CONNECTION', 'mysql'),
-
- /*
- |--------------------------------------------------------------------------
- | Database Connections
- |--------------------------------------------------------------------------
- |
- | Here are each of the database connections setup for your application.
- | Of course, examples of configuring each database platform that is
- | supported by eloquent is shown below to make development simple.
- |
- |
- | All database work in eloquent is done through the PHP PDO facilities
- | so make sure you have the driver for your particular database of
- | choice installed on your machine before you begin development.
- |
- */
-
- 'connections' => [
- 'sqlite' => [
- 'driver' => 'sqlite',
- 'url' => _env('DATABASE_URL'),
- 'database' => _env('DB_DATABASE', DatabasePath('database.sqlite')),
- 'prefix' => '',
- 'foreign_key_constraints' => _env('DB_FOREIGN_KEYS', true),
- ],
-
- 'mysql' => [
- 'driver' => 'mysql',
- 'url' => _env('DATABASE_URL'),
- 'host' => _env('DB_HOST', '127.0.0.1'),
- 'port' => _env('DB_PORT', '3306'),
- 'database' => _env('DB_DATABASE', 'forge'),
- 'username' => _env('DB_USERNAME', 'forge'),
- 'password' => _env('DB_PASSWORD', ''),
- 'unix_socket' => _env('DB_SOCKET', ''),
- 'charset' => _env('DB_CHARSET', 'utf8mb4'),
- 'collation' => _env('DB_COLLATION', 'utf8mb4_unicode_ci'),
- 'prefix' => '',
- 'prefix_indexes' => true,
- 'strict' => true,
- 'engine' => null,
- 'options' => extension_loaded('pdo_mysql') ? array_filter([
- PDO::MYSQL_ATTR_SSL_CA => _env('MYSQL_ATTR_SSL_CA'),
- ]) : [],
- ],
-
- 'pgsql' => [
- 'driver' => 'pgsql',
- 'url' => _env('DATABASE_URL'),
- 'host' => _env('DB_HOST', '127.0.0.1'),
- 'port' => _env('DB_PORT', '5432'),
- 'database' => _env('DB_DATABASE', 'forge'),
- 'username' => _env('DB_USERNAME', 'forge'),
- 'password' => _env('DB_PASSWORD', ''),
- 'charset' => _env('DB_CHARSET', 'utf8'),
- 'prefix' => '',
- 'prefix_indexes' => true,
- 'schema' => 'public',
- 'sslmode' => 'prefer',
- ],
-
- 'sqlsrv' => [
- 'driver' => 'sqlsrv',
- 'url' => _env('DATABASE_URL'),
- 'host' => _env('DB_HOST', 'localhost'),
- 'port' => _env('DB_PORT', '1433'),
- 'database' => _env('DB_DATABASE', 'forge'),
- 'username' => _env('DB_USERNAME', 'forge'),
- 'password' => _env('DB_PASSWORD', ''),
- 'charset' => _env('DB_CHARSET', 'utf8'),
- 'prefix' => '',
- 'prefix_indexes' => true,
- ],
- ],
-];
-```
-
-This config has been modified to use the `_env` helper function. This helper function will check if the environment variable is set and if not, it will return the default value. This is useful for when you want to use the same config file for both development and production. Leaf will automatically use the connection details from the selected db type (`DB_CONNECTION`) in the `.env` file.
-
-The database config is used by your application models, Leaf DB and Leaf Auth to connect to the database.
-
-## Paths config
-
-The paths config allows you to configure the paths to your application's folders. The default config looks like this:
-
-```php
-return [
- 'controllersPath' => 'app/controllers',
-
- 'modelsPath' => 'app/models',
-
- 'migrationsPath' => 'app/database/migrations',
-
- 'seedsPath' => 'app/database/seeds',
-
- 'factoriesPath' => 'app/database/factories',
-
- 'helpersPath' => 'app/helpers',
-
- 'viewsPath' => 'app/views',
-
- 'configPath' => 'config',
-
- 'storagePath' => 'storage',
-
- 'commandsPath' => 'app/console',
-
- 'routesPath' => 'app/routes',
-
- 'libPath' => 'lib',
-
- 'publicPath' => 'public',
-
- 'databaseStoragePath' => 'storage/app/db'
-];
-```
-
-The paths config is used by Leaf to locate your application's folders. If you want to change the default paths, you can do so in the `config/paths.php` file.
-
-## View Config
-
-The view config allows you to configure the view engine and the view cache. The default config looks like this:
-
-```php
-use Leaf\View;
-
-return [
- /*
- |--------------------------------------------------------------------------
- | Template Engine [EXPERIMENTAL]
- |--------------------------------------------------------------------------
- |
- | Leaf MVC unlike other frameworks tries to give you as much control as
- | you need. As such, you can decide which view engine to use.
- |
- */
- 'view_engine' => \Leaf\Blade::class,
-
- /*
- |--------------------------------------------------------------------------
- | Custom config method
- |--------------------------------------------------------------------------
- |
- | Configuration for your templating engine.
- |
- */
- 'config' => function ($config) {
- View::blade()->config($config['views_path'], $config['cache_path']);
- },
-
- /*
- |--------------------------------------------------------------------------
- | Custom render method
- |--------------------------------------------------------------------------
- |
- | This render method is triggered whenever render() is called
- | in your app if you're using a custom view engine.
- |
- */
- 'render' => null,
-];
-```
-
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf MVC.
-
-
diff --git a/src/docs/mvc/console.md b/src/docs/mvc/console.md
index 5b95e3ff..2f6474d4 100644
--- a/src/docs/mvc/console.md
+++ b/src/docs/mvc/console.md
@@ -2,403 +2,242 @@
-Leaf MVC and Leaf API come with a robust console tool to help you manage your app from the command line. We call this tool Aloe.
+Leaf MVC includes a powerful command-line tool called Aloe to help you manage your application from the terminal. With Aloe, you can scaffold projects, manage databases, and handle various app tasks efficiently, all with simple commands. To get started and see the list of all available commands, just run:
-Aloe comes with a predefined set of commands which provide project scaffolding, database and app management right from your terminal. To view all available commands, run `php leaf list` from your terminal.
-
-## Aloe CLI vs Leaf CLI
-
-Before we go any further, it's important to note that Aloe is not the same as Leaf CLI.
-
-Leaf CLI is a tool for creating and managing your Leaf applications, it is installed globally and can be used in Leaf and Leaf MVC/Leaf API applications. The Leaf CLI has a more generalized set of commands which can be used in any Leaf application.
-
-Aloe on the other hand is a tool for managing Leaf MVC and Leaf API applications. It is limited to the root directory of your Leaf MVC/Leaf API application and has a more specific set of commands which are only available in Leaf MVC/Leaf API applications.
-
-## Aloe Commands
-
-Aloe provides a large set of commands to ease your development process. Although they may look like a lot, we can group them into 6 categories:
-
-- App commands
-- Scaffold commands
-- Generate commands
-- Delete commands
-- Database commands
-- View commands
-
-## App Commands
-
-App commands are commands which help you manage your Leaf MVC/Leaf API application. These commands are used to manage your app's state, interact with your app and it's dependencies and more.
-
-### Serve
-
-The `serve` command is used to start the Leaf development server. It is the same as running `php -S localhost:[PORT]` from your terminal, but it also runs your app's bootstrapping process.
-
-To start the Leaf development server, run `php leaf serve` from your terminal. You can also specify a port to run the server on by running `php leaf serve --port=[PORT]`.
-
-```bash
-php leaf serve
-```
-
-### Interact
-
-The `interact` command is used to start the Leaf interactive shell. The interactive shell is a REPL (Read-Eval-Print-Loop) which allows you to interact with your app from the command line. It is powered by [PsySH](https://psysh.org/).
-
-```bash
-php leaf interact
-```
-
-### Up and Down
-
-The `app:up` and `app:down` commands are used to put your app in maintenance mode. When your app is in maintenance mode, all requests to your app will return a 503 response. This is useful when you want to take your app down for maintenance.
-
-To put your app in maintenance mode, run `php leaf app:down`. To take your app out of maintenance mode, run `php leaf app:up`.
-
-```bash
-php leaf app:down
-php leaf app:up
-```
-
-## Scaffold Commands
-
-Scaffold commands are commands which help you scaffold your Leaf MVC/Leaf API application. These commands are used to create new files and folders in your app. Some of these commands even scaffold entire flows for you.
-
-### Auth Scaffold
-
-The `auth:scaffold` command is used to scaffold basic authentication for your Leaf MVC/Leaf API application. It creates required models, controllers, views and routes, migrations and everything you need to get started with authentication. Depending on your flow, you may need to make some changes to the files generated by this command.
-
-Note that this command will generate different files depending on whether you're using Leaf MVC or Leaf API.
-
-If you're building a Leaf MVC app, this command will automatically scaffold a login and registration flow for you with views and controllers, however, since Leaf API comes with the View layer disabled, this command will only scaffold the required models, controllers, routes and migrations for you. All controllers in Leaf API will return JSON responses.
-
-You can force the command to generate files for Leaf MVC or Leaf API by passing the `--mvc` or `--api` flag respectively.
-
-```bash
-php leaf auth:scaffold
-php leaf auth:scaffold --mvc # force Leaf MVC
-php leaf auth:scaffold --api # force Leaf API
-```
-
-You can find the Leaf MVC authentication documentation [here](/modules/auth/mvc).
-
-### Mail Setup
-
-The `mail:setup` command is used to setup mailing in your Leaf MVC/Leaf API application. It installs the Leaf Mail package and creates a `mail.php` config file in your `config` folder as well as a demo mailer in your `app/mailers` folder.
-
-```bash
-php leaf mail:setup
-```
-
-Find the MVC Mail documentation [here](/docs/mvc/mail).
-
-### Env Generate
-
-The `env:generate` command is used to generate a `.env` file in your Leaf MVC/Leaf API application. It generates a `.env` file from your `.env.example` file and fills it with the values in your `.env.example` file.
-
-If there is no `.env.example` file in your app, this command will generate a `.env` file from scratch.
-
-```bash
-php leaf env:generate
-```
-
-### Devtools Install
-
-The `devtools:install` command is used to install and setup the Leaf PHP devtools in your Leaf MVC/Leaf API application.
-
-```bash
-php leaf devtools:install
-```
-
-You can find the Leaf PHP devtools documentation [here](/modules/devtools/).
-
-### View Install
-
-The `view:install` command is used to install and setup the frontend of your Leaf MVC/Leaf API application. It can be used to install any frontend framework of your choice, vite, tailwind or a template engine like bare ui. You can use the `--react`, `--vue`, `--blade`, and `--bareui` options to scaffold your frontend setup.
-
-```bash
-php leaf view:install --react
+```bash:no-line-numbers
+php leaf list
```
-You can also use the `--vite` and `--tailwind` options to scaffold Vite and Tailwind respectively.
+## Aloe vs. Leaf CLI: What's the Difference?
-```bash
-php leaf view:install --vite
-php leaf view:install --tailwind
-```
+Before diving in, it’s important to know that Aloe is different from Leaf CLI.
-You can check the [frontend documentation](/modules/views/) for more information.
+Leaf CLI is a general tool used for creating and managing any Leaf application. It's installed globally and works across different Leaf apps, including Leaf MVC.
-## Generate Commands
+Aloe is more specific. It's used only in the root directory of your Leaf MVC apps. Aloe has commands that are specifically designed for managing Leaf MVC projects.
-These commands are used to generate files like controllers, models, migrations, views and more directly into your app.
+## Aloe Command Categories
-### Generate Command
+Aloe commands are divided into six groups to help with different parts of your development process:
-The `g:command` command is used to generate a new console command in your Leaf MVC/Leaf API application. It creates a new command class in your `app/commands` folder.
+- App Commands: Manage your app's state and dependencies.
+- Scaffold Commands: Create files and structures in your app.
+- Generate Commands: Quickly create controllers, models, and more.
+- Delete Commands: Remove unwanted files.
+- Database Commands: Manage your app’s database.
+- View Commands: Build and serve your frontend.
-```bash
-php leaf g:command [name]
-```
+### App Commands
-### Generate Controller
+- Serve
-The `g:controller` command is used to generate a new controller in your Leaf MVC/Leaf API application. It creates a new controller class in your `app/controllers` folder.
+ To run your app, use the serve command, which starts a development server. It’s similar to running php -S localhost:[PORT], but with some added setup specific to Leaf.
-```bash
-php leaf g:controller [name]
-```
+ ```bash:no-line-numbers
+ php leaf serve
+ ```
-This command can also be used to generate a controller with a resource route. To generate a controller with a resource route, pass the `--resource` flag.
+ You can also specify a custom port:
-```bash
-php leaf g:controller [name] --resource
-```
+ ```bash:no-line-numbers
+ php leaf serve --port=8000
+ ```
-Resource controllers are controllers which have a route for every CRUD operation. You can find more information about resource controllers [here](/docs/mvc/controllers).
+- Interact
-You can also generate a controller and a model at the same time by passing the `--model` flag.
+ If you want to interact with your app directly in the terminal, use interact. This opens a REPL (Read-Eval-Print Loop) powered by PsySH.
-```bash
-php leaf g:controller [name] --model
-```
+ ```bash:no-line-numbers
+ php leaf interact
+ ```
-You can also generate a migration and model at the same time by passing the `--all` flag, or just `-a` for short.
+- Maintenance Mode
-```bash
-php leaf g:controller [name] --all
-php leaf g:controller [name] -a
-```
+ Sometimes you need to take your app down for maintenance. Use app:down to put your app in maintenance mode (it will return a 503 status), and app:up to bring it back online.
-### Generate Factory
+ ```bash:no-line-numbers
+ php leaf app:down
+ php leaf app:up
+ ```
-The `g:factory` command is used to generate a new model factory in your Leaf MVC/Leaf API application. It creates a new factory class in your `app/database/factories` folder.
+### Scaffold Commands
-```bash
-php leaf g:factory [name]
-```
+These commands help you quickly create files and structure your app.
-### Generate Helper
+- Scaffold Authentication
-The `g:helper` command is used to generate a new helper class in your Leaf MVC/Leaf API application. It creates a new helper class in your `app/helpers` folder.
+ Need basic user authentication? Use the auth:scaffold command to automatically generate everything you need for login and registration (routes, models, controllers, views, etc.).
-```bash
-php leaf g:helper [name]
-```
+ ```bash:no-line-numbers
+ php leaf auth:scaffold
+ ```
-### Generate Mailer
+ For a Leaf MVC app: generates full login and registration views and controllers. You can force it to generate API files using `--api`.
-The `g:mailer` command is used to generate a new mailer in your Leaf MVC/Leaf API application. It creates a new mailer class in your `app/mailers` folder.
+ ```bash:no-line-numbers
+ php leaf auth:scaffold --api
+ ```
-```bash
-php leaf g:mailer [name]
-```
+- Mail Setup
-### Generate Migration
+ To set up mailing for your app, run:
-The `g:migration` command is used to generate a new migration in your Leaf MVC/Leaf API application. It creates a new migration file in your `app/database/migrations` folder.
+ ```bash:no-line-numbers
+ php leaf mail:setup
+ ```
-```bash
-php leaf g:migration [name]
-```
+ This installs the Leaf Mail package and sets up the necessary configuration files.
-By default, this command assumes your table name from the migration name. For example, if you run `php leaf g:migration users`, the command will assume your table name is `users`. You can override this by passing the `--table` flag.
+### Generate Commands
-```bash
-php leaf g:migration [name] --table=[table_name]
-```
+These commands are used to generate files for your project, saving you time by automating tasks like creating controllers, models, migrations, etc.
-### Generate Model
+- Create a Controller
-The `g:model` command is used to generate a new model in your Leaf MVC/Leaf API application. It creates a new model class in your `app/models` folder.
+ To generate a new controller, use:
-```bash
-php leaf g:model [name]
-```
+ ```bash:no-line-numbers
+ php leaf g:controller [name]
+ ```
-If you want to generate a model with a migration, you can pass the `--migration` flag.
+ You can add a resource route (for standard CRUD operations) with:
-```bash
-php leaf g:model [name] --migration
-```
+ ```bash:no-line-numbers
+ php leaf g:controller [name] --resource
+ ```
-### Generate Seed
+ You can also create a controller with a model or migration:
-The `g:seed` command is used to generate a new seed file in your Leaf MVC/Leaf API application. It creates a new seed file in your `app/database/seeds` folder.
+ ```bash:no-line-numbers
+ php leaf g:controller [name] --model
+ php leaf g:controller [name] --all # or -a to generate everything
+ ```
-```bash
-php leaf g:seed [name]
-```
+- Create a Model
-### Generate Template
+ Need a model for your database? Generate one with:
-The `g:template` command is used to generate a new view file in your Leaf MVC/Leaf API application. It creates a new view file in your `resources/views` folder.
+ ```bash:no-line-numbers
+ php leaf g:model [name]
+ ```
-```bash
-php leaf g:template [name]
-```
+ To create a model with a migration, use:
-You can tell this command what kind of view file you want to create using the `--type` flag. The available types are `blade`, `jsx`, `vue` and `html`.
+ ```bash:no-line-numbers
+ php leaf g:model [name] --migration
+ ```
-```bash
-php leaf g:template [name] --type=blade
-php leaf g:template [name] --type=jsx
-php leaf g:template [name] --type=vue
-php leaf g:template [name] --type=html
-```
+- Other Generate Commands
-## Delete Commands
+ - Factory: php leaf g:factory [name]
+ - Helper: php leaf g:helper [name]
+ - Mailer: php leaf g:mailer [name]
+ - Migration: php leaf g:migration [name]
+ - Seed: php leaf g:seed [name]
+ - View Template: php leaf g:template [name] --type=[blade|jsx|vue|html]
-These commands are used to delete files like controllers, models, migrations, views and more directly from your app.
+### Delete Commands
-### Delete Command
+These are the reverse of generate commands—use them to delete files.
-The `d:command` command is used to delete a console command from your Leaf MVC/Leaf API application. It deletes a command class from your `app/commands` folder and automatically unregisters it from Aloe.
+- Delete Controller: php leaf d:controller [name]
+- Delete Model: php leaf d:model [name]
+- Delete Migration: php leaf d:migration [name]
+- Delete Seed: php leaf d:seed [name]
-```bash
-php leaf d:command [name]
-```
+### Database Commands
-### Delete Controller
+Leaf MVC makes database management easy with these commands.
-The `d:controller` command is used to delete a controller from your Leaf MVC/Leaf API application. It deletes a controller class from your `app/controllers` folder.
+- Create a Database
-```bash
-php leaf d:controller [name]
-```
+ To create a new database from the credentials in your .env file, use:
-### Delete Factory
+ ```bash:no-line-numbers
+ php leaf db:install
+ ```
-The `d:factory` command is used to delete a model factory from your Leaf MVC/Leaf API application. It deletes a factory class from your `app/database/factories` folder.
+- Migrate Database
-```bash
-php leaf d:factory [name]
-```
+ To run your migrations and set up your database schema, run:
-### Delete Migration
+ ```bash:no-line-numbers
+ php leaf db:migrate
+ ```
-The `d:migration` command is used to delete a migration from your Leaf MVC/Leaf API application. It deletes a migration file from your `app/database/migrations` folder.
+- Reset Database
-```bash
-php leaf d:migration [name]
-```
+ This command rolls back, migrates, and seeds your database in one go:
-### Delete Model
+ ```bash:no-line-numbers
+ php leaf db:reset
+ ```
-The `d:model` command is used to delete a model from your Leaf MVC/Leaf API application. It deletes a model class from your `app/models` folder.
+ You can skip the seeding step if you want:
-```bash
-php leaf d:model [name]
-```
+ ```bash:no-line-numbers
+ php leaf db:reset --noSeed
+ ```
-### Delete Seed
+- Rollback Database
-The `d:seed` command is used to delete a seed file from your Leaf MVC/Leaf API application. It deletes a seed file from your `app/database/seeds` folder.
+ If you need to undo recent changes, you can roll back your migrations with:
-```bash
-php leaf d:seed [name]
-```
+ ```bash:no-line-numbers
+ php leaf db:rollback
+ ```
-## Database Commands
+ You can also rollback a specific number of migrations using the --step flag:
-These commands are used to manage your database. They are used to create, migrate, seed and rollback your database.
+ ```bash:no-line-numbers
+ php leaf db:rollback --step=2
+ ```
-### Install Database
+- Seed Database
-The `db:install` command is used to create a new database from your `.env` file. It creates a new database using the credentials in your `.env` file.
+ To populate your database with dummy data, use:
-```bash
-php leaf db:install
-```
+ ```bash:no-line-numbers
+ php leaf db:seed
+ ```
-### Migrate Database
+### View Commands
-The `db:migrate` command is used to run your database migrations. It runs all migrations in your `app/database/migrations` folder.
+These commands handle your frontend setup, building, and serving.
-```bash
-php leaf db:migrate
-```
+- Build Your Frontend
-You can also run a specific migration by passing the migration name to the `--file` flag.
+ When you’re ready to compile your frontend for production, run:
-```bash
-php leaf db:migrate --file=[migration_name]
-php leaf db:migrate --file=users # runs the ..._create_users_table migration
-```
+ ```bash:no-line-numbers
+ php leaf view:build
+ ```
-You can also seed your database after running your migrations by passing the `--seed` flag.
+- Serve Your Frontend
-```bash
-php leaf db:migrate --seed
-```
+ To start your frontend development server, use:
-### Reset Database
+ ```bash:no-line-numbers
+ php leaf view:serve
+ ```
-The `db:reset` command is used to rollback, migrate and seed your database. It runs the `db:rollback`, `db:migrate` and `db:seed` commands in that order.
+- Viewing All Commands
-```bash
-php leaf db:reset
-```
-
-If you want to prevent seeding your database, you can pass the `--noSeed` flag.
-
-```bash
-php leaf db:reset --noSeed
-```
+ You can always view the full list of Aloe commands by running:
-### Rollback Database
-
-The `db:rollback` command is used to rollback your database migrations. It rolls back all migrations in your `app/database/migrations` folder.
-
-```bash
-php leaf db:rollback
-```
-
-You can also rollback a specific migration by passing the migration name to the `--file` flag.
-
-```bash
-php leaf db:rollback --file=[migration_name]
-php leaf db:rollback --file=users # rolls back the ..._create_users_table migration
-```
-
-You may also rollback a specific number of migrations by passing the number to the `--step` flag.
-
-```bash
-php leaf db:rollback --step=[number]
-php leaf db:rollback --step=2 # rolls back the last 2 migrations
-```
+ ```bash:no-line-numbers
+ php leaf list
+ ```
-### Seed Database
+ This will display all available commands for your version of Leaf MVC.
-The `db:seed` command is used to seed your database. It runs all seed files loading in the `app/database/seeds/DatabaseSeeder.php` file. In this file, you can specify which seed files to run.
-
-```bash
-php leaf db:seed
-```
-
-## View Commands
-
-These commands are used to manage your frontend. They are used to build, serve and install your frontend. We already covered the `view:install` command in the Scaffold Commands section above.
-
-### Build Frontend
-
-The `view:build` command is used to build your frontend. It builds your frontend using the build command specified in your `package.json` file.
-
-```bash
-php leaf view:build
-```
-
-### Serve Frontend
-
-The `view:serve` command is used to serve your frontend. It serves your frontend using the `dev` command specified in your `package.json` file.
-
-```bash
-php leaf view:serve
-```
+ With this guide, you should be ready to take full advantage of Aloe and streamline your Leaf MVC app development. Happy coding! 😊
## Command List
This is a list of every command available in Aloe. To view this list from your terminal, run `php leaf list`.
-```bash
+```bash:no-line-numbers
Leaf MVC v3.5.0
Usage:
diff --git a/src/docs/mvc/controllers.md b/src/docs/mvc/controllers.md
index 557fbbc8..33e7d54e 100644
--- a/src/docs/mvc/controllers.md
+++ b/src/docs/mvc/controllers.md
@@ -1,20 +1,28 @@
# Controllers
-
+When building a web app with Leaf, you need to define routes—these are the paths that users visit in your app. For example, `/login` or `/signup`. Normally, you can just tell Leaf what to do when someone visits a route by passing it a function (a piece of code that runs when someone visits the route). This works fine if your app is small. Here's an example:
-Instead of using Closures in route files to define all your request handling logic, you can use controllers to organize this behavior. Controllers can group related request handling logic into a single class. For instance, you may want to group all logic that handles user account details into an `AccountsController` class: actions such as displaying, creating, updating, and deleting users.
+```php
+app()->get('/login', function () {
+ echo 'This is the login page';
+});
+```
-Controllers can also be shared among different route files, giving you a single location to define a controller that can be used in different contexts throughout your application. Leaf MVC and Leaf API controllers are stored in the `app/controllers`. Any new controller you create will be saved in this location.
+This is okay for simple apps, but as your app grows, it can get messy. You don’t want all your route logic (what happens when users visit routes) and your route definitions (what the routes are) in one place. This is where controllers come in.
-## Generating Controllers
+## What are controllers?
-Leaf MVC and Leaf API come with a console helper that can generate a new controller for you. To create a new controller, use the `g:controller` command:
+Controllers are classes that contain methods (functions) that handle requests to your app. When a request comes into your app, Leaf calls the method in the controller that matches the route. This keeps your route definitions clean, and let's you neatly organize your logic so you don't mix your application logic with any other code. Leaf MVC includes a really handy command that you can use to create controllers:
```bash
+php leaf g:controller
+
+# example 👇
+
php leaf g:controller users
```
-This will create a new `UsersController` class in the `app/controllers` directory. The controller will contain a single method, `index`, that returns a simple string:
+Leaf will automatically format the controller name to match the Leaf naming convention, so in the example above, Leaf will create a controller named `UsersController` in the `app/controllers` directory. The generated controller will look like this:
```php
json('Hello World!');
- }
-}
+```php
+app()->get('/users', 'UsersController@index');
```
-You can define a route to this controller action like so:
+Notice that we didn't pass a function to the route definition. Instead, we passed a string that tells Leaf to load the `UsersController` and call the `index` method. This is how Leaf knows which controller to load and which method to call. The syntax is always `ControllerName@methodName`.
-
+## Why Use Controllers?
-```php
-$app->get('/', 'HomeController@index');
-```
+- Organization: Keeps your route definitions and logic separate, making your code easier to understand.
+- Scalability: As your app grows, you won’t have one big file with all your logic—it will be split up into small, manageable pieces.
+- Reusability: You can reuse controller methods for multiple routes if needed.
-
-
+## Outputting Views
+
+In fullstack applications, you'll need to render views (HTML pages) to the user. You can do this by returning a view from your controller method. Leaf has `view()` and `render()` methods that you can use to render views. Here's an example:
```php
-app()->get('/', 'HomeController@index');
+public function index()
+{
+ render('users');
+}
```
-
+You can find the views documentation [here](/docs/frontend/)
-## Resource Controllers
+## Route Parameters
-Leaf resource routing assigns the typical create, read, update, and delete ("CRUD") routes to a controller with a single line of code. To get started, we can use the `g:controller` command's `--resource` option to quickly create a controller to handle these actions:
+When you're building web apps, sometimes you need extra functionality when someone visits a route. For example, maybe only logged-in users should be able to see certain pages. To manage this, Leaf lets you add route parameters like middleware to your routes. This feature also works for controllers and uses the same syntax as function route handlers. Here's an example:
-```sh
-php leaf g:controller Photos --resource
+```php
+app()->get('/users', ['middleware' => 'auth', 'UsersController@index']);
```
-This command will generate a controller at `app/controllers/PhotosController.php`. The controller will contain a method for each of the available resource operations. Next, you may register a resource route that points to the controller:
+In the example above, we passed in a middleware called `auth` to the route as a route parameter. Leaf will run the middleware before calling the `index` method in the `UsersController`.
-```php
-app()->resource('/user/(\d+)', 'UsersController');
-```
+## Resource Controllers
+
+Leaf makes it super easy to set up routes for common actions like creating, reading, updating, and deleting data (also known as CRUD operations). Instead of manually setting up each route, you can use resource controllers to do it all in one line of code!
-The `resource` method accepts a URI and a controller name. The URI may contain route parameters, which will be passed to the controller methods. The controller name should be the fully-qualified class name of the controller. In this example, the `UsersController` class should be defined in the `app/controllers` directory.
+To get started, you can generate a resource controller using the Aloe CLI:
-This single route declaration creates multiple routes to handle a variety of actions on the resource. The generated controller will already have methods stubbed for each of these actions:
+```bash
+php leaf g:controller photos --resource
+```
+This command will generate a controller at `app/controllers/PhotosController.php` which has a bunch of methods pre-defined for you like this:
+
```php
resource('/photos', 'PhotosController');
+```
-| Verb | URI | Action |
-|----------------|-------------------------|---------|
-| GET | /photos | index |
-| POST | /photos | store |
-| GET | /photos/{photo} | show |
-| POST/PUT/PATCH | /photos/{photo} | update |
-| DELETE | /photos/{photo} | destroy |
+This will automatically set up all the routes you need for CRUD operations on the `/photos` route. Here's a list of the routes that will be set up:
-:::
+- `GET /photos` - Index
+- `GET /photos/create` - Create
+- `POST /photos` - Store
+- `GET /photos/{id}` - Show
+- `GET /photos/{id}/edit` - Edit
+- `PUT /photos/{id}` - Update
+- `DELETE /photos/{id}` - Destroy
-## Leaf Console Helper
+## API Resource Controllers
-You can also generate a model together with your controller.
+API resource controllers are similar to resource controllers, but they return JSON responses instead of HTML which means that the `create` and `edit` methods are not included. You can generate an API resource controller using the Aloe CLI:
```bash
-php leaf g:controller -m
+php leaf g:controller photos --api
+```
+
+You can load the controller in your routes like this:
+
+```php
+app()->apiResource('/photos', 'PhotosController');
```
-Create a template for your controller
+## Aloe Console Helper
+
+Allow has a few more shortcuts you can incorporate into your controller generation:
```bash
-php leaf g:controller -t
+php leaf g:controller -m
```
-Create a model and migration for your controller
+This command will generate your controller together with a model that corresponds to the controller name. The model will be generated in the `app/models` directory.
```bash
-php leaf g:controller -a
+php leaf g:controller -t
```
-### Controller Help
+The `-t` flag will generate a controller with a frontend template that corresponds to the controller name. The template will be generated in the `app/views` directory.
```bash
-Description:
- Create a new controller class
-
-Usage:
- g:controller [options] [--]
-
-Arguments:
- controller controller name
-
-Options:
- -a, --all Create a model and migration for controller
- -m, --model Create a model for controller
- -r, --resource Create a resource controller
- -w, --web Create a web(ordinary) controller
- -h, --help Display this help message
- -q, --quiet Do not output any message
- -V, --version Display this application version
- --ansi Force ANSI output
- --no-ansi Disable ANSI output
- -n, --no-interaction Do not ask any interactive question
- -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debu
+php leaf g:controller -a
```
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf MVC.
-
-
+This command will generate your controller together with a model and a migration that corresponds to the controller name. The model and migration will be generated in the `app/models` and `app/database/migrations` directories respectively.
diff --git a/src/docs/mvc/globals.md b/src/docs/mvc/globals.md
index 6408e674..d40c8a5f 100644
--- a/src/docs/mvc/globals.md
+++ b/src/docs/mvc/globals.md
@@ -1,10 +1,10 @@
-# MVC Helpers
+# MVC Globals
-Just as Leaf has a couple of built-in helpers, Leaf MVC also ships with a bunch of helpers to make your life easier. These helpers are available throughout your application and help you with common tasks like finding files and loading paths.
+Leaf MVC comes with a couple of global functions that you can use to access your app's configuration, paths and more. These functions are available globally and can be used anywhere in your app.
## Loading app paths
-Since Leaf MVC and Leaf API come with a robust structure out of the box, they also come with quick ways to reference files in these structures. For example, if you want to reference a file in your `public` folder, you can use the `PublicPath()` helper.
+Since Leaf MVC comes with a robust structure out of the box, it also comes with quick ways to reference files in these structures. For example, if you want to reference a file in your `public` folder, you can use the `PublicPath()` helper.
### AppPaths()
diff --git a/src/docs/mvc/index.md b/src/docs/mvc/index.md
index 42c7e9ed..96763b7d 100644
--- a/src/docs/mvc/index.md
+++ b/src/docs/mvc/index.md
@@ -1,71 +1,151 @@
-
-
# Leaf + MVC
+
+
-Leaf is a simple PHP framework/set of libraries that can be used to build any kind of application. By default, Leaf doesn't give you a lot of structure, but it fully supports the MVC pattern without any extra configuration.
+Leaf is a lightweight PHP framework with a ton of loosely coupled libraries that can be used to build any kind of application. By default, Leaf doesn't give you a lot of structure, but it fully supports the MVC pattern without any extra configuration.
## What is MVC?
MVC stands for Model-View-Controller. It is a pattern that separates your application into three distinct parts:
- Models: These are the classes that represent your data. They are responsible for interacting with your database, and for validating your data.
-- Views: These are the files that are responsible for displaying your data to the user. They are usually written in HTML, but can also be written in other templating languages like [BareUI](https://leafphp.dev/modules/views/bareui/) or [Blade](https://leafphp.dev/modules/views/blade/) or frameworks like [Vue](https://vuejs.org/) or [React](https://reactjs.org/)
+- Views: These are the files that are responsible for displaying your data to your user. They are usually written in HTML, but can also be written in other templating languages like [BareUI](https://leafphp.dev/docs/views/bareui/) or [Blade](https://leafphp.dev/docs/views/blade/) or frameworks like [Vue](https://vuejs.org/) or [React](https://reactjs.org/)
- Controllers: These are the classes that are responsible for handling the user's request, and for returning the appropriate response.
-
+:::
## MVC in Leaf
-Leaf out of the box doesn't provide any structure, however, the Leaf team also provides a few setups that you can use to get started with Leaf and MVC. These setups are designed to give you a good starting point for your application, and come with additional tooling that make building with Leaf even faster.
+Leaf provides a minimal but powerful setup for building applications using the MVC pattern. It's built on top of Leaf, and comes with additional tooling that makes building with Leaf even faster. It is a good starting point for building applications using the MVC pattern.
+
+## Installation
+
+You can set up a new MVC application using the [Leaf CLI](/docs/cli/) or using [Composer](https://getcomposer.org/). They both work, but using the Leaf CLI gives you the option to choose between a regular MVC app and an MVC app that is fine-tuned for creating APIs, plus a few other options.
+
+::: code-group
+
+```bash:no-line-numbers [Leaf CLI]
+leaf create
+```
+
+```bash:no-line-numbers [Composer]
+composer create-project leafs/mvc
+```
+
+:::
+
+This command will set up a new MVC app in the `` directory. You can then run the app using the Leaf CLI:
+
+```bash:no-line-numbers
+cd
+leaf serve # or php leaf serve
+```
+
+You should then see the welcome page in your browser.
+
+![Leaf MVC Welcome Page](https://user-images.githubusercontent.com/26604242/223189921-d5da1555-bc29-4f99-a3ec-d6cbfdc5350b.png)
+
+## Directory Structure
+
+The Leaf MVC directory structure is inspired by [Ruby on Rails](https://rubyonrails.org/) and [Laravel](https://laravel.com/). It takes a lot of inspiration from these frameworks, but it's not a clone of either of them. It is meant to be a starting point for building your own applications, and is fully customizable. You can completely change the directory structure to suit your needs, just be sure to update the paths in the `config/paths.php` file.
+
+For a fresh MVC app, the directory structure looks like this:
+
+```bash:no-line-numbers
+.
+├───app
+│ ├── console
+│ ├── controllers
+│ ├── database
+│ │ ├── factories
+│ │ ├── migrations
+│ │ ├── schema
+│ │ └── seeds
+│ ├── helpers
+│ ├── models
+│ ├── routes
+│ └── views
+│ └── errors
+├───config
+├───public
+│ └───assets
+│ ├── css
+│ └── img
+├───storage
+│ ├───app
+│ │ └───public
+│ ├───framework
+│ │ └───views
+│ └───logs
+└───vendor
+```
+
+- ### The `app` directory
+
+ The `app` directory contains the core code of your application. It's divided into a few sub-directories:
+
+ - `console` - Contains the console commands for your application. These are used to perform tasks on the command line.
+ - `controllers` - Contains the controllers for your application. These are used to handle HTTP requests.
+ - `database` - Contains the database related code for your application. This includes migrations, seeds, factories and schema.
+ - `helpers` - Contains the helper functions for your application.
+ - `models` - Contains the models for your application. These are used to interact with the database.
+ - `routes` - Contains the routes for your application. These are used to map HTTP requests to controllers.
+ - `views` - Contains the views for your application. These are used to render HTML responses.
+
+- ### The `config` directory
+
+ The `config` directory contains the configuration files for your application. These are used to configure how Leaf and it's modules interact with your application. Each file controls a different feature of your application, e.g. the `app.php` file is used to configure the application, the `database.php` file is used to configure the database connection, etc.
+
+- ### The `public` directory
+
+ The `public` directory contains the entry point for your application, and it's also used to serve static assets. The `index.php` file is the entry point for your application. All requests are routed through this file by the web server. This file doesn't contain any application logic, but it does load the Composer autoloader, the application config and all your routes.
+
+ There is also an `assets` directory found in the `public` directory. It contains the static assets for your application. These are served by the web server and are accessible to users.
+
+- ### The `storage` directory
+
+ The `storage` directory contains the compiled views, logs and other files generated by your application. It's divided into a few sub-directories:
+
+ - `app` - Contains the files generated by your application. This includes the compiled views and the files uploaded by users.
+ - `framework` - Contains the framework generated files for your application.
+ - `logs` - Contains the log files generated by your application.
-We provide two setups for you to choose from:
+- ### The `vendor` directory
-- [Leaf MVC](/docs/leafmvc/)
-- [Leaf API](/docs/leafapi/)
+ The `vendor` directory contains all the dependencies installed by Composer. It's automatically generated when you install the dependencies using Composer.
-### Leaf MVC vs Leaf API
+## Configuring Leaf MVC
-| Engine | Main use | Extra Notes |
-| --------------------------- | :-------------: | :----------------------------: |
-| [Leaf MVC](/docs/leafmvc/) | General purpose | - |
-| [Leaf API](/docs/leafapi/) | Building APIs | View layer disabled by default |
+Leaf MVC tries to maintain a clean and easy-to-understand structure that works out-of-the-box for most applications. However, there are times when you need to customize some features to fit your specific use-cases.
-Leaf MVC and Leaf API pretty much support the same tooling, but Leaf API is designed to be used for building APIs. It comes with the view layer disabled by default, and comes with a few extra tools that make building APIs with Leaf even easier.
+You can find all the configuration options used by Leaf MVC in the `config` directory of your Leaf MVC project. Each feature has its own configuration file, and you can customize these files to fit your needs, e.g. the database configuration file is `config/database.php`.
-## Leaf Skeleton
+You only need to change only the specific values you want to customize so you can leave the rest of the configuration as it is. Each option is documented, so feel free to look through the files and get familiar with the options available to you.
-Skeleton was designed to be a simple starting point for your application, and came with just the bare minimum to get you started. However, we have decided to deprecate Skeleton in favor of the Leaf CLI. The Leaf CLI is a command-line tool for generating Leaf projects, installing modules, and more.
+For the final bit, we hooked up most of the configuration files to your `.env` file so you can easily change your configuration values without having to touch the configuration files directly. This is especially useful when you want to deploy your application to different environments.
-We recently released an update to the Leaf CLI that allows you to select specific features you want to include and generate a project with everything you need. This functionality is similar to what Skeleton provided but is more flexible and allows you to create projects with only the features that you need, which is why we've decided to deprecate Leaf Skeleton.
+## Application Environment
-Skeleton will still be available for download, but we won't be updating it anymore. We recommend that you generate a project with the CLI or use Leaf MVC or Leaf API instead.
+A fresh Leaf MVC installation comes with a `.env.example` file which is automatically duplicated to a `.env` file on installation. This file is used to store your application's environment variables, and you can put sensitive information like your database credentials or mail server credentials in this file. This allows you to have different configurations for different environments like development, testing, and production.
-[> Leaf CLI Docs](/docs/cli/)
+Any value in your `.env` file is automatically loaded into your application's environment variables, and you can access these values using the `_env()` helper function. This function takes in the key of the environment variable you want to access and an optional default value if the environment variable is not set.
-## MVC Tools
+Here's an example of how you can use the `_env()` helper function:
-Besides the MVC setups, Leaf also provides a few tools that can help you build your own MVC setup if you want to. You can check the "MVC Tools" section in the sidebar to learn more about these tools.
+```php
+$database = _env('DB_DATABASE');
+$databaseWithDefault = _env('DB_DATABASE', 'leaf');
+```
-
+Be careful not to commit your `.env` file to your version control system as it contains sensitive information. We have already added the `.env` file to your `.gitignore` file so you don't have to worry about this.
diff --git a/src/docs/mvc/mail.md b/src/docs/mvc/mail.md
deleted file mode 100644
index 69429188..00000000
--- a/src/docs/mvc/mail.md
+++ /dev/null
@@ -1,352 +0,0 @@
-# Mailing
-
-Leaf provides amazing support for handling mailing in your application via Leaf Mail. The documentation for the Leaf Mailer module can be found on the [Leaf Mail page](/modules/mail/). This page will only cover how to use Leaf Mail in your Leaf MVC or Leaf API application.
-
-If you haven't already, we recommend you read the [Leaf Mail documentation](/modules/mail/) before continuing.
-
-## Setting up Leaf Mail
-
-Leaf MVC and Leaf API provide a lean setup out of the box that comes without mailing pre-activated. To activate mailing, you can run the following command in the root of your app:
-
-```bash
-php leaf mail:setup
-```
-
-This will setup everything you need to start using mailing and will also create a `mail.php` file in your `config` folder. This file contains all the configuration options for Leaf Mail. You can read more about the configuration options in the [Leaf Mail documentation](/modules/mail/#mailer-config).
-
-## Mail server connection
-
-After setting up Leaf Mail, the next thing to do is to connect to your mail server. This connection is what Leaf Mail will attempt to use whenever you initiate an email send.
-
-Before you can connect to your mail server, you need to have your mail server credentials. You can get these from your mail server provider.
-
-### Your mail provider
-
-If you are using a mail provider like Mailgun, Sendgrid, etc, you need to head over to your provider's dashboard and get your mail server credentials. From there, you need to update the mail host and port in your `.env` file.
-
-```env
-MAIL_HOST=smtp.mailtrap.io
-MAIL_PORT=2525
-```
-
-There are different kinds of server connections you can use. The most common one is SMTP using a username and password. You can also use OAuth authentication with a provider like Google.
-
-### Connection with username and password
-
-To connect to a server using your username and password, you can head over to your `.env` file and update the following values:
-
-```env
-MAIL_USERNAME=null
-MAIL_PASSWORD=null
-```
-
-These are your mail server username and password respectively. **Note that these values are not set by default**. You need to set them yourself.
-
-### Connection with OAuth
-
-Some mail providers like Google require OAuth authentication. To connect to a server using OAuth, you need to add an OAuth provider like league/oauth2-google to your project. You can install this using the Leaf CLI:
-
-```bash
-leaf install league/oauth2-google
-```
-
-Or with composer:
-
-```bash
-composer require league/oauth2-google
-```
-
-From there, you need to update the `config/mail.php` file to work with OAuth instead of username and password. You can do this by replacing these lines:
-
-```php
-'auth' => [
- 'username' => _env('MAIL_USERNAME'),
- 'password' => _env('MAIL_PASSWORD'),
-],
-```
-
-With the OAuth config:
-
-```php
-use League\OAuth2\Client\Provider\Google;
-use PHPMailer\PHPMailer\OAuth;
-
-return [
- ...
-
- 'auth' => new OAuth(
- [
- 'userName' => _env('MAIL_USERNAME'),
- 'clientSecret' => _env('MAIL_CLIENT_SECRET'),
- 'clientId' => _env('MAIL_CLIENT_ID'),
- 'refreshToken' => _env('MAIL_REFRESH_TOKEN'),
- 'provider' => new Google(
- [
- 'clientId' => _env('MAIL_CLIENT_ID'),
- 'clientSecret' => _env('MAIL_CLIENT_SECRET'),
- ]
- ),
- ]
- ),
-
- ...
-];
-```
-
-Since more environment variables have been added, you need to update your `.env` file to include these variables:
-
-```env
-MAIL_CLIENT_ID=
-MAIL_CLIENT_SECRET=
-MAIL_REFRESH_TOKEN=
-```
-
-::: tip .env.example
-It is a good practice to add these variables to your `.env.example` file so that other developers can easily know what environment variables they need to set.
-:::
-
-## Sending emails
-
-Before you can send emails, you need to create a mailer. You can create a mailer by running the following command in the root of your app:
-
-```bash
-php leaf mail:create
-```
-
-A mailer is a class that allows you to group related emails together. Mailers have methods called "actions" which are responsible for handling a specific type of email. For instance, you can create a mailer called `UserMailer` that has a `welcome` action for sending welcome emails, a `passwordReset` action for sending password reset emails, etc.
-
-Using this example, we can create a `UserMailer` by running the following command:
-
-```bash
-php leaf mail:create user
-```
-
-This will create a `UserMailer` class in your `app/mailers` folder. The `UserMailer` class will look like this:
-
-```php
- 'UserMailer Test',
- 'body' => 'This is a test mail from action',
- 'recipientEmail' => $user->email,
- 'recipientName' => $user->name,
-
- // next couple of lines can be skipped if you
- // set defaults in the config/mail.php file
- 'senderName' => _env('MAIL_SENDER_NAME'),
- 'senderEmail' => _env('MAIL_SENDER_EMAIL'),
- ]);
- }
-}
-```
-
-You can rename the `action` method to anything you want, in this case we will rename it to `welcome`. The method is responsible for creating and returning a new `Mail` instance. The `Mail` instance is what is used to send the email. You can read more about the `Mail` class in the [Leaf Mail documentation](/modules/mail/#mailer-config).
-
-```php
- 'Welcome to my app',
- 'body' => 'This is a test mail from action',
- 'recipientEmail' => $user->email,
- 'recipientName' => $user->name,
- ]);
- }
-}
-```
-
-To send the welcome email, you can call the `welcome` method on the `UserMailer` class like this:
-
-```php
-UserMailer::welcome($user)->send();
-```
-
-## Setting mail defaults
-
-Some values like the `senderName` and `senderEmail` are repeated in every email you send although they may not change. To avoid repeating these values, we set them as defaults in the `config/mail.php` file. You can configure these in your `.env` file like this:
-
-```env
-MAIL_SENDER_NAME=
-MAIL_SENDER_EMAIL=
-MAIL_REPLY_TO_NAME=
-MAIL_REPLY_TO_EMAIL=
-```
-
-### Removing defaults
-
-If you don't want to set defaults, you can remove them from the `config/mail.php` file. The `.env` values will then be ignored. Your updated `config/mail.php` file will look like this:
-
-```php
-...
-'defaults' => [],
-...
-```
-
-Removing these defaults means that you will have to set these values in every email you send.
-
-## Mail Debugging
-
-Leaf Mail by default reports all errors from your mail server. This is useful for debugging, but can be annoying when you are in production. You can disable this by setting the `MAIL_DEBUG` environment variable to `false` in your `.env` file.
-
-```env
-MAIL_DEBUG=false
-```
-
-## Mail Config
-
-The `config/mail.php` file contains all the configuration options for Leaf Mail. You can read more about the configuration options in the [Leaf Mail documentation](/modules/mail/#mailer-config).
-
-```php
- _env('MAIL_DRIVER', 'smtp'),
-
- /*
- |--------------------------------------------------------------------------
- | Mailer hostname
- |--------------------------------------------------------------------------
- |
- | This is the hostname for your mailer
- |
- */
- 'host' => _env('MAIL_HOST', 'smtp.mailtrap.io'),
-
- /*
- |--------------------------------------------------------------------------
- | Mailer port
- |--------------------------------------------------------------------------
- |
- | Port to use for mailer connection
- |
- */
- 'port' => _env('MAIL_PORT', 2525),
-
- /*
- |--------------------------------------------------------------------------
- | Keep Alive
- |--------------------------------------------------------------------------
- |
- | This config is used to keep the connection to your mail server alive.
- | This is useful if you are sending multiple emails. It takes in a boolean.
- |
- */
- 'keepAlive' => true,
-
- /*
- |--------------------------------------------------------------------------
- | Mailer Debug
- |--------------------------------------------------------------------------
- |
- | Enable or disable debug mode. Supported values are:
- | 'SERVER', false or any value supported by PHPMailer's
- | SMTPDebug config
- |
- */
- 'debug' => _env('MAIL_DEBUG', 'SERVER'),
-
- /*
- |--------------------------------------------------------------------------
- | Mailer Encryption
- |--------------------------------------------------------------------------
- |
- | This is the encryption used for your mailer. Supported values are:
- | 'STARTTLS' or any value supported by PHPMailer's SMTPSecure config
- |
- */
- 'security' => _env('MAIL_ENCRYPTION', 'STARTTLS'),
-
- /*
- |--------------------------------------------------------------------------
- | Auth
- |--------------------------------------------------------------------------
- |
- | This config handles the authentication details for your mailer.
- | It supports authentication with username and password and also
- | OAuth authentication.
- |
- | For OAuth authentication, you will need to add an OAuth
- | provider like league/oauth2-google to your project.
- |
- | An example OAuth config is shown below:
- |
- | use League\OAuth2\Client\Provider\Google;
- | use PHPMailer\PHPMailer\OAuth;
- |
- | 'auth' => new OAuth(
- | [
- | 'userName' => 'mail@gmail.com',
- | 'clientSecret' => 'CLIENT_SECRET',
- | 'clientId' => 'CLIENT_ID',
- | 'refreshToken' => 'GMAIL_REFRESH_TOKEN',
- | 'provider' => new Google(
- | [
- | 'clientId' => 'CLIENT_ID',
- | 'clientSecret' => 'CLIENT_SECRET',
- | ]
- | ),
- | ]
- |)
- */
- 'auth' => [
- 'username' => _env('MAIL_USERNAME'),
- 'password' => _env('MAIL_PASSWORD'),
- ],
-
- /*
- |--------------------------------------------------------------------------
- | Default addresses
- |--------------------------------------------------------------------------
- |
- | This config is used to set default values for the
- | `recipientEmail`, `recipientName`,
- | `senderEmail`, `senderName`,
- | `replyToName`, and `replyToEmail` of your emails.
- |
- */
- 'defaults' => [
- 'senderName' => _env('MAIL_SENDER_NAME'),
- 'senderEmail' => _env('MAIL_SENDER_EMAIL'),
- 'replyToName' => _env('MAIL_REPLY_TO_NAME'),
- 'replyToEmail' => _env('MAIL_REPLY_TO_EMAIL'),
- ],
-];
-```
diff --git a/src/docs/mvc/models.md b/src/docs/mvc/models.md
deleted file mode 100644
index 40949075..00000000
--- a/src/docs/mvc/models.md
+++ /dev/null
@@ -1,281 +0,0 @@
-# Models
-
-
-
-A model is a class that represents your application's data and business logic, and it is responsible for managing data storage, retrieval, and manipulation. The Model communicates with the View and the Controller to provide data and to update the application's state.
-
-Each database table has a corresponding "Model" which is used to interact with that table. Models allow you to query for data in your tables, as well as insert new records into the table.
-
-::: tip Base Model
-Leaf Models are built on top of [Laravel's Eloquent ORM](https://laravel.com/docs/10.x/eloquent). This means that you can use all the features of Eloquent in your Leaf applications. You can find the documentation for Eloquent [here](https://laravel.com/docs/10.x/eloquent).
-:::
-
-## Defining Models
-
-Your models can be found in the `app/models` directory in Leaf MVC and Leaf API. Your models can be created using the `php leaf g:model` command from the root of your project.
-
-```bash
-php leaf g:model User
-```
-
-This will create a `User.php` file in the `app/models` directory.
-
-## Model Structure
-
-Leaf MVC and Leaf API come with a base model class. This is to give you a place to configure all your models seamlessly without having access to the `Leaf\Model` file. It also allows you to add logic that you want to be available to all your models.
-
-```php
-class Flight extends Model
-{
- //
-}
-```
-
-## Leaf Model Conventions
-
-Now, let's look at an example `Flight` model, which we will use to retrieve and store information from our `flights` database table:
-
-```php
-class Flight extends Model
-{
- //
-}
-```
-
-### Table Names
-
-Note that we did not tell Leaf which table to use for our `Flight` model. By convention, the "snake case", plural name of the class will be used as the table name unless another name is explicitly specified. So, in this case, Leaf will assume the `Flight` model stores records in the `flights` table. You may specify a custom `table` by defining a table property on your model:
-
-```php
-class Flight extends Model
-{
- /**
- * The table associated with the model.
- *
- * @var string
- */
- protected $table = 'my_flights';
-}
-```
-
-### Primary Keys
-
-Leaf will also assume that each table has a primary key column named id. You may define a protected `$primaryKey` property to override this convention:
-
-```php
-class Flight extends Model
-{
- /**
- * The primary key associated with the table.
- *
- * @var string
- */
- protected $primaryKey = 'flight_id';
-}
-```
-
-In addition, Leaf assumes that the primary key is an incrementing integer value, which means that by default the primary key will automatically be cast to an int. If you wish to use a non-incrementing or a non-numeric primary key you must set the public `$incrementing` property on your model to false:
-
-```php
-/**
-* Indicates if the IDs are auto-incrementing.
-*
-* @var bool
-*/
-public $incrementing = false;
-```
-
-If your primary key is not an integer, you should set the protected `$keyType` property on your model to string:
-
-```php
-/**
-* The "type" of the auto-incrementing ID.
-*
-* @var string
-*/
-protected $keyType = 'string';
-```
-
-### Timestamps
-
-By default, Leaf expects `created_at` and `updated_at` columns to exist on your tables. If you do not wish to have these columns automatically managed by Leaf, set the $timestamps property on your model to false:
-
-```php
-class Flight extends Model
-{
- /**
- * Indicates if the model should be timestamped.
- *
- * @var bool
- */
- public $timestamps = false;
-}
-```
-
-If you need to customize the format of your timestamps, set the `$dateFormat` property on your model. This property determines how date attributes are stored in the database, as well as their format when the model is serialized to an array or JSON:
-
-```php
-/**
-* The storage format of the model's date columns.
-*
-* @var string
-*/
-protected $dateFormat = 'U';
-```
-
-If you need to customize the names of the columns used to store the timestamps, you may set the `CREATED_AT` and `UPDATED_AT` constants in your model:
-
-```php
-class Flight extends Model
-{
- const CREATED_AT = 'creation_date';
- const UPDATED_AT = 'last_update';
-}
-```
-
-### Database Connection
-
-By default, all Leaf models will use the default database connection configured for your application. If you would like to specify a different connection for the model, use the `$connection` property:
-
-```php
-class Flight extends Model
-{
- /**
- * The connection name for the model.
- *
- * @var string
- */
- protected $connection = 'connection-name';
-}
-```
-
-## Default Attribute Values
-
-If you would like to define the default values for some of your model's attributes, you may define an $attributes property on your model:
-
-```php
- false,
- ];
-}
-```
-
-## Retrieving Models
-
-Once you have created a model and its associated database table, you are ready to start retrieving data from your database. Think of each Leaf model as a powerful query builder allowing you to fluently query the database table associated with the model. For example:
-
-```php
-name;
-}
-```
-
-### Adding Additional Constraints
-
-The Leaf all method will return all of the results in the model's table. Since each Leaf model serves as a query builder, you may also add constraints to queries, and then use the get method to retrieve the results:
-
-```php
-$flights = Flight::where('active', 1)->orderBy('name', 'desc')->take(10)->get();
-```
-
-> **You can check [here](https://laravel.com/docs/10.x/queries) for available queries on your models.**
-
-### Refreshing Models
-
-You can refresh models using the `fresh` and `refresh` methods. The `fresh` method will re-retrieve the model from the database. The existing model instance will not be affected:
-
-```php
-$flight = Flight::where('number', 'FR 900')->first();
-
-$freshFlight = $flight->fresh();
-```
-
-The `refresh` method will re-hydrate the existing model using fresh data from the database. In addition, all of its loaded relationships will be refreshed as well:
-
-```php
-$flight = Flight::where('number', 'FR 900')->first();
-
-$flight->number = 'FR 456';
-
-$flight->refresh();
-
-$flight->number; // "FR 900"
-```
-
-## Inserting & Updating Models
-
-### Inserts
-
-To create a new record in the database, create a new model instance, set attributes on the model, then call the save method:
-
-```php
-name = $this->request->name;
-
- $flight->save();
- }
-}
-```
-
-In this example, we assign the name parameter from the incoming HTTP request to the name attribute of the `Flight` model instance. When we call the save method, a record will be inserted into the database. The created_at and updated_at timestamps will automatically be set when the save method is called, so there is no need to set them manually.
-
-### Updates
-
-The save method may also be used to update models that already exist in the database. To update a model, you should retrieve it, set any attributes you wish to update, and then call the save method. Again, the updated_at timestamp will automatically be updated, so there is no need to manually set its value:
-
-```php
-$flight = Flight::find(1);
-
-$flight->name = 'New Flight Name';
-
-$flight->save();
-```
-
-Since Leaf Models use Eloquent, you can read more [here](https://laravel.com/docs/10.x/eloquent) to view available methods on the Eloquent object.
-
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf MVC.
-
-
diff --git a/src/docs/mvc/routing.md b/src/docs/mvc/routing.md
deleted file mode 100644
index 036d61cd..00000000
--- a/src/docs/mvc/routing.md
+++ /dev/null
@@ -1,101 +0,0 @@
-# Routing
-
-
-
-Leaf MVC, Leaf API and Skeleton all rely on Leaf's powerful routing engine. The only difference is that routing the MVC way makes use of controllers instead of callable functions. Everything else works the same way. This document will cover the basics of Leaf MVC routing.
-
-::: tip Leaf Routing
-If you're not familiar with Leaf's routing, you should read the [Leaf Routing](/docs/routing/) document first.
-:::
-
-## The Routes Folder
-
-Leaf MVC, Leaf API and Skeleton all have a `routes` folder in which all your application's routes are defined. The `routes` folder is located in the `app` directory in Leaf MVC and Leaf API but is located in the root directory in Skeleton. The `routes` folder contains a single file called `index.php` which is where all your application's routes are defined. This file is automatically loaded by Leaf when your application starts.
-
-## Linking Controllers
-
-Controllers provide a way to organize your application's logic. They are a great way to keep your routes file clean and easy to read. Controllers are just classes that implement the `App\Controllers\Controller` protocol. You can find more information about controllers in the [Controllers](/docs/mvc/controllers) document. This document will focus on how to link controllers to routes.
-
-Leaf provides a simple interface for interacting with controllers and their methods from inside your routes. The idea is to run a method inside your controller whenever a route is matched. This is done by telling Leaf which controller to use and which method to run. Leaf will then create an instance of the controller and run the method.
-
-### Example
-
-Let's say you have a controller called `App\Controllers\HomeController` and you want to run the `index` method inside it whenever the `/` route is matched. You can do this by passing a string containing your controller name and method to your route. The string should be in the format `controllerName@methodName`.
-
-
-
-```php
-$app->get('/', '\App\Controllers\HomeController@index');
-```
-
-
-
-
-```php
-app()->get('/', '\App\Controllers\HomeController@index');
-```
-
-
-
-## Controller Namespaces
-
-In case you're using an auto loader or using leaf in another framework and you have your controllers in another directory, you can do sommething like this
-
-
-
-```php
-app()->get('/(\d+)', '\App\Controllers\User@showProfile');
-```
-
-
-
-
-```php
-$app->get('/(\d+)', '\App\Controllers\User@showProfile');
-```
-
-
-
-But this gets tedious if you have a lot of routes. So Leaf allows you to set a "general" namespace, you can set the default namespace to use on your router instance via `setNamespace()`
-
-
-
-```php
-app()->setNamespace('\App\Controllers');
-
-app()->get('/users/(\d+)', 'User@showProfile');
-app()->get('/cars/(\d+)', 'Car@showProfile');
-```
-
-
-
-
-```php
-$app->setNamespace('\App\Controllers');
-
-$app->get('/users/(\d+)', 'User@showProfile');
-$app->get('/cars/(\d+)', 'Car@showProfile');
-```
-
-
-
-This has already been setup for you in the root routes file of your MVC application.
-
-## Next Steps
-
-Follow along with the next steps to learn more about Leaf MVC.
-
-
diff --git a/src/docs/mvc/views.md b/src/docs/mvc/views.md
deleted file mode 100644
index a3364a04..00000000
--- a/src/docs/mvc/views.md
+++ /dev/null
@@ -1,81 +0,0 @@
-# Views
-
-
-
-Views make up the 'V' in MVC. Views allow you to separate your logic from your presentation layer instead of mixing them together in a single file. This allows you to easily change the look and feel of your application without having to change any of your logic.
-
-## View Engines
-
-Leaf comes with support for 3 view engines designed by the team at Leaf:
-
-| Engine | Use case |
-| -------------------------------- | -------------------------------------------- |
-| [bareui](/modules/views/bareui/) | Blazing fast templating with no compile time |
-| [veins](/modules/views/veins/) | Lightweight but powerful templating engine |
-| [blade](/modules/views/blade/) | Laravel blade templating engine for leaf |
-
-Leaf MVC and Leaf API come with Blade already installed and configured, but of course, you can use any templating engine you prefer. These have first party support, and work amazingly well out of the box.
-
-***You can find more information on the [Views Docs Page](/modules/views/)***
-
-## Defining Views
-
-Views are defined in the `app/views` directory in Leaf API and Leaf MVC. You can create subdirectories to organize your views based on your preference. For example, you might create a `layouts` directory to store your layout files. To quickly create a view, you can use the `php leaf g:template` command from the root of your project.
-
-```bash
-php leaf g:template home
-```
-
-This will create a file called `home.blade.php` in the `app/views` directory.
-
-## Rendering Views
-
-Leaf ships a `view` method as an extension of functional mode. This method allows you to render a view/template found in the views directory. This method accepts two parameters:
-
-- The name of the view to render
-- Data to pass to the view
-
-```php
-echo view('home', ['name' => 'John Doe']);
-```
-
-Notice that we pass the name of the view without the file extension. This is because Leaf will automatically append the correct file extension based on the view engine you're using.
-
-### The `render()` method
-
-To make things even easier for you, Leaf also ships with a `render()` method. This method accepts the same parameters as the `view()` method but automatically outputs the views with the correct headers in place.
-
-```php
-render('home', ['name' => 'John Doe']);
-```
-
-## Asset Bundling
-
-[Vite](https://vitejs.dev/) is a modern build tool for frontend applications. It aims to provide a faster and leaner development experience for modern web projects. Leaf allows you to bundle your CSS and JS assets using vite, using the powerful [leaf-vite](/modules/views/vite/) module.
-
-[> Read the docs](/modules/views/vite/)
-
-## Frontend Frameworks
-
-Leaf has support for some of the most popular frontend frameworks using [Inertia.js](https://inertiajs.com/). Inertia.js is a framework that allows you to create fully client-side rendered, single-page apps, without much of the complexity that comes with modern SPAs. It does this by leveraging Leaf's server-side rendering capabilities.
-
-[> Read the docs](/modules/views/inertia/)
-
-## Next Steps
-
-You can continue learning about MVC with Leaf from the sidebar or check out the view engines below:
-
-
diff --git a/src/docs/routing/controller.md b/src/docs/routing/controller.md
deleted file mode 100755
index 8c9bc71b..00000000
--- a/src/docs/routing/controller.md
+++ /dev/null
@@ -1,172 +0,0 @@
-# Using Controllers
-
-
-Controllers are simply classes that serve as bridges between Models and the View part of your application. Don't think too much of controllers, they're nothing but a class.
-
-In this section, we'll be looking at how to handle a route with a controller. So let's make an example controller: **remember it's just a php class**
-
-```php
-
-
-```php
-require "HomeController.php";
-
-// we leave out the second parameter for now
-app()->get("/home");
-```
-
-