-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathindex.html
More file actions
111 lines (105 loc) · 179 KB
/
Copy pathindex.html
File metadata and controls
111 lines (105 loc) · 179 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper plugin-docs plugin-id-default docs-version-current docs-doc-page docs-doc-id-tutorial/hello-world" data-has-hydrated="false">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v3.9.2">
<title data-rh="true">Hello world app without CLI | Agent-first open-source admin panel framework</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:image" content="https://adminforth.dev/img/og.jpg"><meta data-rh="true" name="twitter:image" content="https://adminforth.dev/img/og.jpg"><meta data-rh="true" property="og:url" content="https://adminforth.dev/docs/tutorial/hello-world/"><meta data-rh="true" property="og:locale" content="en"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="current"><meta data-rh="true" name="docusaurus_tag" content="docs-default-current"><meta data-rh="true" name="docsearch:version" content="current"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-current"><meta data-rh="true" property="og:title" content="Hello world app without CLI | Agent-first open-source admin panel framework"><meta data-rh="true" name="description" content="Manual code way walkthrough (alternative to CLI) for building a minimal AdminForth app without the CLI, including project setup, resources, authentication, and server configuration."><meta data-rh="true" property="og:description" content="Manual code way walkthrough (alternative to CLI) for building a minimal AdminForth app without the CLI, including project setup, resources, authentication, and server configuration."><meta data-rh="true" name="twitter:title" content="Hello world app without CLI"><meta data-rh="true" name="twitter:description" content="Manual code way walkthrough (alternative to CLI) for building a minimal AdminForth app without the CLI, including project setup, resources, authentication, and server configuration."><link data-rh="true" rel="icon" href="/img/favicon.png"><link data-rh="true" rel="canonical" href="https://adminforth.dev/docs/tutorial/hello-world/"><link data-rh="true" rel="alternate" href="https://adminforth.dev/docs/tutorial/hello-world/" hreflang="en"><link data-rh="true" rel="alternate" href="https://adminforth.dev/docs/tutorial/hello-world/" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://VSIPOF54AV-dsn.algolia.net" crossorigin="anonymous"><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"TechArticle","headline":"Hello world app without CLI","description":"Manual code way walkthrough (alternative to CLI) for building a minimal AdminForth app without the CLI, including project setup, resources, authentication, and server configuration.","url":"https://adminforth.dev/docs/tutorial/hello-world","dateModified":"2026-08-14T10:08:21.000Z"}</script><script data-rh="true" type="application/ld+json">{"@context":"https://schema.org","@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"Hello world app without CLI","item":"https://adminforth.dev/docs/tutorial/hello-world"}]}</script><link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Agent-first open-source admin panel framework RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Agent-first open-source admin panel framework Atom Feed">
<link rel="preconnect" href="https://www.google-analytics.com">
<link rel="preconnect" href="https://www.googletagmanager.com">
<script async src="https://www.googletagmanager.com/gtag/js?id=G-7K99Q2BH04"></script>
<script>function gtag(){dataLayer.push(arguments)}window.dataLayer=window.dataLayer||[],gtag("js",new Date),gtag("config","G-7K99Q2BH04",{anonymize_ip:!0})</script>
<link rel="search" type="application/opensearchdescription+xml" title="Agent-first open-source admin panel framework" href="/opensearch.xml">
<meta name="application-name" content="AdminForth">
<meta name="robots" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1">
<meta name="googlebot" content="index,follow,max-image-preview:large,max-snippet:-1,max-video-preview:-1">
<meta name="keywords" content="agent-first admin panel framework, open-source admin panel, agentic back office, tailwind admin framework, vue typescript admin panel, internal admin agent">
<link rel="image_src" href="https://adminforth.dev/img/adminforth_screenshot.png">
<script type="application/ld+json">{"@context":"https://schema.org","@type":"WebSite","name":"AdminForth","url":"https://adminforth.dev","description":"Agent-first open-source admin panel framework. Build robust and powerful agentic back-office panels for your projects while maintaining full control over the code.","keywords":"backoffice, vue backoffice, agent-first admin panel framework, open-source admin panel, agentic back office, tailwind admin framework, vue typescript admin panel, internal admin agent"}</script>
<script src="/scripts/adminforth.js"></script>
<script src="/scripts/tluma-config.js"></script>
<script src="https://tluma.ai/widget.js" async></script><link rel="stylesheet" href="/assets/css/styles.e5bdffa0.css">
<script src="/assets/js/runtime~main.33b4e60d.js" defer="defer"></script>
<script src="/assets/js/main.0f480a02.js" defer="defer"></script>
</head>
<body class="navigation-with-keyboard">
<svg style="display: none;"><defs>
<symbol id="theme-svg-external-link" viewBox="0 0 24 24"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"/></symbol>
</defs></svg>
<script>!function(){var t=function(){try{return new URLSearchParams(window.location.search).get("docusaurus-theme")}catch(t){}}()||function(){try{return window.localStorage.getItem("theme")}catch(t){}}();document.documentElement.setAttribute("data-theme",t||"light"),document.documentElement.setAttribute("data-theme-choice",t||"light")}(),function(){try{const c=new URLSearchParams(window.location.search).entries();for(var[t,e]of c)if(t.startsWith("docusaurus-data-")){var a=t.replace("docusaurus-data-","data-");document.documentElement.setAttribute(a,e)}}catch(t){}}()</script><div id="__docusaurus"><div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#__docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="theme-layout-navbar navbar navbar--fixed-top"><div class="navbar__inner"><div class="theme-layout-navbar-left navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.svg" alt="AdminForth Logo" class="themedComponent_mlkZ themedComponent--light_NVdE"><img src="/img/logo.svg" alt="AdminForth Logo" class="themedComponent_mlkZ themedComponent--dark_xIcU"></div><b class="navbar__title text--truncate">AdminForth</b></a><a aria-current="page" class="navbar__item navbar__link navbar__link--active" href="/docs/tutorial/gettingStarted/">Tutorial</a><a class="navbar__item navbar__link" href="/docs/api/">API</a><a class="navbar__item navbar__link" href="/blog/">Blog</a></div><div class="theme-layout-navbar-right navbar__items navbar__items--right"><div class="navbarSearchContainer_Bca1"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search (Command+K)"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20" aria-hidden="true"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div><a href="https://demo.adminforth.dev/" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">Live Demo<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><a href="https://github.com/devforth/adminforth" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="system mode" aria-label="Switch between dark and light mode (currently system mode)"><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" class="toggleIcon_g3eP systemToggleIcon_QzmC"><path fill="currentColor" d="m12 21c4.971 0 9-4.029 9-9s-4.029-9-9-9-9 4.029-9 9 4.029 9 9 9zm4.95-13.95c1.313 1.313 2.05 3.093 2.05 4.95s-0.738 3.637-2.05 4.95c-1.313 1.313-3.093 2.05-4.95 2.05v-14c1.857 0 3.637 0.737 4.95 2.05z"></path></svg></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="__docusaurus_skipToContent_fallback" class="theme-layout-main main-wrapper mainWrapper_z2l0"><div class="docsWrapper_hBAB"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docRoot_UBD9"><aside class="theme-doc-sidebar-container docSidebarContainer_YfHR"><div class="sidebarViewport_aRkj"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/gettingStarted/"><span title="Getting Started" class="linkLabel_WmDU">Getting Started</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item hidden-sidebar"><a class="menu__link menu__link--active" aria-current="page" href="/docs/tutorial/hello-world/"><span title="Hello world app without CLI" class="linkLabel_WmDU">Hello world app without CLI</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/glossary/"><span title="Glossary" class="linkLabel_WmDU">Glossary</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="true" href="/docs/tutorial/Customization/branding/"><span title="Customization" class="categoryLinkLabel_W154">Customization</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/branding/"><span title="Branding and Theming" class="linkLabel_WmDU">Branding and Theming</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/customFieldRendering/"><span title="Custom record field rendering" class="linkLabel_WmDU">Custom record field rendering</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/virtualColumns/"><span title="Virtual columns" class="linkLabel_WmDU">Virtual columns</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/hooks/"><span title="Hooks" class="linkLabel_WmDU">Hooks</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/limitingAccess/"><span title="Limiting actions access" class="linkLabel_WmDU">Limiting actions access</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/customPages/"><span title="Custom pages" class="linkLabel_WmDU">Custom pages</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/alert/"><span title="Alerts and confirmations" class="linkLabel_WmDU">Alerts and confirmations</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/pageInjections/"><span title="Page Injections" class="linkLabel_WmDU">Page Injections</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/Actions/"><span title="Actions" class="linkLabel_WmDU">Actions</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/menuConfiguration/"><span title="Menu & Header" class="linkLabel_WmDU">Menu & Header</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/dataApi/"><span title="Data API" class="linkLabel_WmDU">Data API</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/security/"><span title="Security" class="linkLabel_WmDU">Security</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/standardPagesTuning/"><span title="Standard pages tuning" class="linkLabel_WmDU">Standard pages tuning</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/afcl/"><span title="AdminForth Components Library" class="linkLabel_WmDU">AdminForth Components Library</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Customization/websocket/"><span title="Websocket" class="linkLabel_WmDU">Websocket</span></a></li></ul></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/connectors/"><span title="Connectors" class="linkLabel_WmDU">Connectors</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/deploy/"><span title="Deploy in Docker" class="linkLabel_WmDU">Deploy in Docker</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist" href="/docs/tutorial/ListOfAdapters/"><span title="Adapters" class="categoryLinkLabel_W154">Adapters</span></a><button aria-label="Expand sidebar category 'Adapters'" aria-expanded="false" type="button" class="clean-btn menu__caret"></button></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/CLICommands/"><span title="CLI Commands" class="linkLabel_WmDU">CLI Commands</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/tutorial/UsageOfLogger/"><span title="Usage of the logger" class="linkLabel_WmDU">Usage of the logger</span></a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist" href="/docs/tutorial/ListOfPlugins/"><span title="Plugins" class="categoryLinkLabel_W154">Plugins</span></a><button aria-label="Collapse sidebar category 'Plugins'" aria-expanded="true" type="button" class="clean-btn menu__caret"></button></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/agent/"><span title="Agent" class="linkLabel_WmDU">Agent</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/two-factors-auth/"><span title="Two-Factor Authentication Plugin" class="linkLabel_WmDU">Two-Factor Authentication Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/foreign-inline-list/"><span title="Foreign Inline List" class="linkLabel_WmDU">Foreign Inline List</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/audit-log/"><span title="Audit Log" class="linkLabel_WmDU">Audit Log</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/markdown/"><span title="Markdown" class="linkLabel_WmDU">Markdown</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/email-password-reset/"><span title="Email Password Reset" class="linkLabel_WmDU">Email Password Reset</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/import-export/"><span title="Import Export" class="linkLabel_WmDU">Import Export</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/open-signup/"><span title="Open Signup" class="linkLabel_WmDU">Open Signup</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/i18n/"><span title="Internationalization (i18n)" class="linkLabel_WmDU">Internationalization (i18n)</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/oauth/"><span title="OAuth Authentication" class="linkLabel_WmDU">OAuth Authentication</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/inline-create/"><span title="Inline Create" class="linkLabel_WmDU">Inline Create</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/list-in-place-edit/"><span title="List In-Place Edit" class="linkLabel_WmDU">List In-Place Edit</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/text-complete/"><span title="Text Complete" class="linkLabel_WmDU">Text Complete</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/foreign-inline-show/"><span title="Foreign Inline Show" class="linkLabel_WmDU">Foreign Inline Show</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/email-invite/"><span title="Email Invite" class="linkLabel_WmDU">Email Invite</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/bulk-ai-flow/"><span title="Bulk AI Flow" class="linkLabel_WmDU">Bulk AI Flow</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/universal-search/"><span title="Universal Search (Legacy)" class="linkLabel_WmDU">Universal Search (Legacy)</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/login-captcha/"><span title="Login Captcha" class="linkLabel_WmDU">Login Captcha</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/user-soft-delete/"><span title="User Soft Delete" class="linkLabel_WmDU">User Soft Delete</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/clone-row/"><span title="Clone Row" class="linkLabel_WmDU">Clone Row</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/many2many/"><span title="Many to Many" class="linkLabel_WmDU">Many to Many</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/background-jobs/"><span title="Background Jobs" class="linkLabel_WmDU">Background Jobs</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/quick-filters/"><span title="Quick Filters" class="linkLabel_WmDU">Quick Filters</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/auto-remove/"><span title="Auto Remove Plugin" class="linkLabel_WmDU">Auto Remove Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/rich-editor/"><span title="Rich Editor" class="linkLabel_WmDU">Rich Editor</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/CRUDApprove/"><span title="CRUD Approve Plugin" class="linkLabel_WmDU">CRUD Approve Plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/json-form/"><span title="JSON Form" class="linkLabel_WmDU">JSON Form</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/upload/"><span title="Upload" class="linkLabel_WmDU">Upload</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/05-1-upload-api/"><span title="Upload API" class="linkLabel_WmDU">Upload API</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/dashboard/"><span title="Dashboard plugin" class="linkLabel_WmDU">Dashboard plugin</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Plugins/dashboard-reference/"><span title="Dashboard Query Reference" class="linkLabel_WmDU">Dashboard Query Reference</span></a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="categoryLink_byQd menu__link menu__link--sublist menu__link--sublist-caret" role="button" aria-expanded="true" href="/docs/tutorial/Advanced/plugin-development/"><span title="Advanced" class="categoryLinkLabel_W154">Advanced</span></a></div><ul class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Advanced/plugin-development/"><span title="Plugin development guide" class="linkLabel_WmDU">Plugin development guide</span></a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-2 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/tutorial/Advanced/working-without-direct-database-connection/"><span title="Working without direct database connection" class="linkLabel_WmDU">Working without direct database connection</span></a></li></ul></li></ul></nav></div></div></aside><main class="docMainContainer_TBSr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link">Hello world app without CLI</span></li></ul></nav><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Hello world app without CLI</h1></header>
<p>While AdminForth CLI is the fastest way to create a new project, you can also create a new project manually.</p>
<p>This might help you better understand how AdminForth project is structured and how to customize it.</p>
<p>Here we create database with users and posts tables and admin panel for it.</p>
<p>Users table will be used to store a credentials for login into admin panel itself.</p>
<p>When back-office user creates a new post it will be automatically assigned using <code>authorId</code> to the user who created it.</p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="prerequisites">Prerequisites<a href="#prerequisites" class="hash-link" aria-label="Direct link to Prerequisites" title="Direct link to Prerequisites" translate="no"></a></h2>
<p>We will use Node v20 for this demo. If you have other Node versions, we recommend using <a href="https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script" target="_blank" rel="noopener noreferrer" class="">NVM</a> to switch them easily:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">nvm </span><span class="token function" style="color:#e6db74">install</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">20</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">nvm </span><span class="token builtin class-name" style="color:#e6db74">alias</span><span class="token plain"> default </span><span class="token number" style="color:#ae81ff">20</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">nvm use </span><span class="token number" style="color:#ae81ff">20</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="installation">Installation<a href="#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no"></a></h2>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">mkdir</span><span class="token plain"> af-hello</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token builtin class-name" style="color:#e6db74">cd</span><span class="token plain"> af-hello</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> init</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">add</span><span class="token plain"> adminforth express@^4 @dotenvx/dotenvx @types/express typescript tsx @types/node prisma @prisma/client </span><span class="token parameter variable" style="color:#f8f8f2">-D</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">npx </span><span class="token parameter variable" style="color:#f8f8f2">--yes</span><span class="token plain"> tsc </span><span class="token parameter variable" style="color:#f8f8f2">--init</span><span class="token plain"> </span><span class="token parameter variable" style="color:#f8f8f2">--module</span><span class="token plain"> NodeNext </span><span class="token parameter variable" style="color:#f8f8f2">--target</span><span class="token plain"> ESNext</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="environment-variables">Environment variables<a href="#environment-variables" class="hash-link" aria-label="Direct link to Environment variables" title="Direct link to Environment variables" translate="no"></a></h2>
<p>Create two files in your project's root directory:</p>
<ul>
<li class=""><code>.env.local</code> — Place your non-sensitive environment variables here (e.g., local database paths, default configurations). This file can be safely committed to your repository as a demo or template configuration.</li>
<li class=""><code>.env</code> — Store sensitive tokens and secrets here (for example, <code>ADMINFORTH_SECRET</code> and other private keys). Ensure that <code>.env</code> is added to your <code>.gitignore</code> to prevent accidentally committing sensitive data.</li>
</ul>
<p>Put the following content to the <code>.env.local</code> file:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./.env.local</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token assign-left variable" style="color:#f8f8f2">ADMINFORTH_SECRET</span><span class="token operator" style="color:#66d9ef">=</span><span class="token number" style="color:#ae81ff">123</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token assign-left variable" style="color:#f8f8f2">NODE_ENV</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">development</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token assign-left variable" style="color:#f8f8f2">DATABASE_URL</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">sqlite://.db.sqlite</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token assign-left variable" style="color:#f8f8f2">PRISMA_DATABASE_URL</span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain">file:.db.sqlite</span><br></span></code></pre></div></div>
<blockquote>
<p>☝️ Production best practices:</p>
<ol>
<li class="">Most likely you not need <code>.env</code> file at all, instead you should use environment variables (from Docker, Kubernetes, Operating System, etc.)</li>
<li class="">Set <code>NODE_ENV</code> to <code>production</code> in your deployment environment to optimize performance and disable development features like hot reloading.</li>
<li class="">You should generate very unique value <code>ADMINFORTH_SECRET</code> and store it in Vault or other secure place.</li>
</ol>
</blockquote>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-up-the-scripts">Setting up the scripts<a href="#setting-up-the-scripts" class="hash-link" aria-label="Direct link to Setting up the scripts" title="Direct link to Setting up the scripts" translate="no"></a></h2>
<p>Open <code>package.json</code> and add the following scripts:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./package.json</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> ...</span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"type"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"module"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"scripts"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> ...</span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"dev"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"pnpm _env:dev tsx watch index.ts"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"prod"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"pnpm _env:prod tsx index.ts"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"start"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"pnpm dev"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"makemigration"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"pnpm _env:dev npx --yes prisma migrate dev --create-only"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"migrate:local"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"pnpm _env:dev npx --yes prisma migrate deploy"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"migrate:prod"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"pnpm _env:prod npx --yes prisma migrate deploy"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"_env:dev"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"dotenvx run -f .env -f .env.local --"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"_env:prod"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"dotenvx run -f .env.prod --"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"engines"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"author"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">""</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"node"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">">=20"</span><span class="token plain"></span><br></span><span class="token-line code-block-diff-add-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>Create <code>./pnpm-workspace.yaml</code> and put next content there:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./pnpm-workspace.yaml</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">onlyBuiltDependencies</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> - better-sqlite3</span><br></span></code></pre></div></div>
<p>Run installation command to apply all dependencies</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">install</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="setting-up-adminforth">Setting up AdminForth<a href="#setting-up-adminforth" class="hash-link" aria-label="Direct link to Setting up AdminForth" title="Direct link to Setting up AdminForth" translate="no"></a></h2>
<p>Create <code>index.ts</code> file in root directory with following content:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./index.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> express </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'express'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForth </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> usersResource </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"./resources/adminuser.js"</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> fileURLToPath </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'url'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> path </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'path'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> Filters </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> initApi </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'./api.js'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> logger </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> </span><span class="token constant" style="color:#e6db74">ADMIN_BASE_URL</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">''</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> admin </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">AdminForth</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> baseUrl</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token constant" style="color:#e6db74">ADMIN_BASE_URL</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> auth</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> usersResourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> usernameField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'email'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> passwordHashField</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'password_hash'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> rememberMeDuration</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'30d'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> loginBackgroundImage</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'https://images.unsplash.com/photo-1534239697798-120952b76f2b?q=80&w=3389&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> loginBackgroundPosition</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'1/2'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">loginPromptHTML</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> adminforthUserExists </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">resource</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">"adminuser"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">count</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">Filters</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">EQ</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'email'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">></span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">adminforthUserExists</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"Please use <b>adminforth</b> as username and <b>adminforth</b> as password"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> customization</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> brandName</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"myadmin"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> title</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"myadmin"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> datesFormat</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'DD MMM'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> timeFormat</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'HH:mm a'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showBrandNameInSidebar</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showBrandLogoInSidebar</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> emptyFieldPlaceholder</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'-'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> styles</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> colors</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> light</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primary</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'#1a56db'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sidebar</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> main</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'#f9fafb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> text</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'#213045'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dark</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primary</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'#82ACFF'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> sidebar</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> main</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'#1f2937'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> text</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'#9ca3af'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dataSources</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'maindb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> url</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">process</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation">env</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation constant" style="color:#e6db74">DATABASE_URL</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resources</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> usersResource</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> menu</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'heading'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'SYSTEM'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Users'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> icon</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'flowbite:user-solid'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token function" style="color:#e6db74">fileURLToPath</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">import</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">meta</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">url</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> path</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">resolve</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">argv</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token number" style="color:#ae81ff">1</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> app </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">express</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> app</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">use</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">express</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">json</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function" style="color:#e6db74">initApi</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> port </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">3500</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">bundleNow</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> hotReload</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> process</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">env</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">NODE_ENV</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'development'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">then</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> logger</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">info</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'Bundling AdminForth SPA done.'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">express</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">serve</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">app</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">discoverDatabases</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">then</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">resource</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">count</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">0</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">resource</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">create</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> email</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> password_hash</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">Utils</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">generatePasswordHash</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> role</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'superadmin'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">express</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">listen</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">port</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> logger</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">info</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">\x1b[38;5;249m ⚡ AdminForth is available at\x1b[1m\x1b[38;5;46m http://localhost:</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">port</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation constant" style="color:#e6db74">ADMIN_BASE_URL</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">\x1b[0m\n</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span></code></pre></div></div>
<blockquote>
<p>☝️ For simplicity we defined whole configuration in one file. Normally once configuration grows you should
move each resource configuration to separate file and organize them to folder and import them in <code>index.ts</code>.</p>
</blockquote>
<p>Create <code>api.ts</code> file in root directory with following content:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./api.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> Express</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> Response </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"express"</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> IAdminForth</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> IAdminUserExpressRequest </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"adminforth"</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">*</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> z </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"zod"</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">initApi</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">app</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> Express</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> admin</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> IAdminForth</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> app</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">get</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">admin</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation">config</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation">baseUrl</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string string" style="color:#a6e22e">/api/hello/</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">express</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">withSchema</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> description</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"Returns example data from a custom Express API together with the current authenticated AdminForth user."</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> response</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">object</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> message</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> users</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">array</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">record</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">unknown</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">record</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">string</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> z</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">unknown</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// you can use data API to work with your database https://adminforth.dev/docs/tutorial/Customization/dataApi/</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// and admin.express.authorize to inject req.adminUser</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">express</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">authorize</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">req</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> IAdminUserExpressRequest</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> res</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> Response</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">const</span><span class="token plain"> allUsers </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> admin</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">resource</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">"adminuser"</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">list</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> res</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">json</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> message</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"Hello from AdminForth API!"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> users</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allUsers</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> req</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">adminUser</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<blockquote>
<p>Install and import Zod before using this pattern: <code>pnpm add zod</code> or <code>npm install zod</code>, then <code>import * as z from 'zod';</code>. <code>admin.express.withSchema(...)</code> will convert the Zod schema to OpenAPI for you.</p>
</blockquote>
<p>Update <code>tsconfig.json</code> file in root directory with following content:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./tsconfig.json</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"compilerOptions"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"target"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"esnext"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"module"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"nodenext"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"esModuleInterop"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"forceConsistentCasingInFileNames"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"strict"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"exclude"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">"node_modules"</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"dist"</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<p>Create new directory <code>./resources/adminuser.ts</code> with following content:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./resources/adminuser.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthDataTypes </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> AdminForthResource</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> randomUUID </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'crypto'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> logger </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminforth'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">function</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">allowedForSuperAdmin</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">Promise</span><span class="token operator" style="color:#66d9ef"><</span><span class="token builtin" style="color:#e6db74">boolean</span><span class="token operator" style="color:#66d9ef">></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">role </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'superadmin'</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> dataSource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'maindb'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> table</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> resourceId</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'adminuser'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Admin Users'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">recordLabel</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">r</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">👤 </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">r</span><span class="token template-string interpolation punctuation" style="color:#f8f8f2">.</span><span class="token template-string interpolation">email</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> options</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> allowedActions</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmin</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">delete</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> allowedForSuperAdmin</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> columns</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'id'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> primaryKey</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> initialRecord</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token function" style="color:#e6db74">randomUUID</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'email'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> required</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> isUnique</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> validation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// you can also use AdminForth.Utils.EMAIL_VALIDATOR which is alias to this object</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> regExp</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> message</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Email is not valid, must be in format example@test.com'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'created_at'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">DATETIME</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">fillOnCreate</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> initialRecord</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token keyword" style="color:#66d9ef">new</span><span class="token plain"> </span><span class="token class-name" style="color:#e6db74">Date</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">toISOString</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'role'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">enum</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> value</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'superadmin'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Super Admin'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> value</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'user'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> label</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'User'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'password'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> virtual</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// field will not be persisted into db</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> required</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// make required only on create page</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> editingNote</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'Leave empty to keep password unchanged'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// to show field only on create and edit pages</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> show</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> list</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> filter</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> masked</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// to show stars in input field</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> minLength</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token number" style="color:#ae81ff">8</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> validation</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token comment" style="color:#8292a2;font-style:italic">// request to have at least 1 digit, 1 upper case, 1 lower case</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">Utils</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">PASSWORD_VALIDATORS</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">UP_LOW_NUM</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> name</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'password_hash'</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> type</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthDataTypes</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token constant" style="color:#e6db74">STRING</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> backendOnly</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> showIn</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> all</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> hooks</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> create</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">beforeSave</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> record</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> resource </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> record</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">any</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> resource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthResource </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> record</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">password_hash </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">Utils</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">generatePasswordHash</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">record</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">password</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> edit</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token function-variable function" style="color:#e6db74">beforeSave</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> oldRecord</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> updates</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> resource </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> oldRecord</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">any</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> updates</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token builtin" style="color:#e6db74">any</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> adminUser</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminUser</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> resource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> AdminForthResource </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token operator" style="color:#66d9ef">=></span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> logger</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">info</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token template-string string" style="color:#a6e22e">Updating user, </span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">${</span><span class="token template-string interpolation">updates</span><span class="token template-string interpolation interpolation-punctuation punctuation" style="color:#f8f8f2">}</span><span class="token template-string template-punctuation string" style="color:#a6e22e">`</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">oldRecord</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">id </span><span class="token operator" style="color:#66d9ef">===</span><span class="token plain"> adminUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">dbUser</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">id </span><span class="token operator" style="color:#66d9ef">&&</span><span class="token plain"> updates</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">role</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">false</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> error</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'You cannot change your own role'</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">updates</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">password</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> updates</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">password_hash </span><span class="token operator" style="color:#66d9ef">=</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">await</span><span class="token plain"> AdminForth</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">Utils</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token function" style="color:#e6db74">generatePasswordHash</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token plain">updates</span><span class="token punctuation" style="color:#f8f8f2">.</span><span class="token plain">password</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> ok</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token boolean" style="color:#ae81ff">true</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">as</span><span class="token plain"> AdminForthResourceInput</span><span class="token punctuation" style="color:#f8f8f2">;</span><br></span></code></pre></div></div>
<p>Create new directory <code>./custom/tsconfig.json</code> with following content:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./custom/tsconfig.json</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"compilerOptions"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"baseUrl"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"."</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"paths"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"@/*"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">"../node_modules/adminforth/dist/spa/src/*"</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string-property property" style="color:#f92672">"@@/*"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token string" style="color:#a6e22e">"./*"</span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="database-creation">Database creation<a href="#database-creation" class="hash-link" aria-label="Direct link to Database creation" title="Direct link to Database creation" translate="no"></a></h2>
<blockquote>
<p>☝️ For demo purposes we will create a database using Prisma and SQLite.
You can also create it using any other favorite tool or ORM and skip this step.</p>
</blockquote>
<p>Create <code>./schema.prisma</code> and put next content there:</p>
<div class="language-text codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./schema.prisma</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-text codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token plain">generator client {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> provider = "prisma-client-js"</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">datasource db {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> provider = "sqlite"</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">model adminuser {</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> id String @id</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> email String @unique</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> password_hash String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> role String</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> created_at DateTime</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain">}</span><br></span></code></pre></div></div>
<p>Create <code>./prisma.config.ts</code> and put next content there:</p>
<div class="language-ts codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockTitle_OeMC">./prisma.config.ts</div><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-ts codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'dotenv/config'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"> defineConfig</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"> env </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">from</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">'prisma/config'</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token keyword" style="color:#66d9ef">export</span><span class="token plain"> </span><span class="token keyword" style="color:#66d9ef">default</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">defineConfig</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> datasource</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> url</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">env</span><span class="token punctuation" style="color:#f8f8f2">(</span><span class="token string" style="color:#a6e22e">'PRISMA_DATABASE_URL'</span><span class="token punctuation" style="color:#f8f8f2">)</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token punctuation" style="color:#f8f8f2">)</span><br></span></code></pre></div></div>
<p>Create database using <code>prisma migrate</code>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> run makemigration </span><span class="token parameter variable" style="color:#f8f8f2">--name</span><span class="token plain"> init </span><span class="token punctuation" style="color:#f8f8f2">;</span><span class="token plain"> </span><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> run migrate:local</span><br></span></code></pre></div></div>
<p>Now you can run your app:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token function" style="color:#e6db74">pnpm</span><span class="token plain"> start</span><br></span></code></pre></div></div>
<p>Open <a href="http://localhost:3500" target="_blank" rel="noopener noreferrer" class="">http://localhost:3500</a> in your browser and login with credentials <code>adminforth</code> / <code>adminforth</code>.</p>
<p><img decoding="async" loading="lazy" alt="alt text" src="/assets/images/localhost_3500_login-22b59511349c51948267c9a4080e4d87.png" width="2428" height="1932" class="img_ev3q"></p>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="initializing-custom-directory">Initializing custom directory<a href="#initializing-custom-directory" class="hash-link" aria-label="Direct link to Initializing custom directory" title="Direct link to Initializing custom directory" translate="no"></a></h2>
<p>If you are not using CLI, you can create <code>custom</code> directory and initialize it with <code>npm</code>:</p>
<div class="language-bash codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-bash codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token builtin class-name" style="color:#e6db74">cd</span><span class="token plain"> ./custom</span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token function" style="color:#e6db74">npm</span><span class="token plain"> init </span><span class="token parameter variable" style="color:#f8f8f2">-y</span><br></span></code></pre></div></div>
<p>We will use this directory for all custom components. If you want to call your dir with other name then <code>custom</code>, just set <a class="" href="/docs/api/Back/interfaces/AdminForthConfigCustomization/#customcomponentsdir">customComponentsDir option</a></p>
<p>Also, for better development experience we recommend to create file <code>custom/tsconfig.json</code> with the following content:</p>
<div class="language-json codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#f8f8f2;--prism-background-color:#272822"><div class="codeBlockContent_QJqH"><pre tabindex="0" class="prism-code language-json codeBlock_bY9V thin-scrollbar" style="color:#f8f8f2;background-color:#272822"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#f8f8f2"><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"compilerOptions"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"baseUrl"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"."</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"paths"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">{</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"@/*"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"../node_modules/adminforth/dist/spa/src/*"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"*"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"../node_modules/adminforth/dist/spa/node_modules/*"</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token punctuation" style="color:#f8f8f2">,</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token property" style="color:#f92672">"@@/*"</span><span class="token operator" style="color:#66d9ef">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">[</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token string" style="color:#a6e22e">"."</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">]</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"> </span><span class="token punctuation" style="color:#f8f8f2">}</span><span class="token plain"></span><br></span><span class="token-line" style="color:#f8f8f2"><span class="token plain"></span><span class="token punctuation" style="color:#f8f8f2">}</span><br></span></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_Vzrq" id="possible-configuration-options">Possible configuration options<a href="#possible-configuration-options" class="hash-link" aria-label="Direct link to Possible configuration options" title="Direct link to Possible configuration options" translate="no"></a></h2>
<p>Check <a class="" href="/docs/api/Back/interfaces/AdminForthConfig/">AdminForthConfig</a> for all possible options.</p></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="row margin-top--sm theme-doc-footer-edit-meta-row"><div class="col noPrint_WFHX"></div><div class="col lastUpdated_JAkA"><span class="theme-last-updated">Last updated<!-- --> on <b><time datetime="2026-08-14T10:08:21.000Z" itemprop="dateModified">Aug 14, 2026</time></b></span></div></div></footer></article><nav class="docusaurus-mt-lg pagination-nav" aria-label="Docs pages"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/tutorial/gettingStarted/"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">Getting Started</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/tutorial/glossary/"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">Glossary</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#prerequisites" class="table-of-contents__link toc-highlight">Prerequisites</a></li><li><a href="#installation" class="table-of-contents__link toc-highlight">Installation</a></li><li><a href="#environment-variables" class="table-of-contents__link toc-highlight">Environment variables</a></li><li><a href="#setting-up-the-scripts" class="table-of-contents__link toc-highlight">Setting up the scripts</a></li><li><a href="#setting-up-adminforth" class="table-of-contents__link toc-highlight">Setting up AdminForth</a></li><li><a href="#database-creation" class="table-of-contents__link toc-highlight">Database creation</a></li><li><a href="#initializing-custom-directory" class="table-of-contents__link toc-highlight">Initializing custom directory</a></li><li><a href="#possible-configuration-options" class="table-of-contents__link toc-highlight">Possible configuration options</a></li></ul></div></div></div></div></main></div></div></div><footer class="theme-layout-footer footer footer--dark"><div class="container container-fluid"><div class="row footer__links"><div class="theme-layout-footer-column col footer__col"><div class="footer__title">Docs</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/docs/tutorial/gettingStarted/">Tutorial</a></li><li class="footer__item"><a href="https://demo.adminforth.dev/" target="_blank" rel="noopener noreferrer" class="footer__link-item">Live Demo</a></li><li class="footer__item"><a class="footer__link-item" href="/docs/api/">API</a></li><li class="footer__item"><a class="footer__link-item" href="/blog/archive/">Blog Archive</a></li><li class="footer__item"><a class="footer__link-item" href="/search/">Find anything</a></li></ul></div><div class="theme-layout-footer-column col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://devforth.io" target="_blank" rel="noopener noreferrer" class="footer__link-item">DevForth.io<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://devforth.io/contact" target="_blank" rel="noopener noreferrer" class="footer__link-item">We can develop admin panel for your project<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li><li class="footer__item"><a href="https://github.com/devforth/adminforth" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-label="(opens in new tab)" class="iconExternalLink_nPIU"><use href="#theme-svg-external-link"></use></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="footer__copyright">Copyright © 2026 Devforth sp. z o.o.</div></div></div></footer></div>
</body>
</html>