feat: multiple changes
Signed-off-by: Avior <git@avior.me>
This commit is contained in:
parent
d8f203f434
commit
3e91597dca
2
.github/workflows/lint.yml
vendored
2
.github/workflows/lint.yml
vendored
@ -19,7 +19,7 @@ jobs:
|
||||
run: npm ci
|
||||
|
||||
- name: Run BiomeJS
|
||||
run: npm run lint
|
||||
run: npx biome ci .
|
||||
# - uses: mongolyy/reviewdog-action-biome@v1
|
||||
# with:
|
||||
# github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import node from '@astrojs/node'
|
||||
import tailwind from '@astrojs/tailwind'
|
||||
import { defineConfig } from 'astro/config'
|
||||
import tailwind from "@astrojs/tailwind"
|
||||
import node from "@astrojs/node"
|
||||
import routing from './hooks/routing'
|
||||
|
||||
// const faviconHook = {
|
||||
@ -18,7 +18,7 @@ import routing from './hooks/routing'
|
||||
export default defineConfig({
|
||||
// Use the NodeJS adapter
|
||||
adapter: node({
|
||||
mode: "standalone"
|
||||
mode: 'standalone'
|
||||
}),
|
||||
|
||||
// some settings to the build output
|
||||
@ -66,7 +66,5 @@ export default defineConfig({
|
||||
usePolling: !!(process.env.USE_POLLING ?? process.env.WSL_DISTRO_NAME)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
})
|
||||
}
|
||||
})
|
10
biome.json
10
biome.json
@ -24,7 +24,8 @@
|
||||
"noStaticOnlyClass": "warn",
|
||||
"noUselessTypeConstraint": "warn",
|
||||
"noVoid": "error",
|
||||
"useSimplifiedLogicExpression": "warn"
|
||||
"useSimplifiedLogicExpression": "warn",
|
||||
"noForEach": "off"
|
||||
},
|
||||
"performance": {
|
||||
"noBarrelFile": "error",
|
||||
@ -46,7 +47,7 @@
|
||||
"options": {
|
||||
"strictCase": true,
|
||||
"requireAscii": true,
|
||||
"filenameCases": ["camelCase", "export"]
|
||||
"filenameCases": ["camelCase", "PascalCase", "export"]
|
||||
}
|
||||
},
|
||||
"useForOf": "error",
|
||||
@ -61,6 +62,9 @@
|
||||
"useNodeAssertStrict": "warn",
|
||||
"useNumberNamespace": "warn",
|
||||
"useSingleCaseStatement": "warn"
|
||||
},
|
||||
"suspicious": {
|
||||
"noEmptyInterface": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -74,7 +78,7 @@
|
||||
"semicolons": "asNeeded",
|
||||
"quoteStyle": "single",
|
||||
"trailingComma": "none",
|
||||
"lineWidth": 200,
|
||||
"lineWidth": 120,
|
||||
"bracketSameLine": true
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
import { expect, test } from '@playwright/test'
|
||||
|
||||
test('has title', async ({ page }) => {
|
||||
await page.goto('/');
|
||||
await page.goto('/')
|
||||
|
||||
// Expect a title "to contain" a substring.
|
||||
await expect(page).toHaveTitle(/Dzeio/);
|
||||
await expect(page).toHaveTitle(/Dzeio/)
|
||||
})
|
||||
|
@ -53,14 +53,14 @@ async function updateRoutes(output: string, routes: Array<string>) {
|
||||
let file = baseFile
|
||||
file += `\n\nexport type Routes = ${routes.map((it) => `'${it}'`).join(' | ')}`
|
||||
|
||||
file += '\n\nexport default function route(route: Routes, query?: Record<string, string | number>) {'
|
||||
file +=
|
||||
'\n\nexport default function route(route: Routes, query?: Record<string, string | number>) {'
|
||||
file += '\n\treturn formatRoute(route, query)'
|
||||
file += '\n}\n'
|
||||
|
||||
await fs.writeFile(output, file)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* format the path back to an url usable by the app
|
||||
*
|
||||
@ -141,7 +141,6 @@ const integration: () => AstroIntegration = () => ({
|
||||
await updateRoutes(outputFile, files)
|
||||
},
|
||||
'astro:server:setup': async ({ server }) => {
|
||||
|
||||
// get the files list
|
||||
const files = (await Promise.all([
|
||||
await getFiles(pagesFolder).then((ev) => ev.map((it) => formatPath(pagesFolder, it))),
|
||||
@ -158,7 +157,7 @@ const integration: () => AstroIntegration = () => ({
|
||||
|
||||
let removeExtension = true
|
||||
let folder = pagesFolder
|
||||
if(path.startsWith(publicFolder)) {
|
||||
if (path.startsWith(publicFolder)) {
|
||||
removeExtension = false
|
||||
folder = publicFolder
|
||||
} else if (!path.startsWith(folder)) {
|
||||
@ -178,7 +177,7 @@ const integration: () => AstroIntegration = () => ({
|
||||
path = path.replace(/\\/g, '/')
|
||||
let removeExtension = true
|
||||
let folder = pagesFolder
|
||||
if(path.startsWith(publicFolder)) {
|
||||
if (path.startsWith(publicFolder)) {
|
||||
removeExtension = false
|
||||
folder = publicFolder
|
||||
}
|
||||
|
@ -12,32 +12,39 @@ export default defineConfig({
|
||||
fullyParallel: true,
|
||||
forbidOnly: !!process.env.CI,
|
||||
retries: process.env.CI ? 2 : 0,
|
||||
workers: process.env.CI ? 1 : undefined as any,
|
||||
reporter: process.env.CI ? 'list' : [['html', {
|
||||
workers: process.env.CI ? 1 : (undefined as any),
|
||||
reporter: process.env.CI
|
||||
? 'list'
|
||||
: [
|
||||
[
|
||||
'html',
|
||||
{
|
||||
outputFolder: './playwright/report',
|
||||
open: 'never'
|
||||
}]],
|
||||
}
|
||||
]
|
||||
],
|
||||
use: {
|
||||
baseURL: 'http://localhost:3000',
|
||||
trace: 'on-first-retry',
|
||||
trace: 'on-first-retry'
|
||||
},
|
||||
|
||||
/* Configure projects for major browsers */
|
||||
projects: [
|
||||
{
|
||||
name: 'chromium',
|
||||
use: { ...devices['Desktop Chrome'] },
|
||||
use: { ...devices['Desktop Chrome'] }
|
||||
},
|
||||
|
||||
{
|
||||
name: 'firefox',
|
||||
use: { ...devices['Desktop Firefox'] },
|
||||
use: { ...devices['Desktop Firefox'] }
|
||||
},
|
||||
|
||||
{
|
||||
name: 'webkit',
|
||||
use: { ...devices['Desktop Safari'] },
|
||||
},
|
||||
use: { ...devices['Desktop Safari'] }
|
||||
}
|
||||
|
||||
/* Test against mobile viewports. */
|
||||
// {
|
||||
@ -58,5 +65,5 @@ export default defineConfig({
|
||||
// name: 'Google Chrome',
|
||||
// use: { ...devices['Desktop Chrome'], channel: 'chrome' },
|
||||
// },
|
||||
],
|
||||
]
|
||||
})
|
||||
|
@ -7,12 +7,11 @@ export interface Props extends astroHTML.JSX.AnchorHTMLAttributes {
|
||||
}
|
||||
|
||||
const classes = [
|
||||
"button",
|
||||
{outline: Astro.props.outline},
|
||||
{ghost: Astro.props.ghost},
|
||||
'button',
|
||||
{ outline: Astro.props.outline },
|
||||
{ ghost: Astro.props.ghost },
|
||||
Astro.props.class
|
||||
]
|
||||
|
||||
---
|
||||
{'href' in Astro.props && (
|
||||
<a class:list={classes} {...objectOmit(Astro.props, 'type') as any}>
|
||||
|
@ -1,12 +1,9 @@
|
||||
---
|
||||
import { getImage } from 'astro:assets'
|
||||
import AstroUtils from '../../libs/AstroUtils'
|
||||
import { objectOmit } from '@dzeio/object-util'
|
||||
import AstroUtils from '../../libs/AstroUtils'
|
||||
|
||||
const formats = [
|
||||
'avif',
|
||||
'webp'
|
||||
]
|
||||
const formats = ['avif', 'webp']
|
||||
|
||||
export interface Props extends Omit<astroHTML.JSX.ImgHTMLAttributes, 'src'> {
|
||||
src: ImageMetadata | string
|
||||
@ -17,7 +14,7 @@ export interface Props extends Omit<astroHTML.JSX.ImgHTMLAttributes, 'src'> {
|
||||
|
||||
type PictureResult = {
|
||||
format: 'new'
|
||||
formats: Array<{format: string, img: Awaited<ReturnType<typeof getImage>>}>
|
||||
formats: Array<{ format: string, img: Awaited<ReturnType<typeof getImage>> }>
|
||||
src: Awaited<ReturnType<typeof getImage>>
|
||||
} | {
|
||||
format: 'raw'
|
||||
@ -38,14 +35,25 @@ async function resolvePicture(image: ImageMetadata | string): Promise<PictureRes
|
||||
}
|
||||
}
|
||||
|
||||
const imageFormats: Array<{format: string, img: Awaited<ReturnType<typeof getImage>>}> = await Promise.all(
|
||||
const imageFormats: Array<{ format: string, img: Awaited<ReturnType<typeof getImage>> }> =
|
||||
await Promise.all(
|
||||
formats.map(async (it) => ({
|
||||
img: await getImage({src: Astro.props.src, format: it, width: Astro.props.width, height: Astro.props.height}),
|
||||
img: await getImage({
|
||||
src: Astro.props.src,
|
||||
format: it,
|
||||
width: Astro.props.width,
|
||||
height: Astro.props.height
|
||||
}),
|
||||
format: it
|
||||
}))
|
||||
)
|
||||
|
||||
const orig = await getImage({src: Astro.props.src, format: ext, width: Astro.props.width, height: Astro.props.height})
|
||||
const orig = await getImage({
|
||||
src: Astro.props.src,
|
||||
format: ext,
|
||||
width: Astro.props.width,
|
||||
height: Astro.props.height
|
||||
})
|
||||
|
||||
return {
|
||||
format: 'new',
|
||||
@ -62,7 +70,6 @@ const res = await AstroUtils.wrap<Result>(async () => {
|
||||
})
|
||||
|
||||
const props = objectOmit(Astro.props, 'src', 'srcDark', 'class')
|
||||
|
||||
---
|
||||
|
||||
{res.light.format === 'new' && (
|
||||
|
@ -6,7 +6,6 @@ interface Props extends Omit<astroHTML.JSX.InputHTMLAttributes, 'type'> {
|
||||
}
|
||||
|
||||
const baseProps = objectOmit(Astro.props, 'label', 'block')
|
||||
|
||||
---
|
||||
|
||||
<div class:list={[{parent: Astro.props.block}]}>
|
||||
|
@ -7,7 +7,7 @@ export interface Props extends Omit<astroHTML.JSX.InputHTMLAttributes, 'type'> {
|
||||
block?: boolean
|
||||
suffix?: string
|
||||
prefix?: string
|
||||
options: Array<string | number | {title: string | number, description?: string | number | null}>
|
||||
options: Array<string | number | { title: string | number, description?: string | number | null }>
|
||||
}
|
||||
|
||||
const baseProps = objectOmit(Astro.props, 'label', 'block', 'suffix', 'prefix', 'options')
|
||||
|
@ -87,8 +87,8 @@ export function setOnTableClick(table: HTMLTableElement, fn: (row: number, cell:
|
||||
table.querySelectorAll<HTMLTableCellElement>('td').forEach((it) => {
|
||||
it.addEventListener('click', () => {
|
||||
const row = it.parentElement as HTMLTableRowElement
|
||||
const rowIdx = parseInt(row.dataset.row as string)
|
||||
const cellIdx = parseInt(it.dataset.cell as string)
|
||||
const rowIdx = Number.parseInt(row.dataset.row as string)
|
||||
const cellIdx = Number.parseInt(it.dataset.cell as string)
|
||||
fn(rowIdx, cellIdx)
|
||||
})
|
||||
})
|
||||
|
@ -9,10 +9,9 @@ export interface Props {
|
||||
|
||||
if (Astro.props.icoPath !== '/favicon.ico') {
|
||||
console.warn('It is recommanded that the ICO file should be located at /favicon.ico')
|
||||
|
||||
}
|
||||
|
||||
const appleTouch = await getImage({src: Astro.props.png, width: 180, height: 180})
|
||||
const appleTouch = await getImage({ src: Astro.props.png, width: 180, height: 180 })
|
||||
---
|
||||
|
||||
<>
|
||||
|
@ -1,36 +0,0 @@
|
||||
import { getImage } from 'astro:assets'
|
||||
|
||||
export default class Manifest {
|
||||
static async create(baseImage: ImageMetadata, options: {
|
||||
name: string
|
||||
color?: string
|
||||
images?: Array<number>
|
||||
}) {
|
||||
const [
|
||||
i192,
|
||||
i512
|
||||
] = await Promise.all([
|
||||
getImage({src: baseImage, format: 'png', width: 192, height: 192}),
|
||||
getImage({src: baseImage, format: 'png', width: 512, height: 512})
|
||||
])
|
||||
return JSON.stringify({
|
||||
name: options.name,
|
||||
short_name: options.name,
|
||||
icons: [
|
||||
{
|
||||
src: i192.src,
|
||||
sizes: "192x192",
|
||||
type: "image/png"
|
||||
},
|
||||
{
|
||||
src: i512.src,
|
||||
sizes: "512x512",
|
||||
type: "image/png"
|
||||
}
|
||||
],
|
||||
theme_color: options.color ?? "#fff",
|
||||
background_color: options.color ?? "#fff",
|
||||
display: "standalone"
|
||||
})
|
||||
}
|
||||
}
|
@ -2,8 +2,8 @@
|
||||
const year = new Date().getFullYear()
|
||||
|
||||
export interface Props {
|
||||
links?: Array<{href: string, target?: string, display: string}>
|
||||
socials?: Array<{href: string, target?: string, icon: any}>
|
||||
links?: Array<{ href: string, target?: string, display: string }>
|
||||
socials?: Array<{ href: string, target?: string, icon: any }>
|
||||
}
|
||||
---
|
||||
|
||||
|
@ -1,8 +1,8 @@
|
||||
---
|
||||
import Logo from 'assets/components/layouts/Header/logo.svg'
|
||||
import Picture from 'components/global/Picture.astro'
|
||||
import Button from 'components/global/Button.astro'
|
||||
import { objectMap } from '@dzeio/object-util'
|
||||
import Logo from 'assets/components/layouts/Header/logo.svg'
|
||||
import Button from 'components/global/Button.astro'
|
||||
import Picture from 'components/global/Picture.astro'
|
||||
|
||||
export interface Props {
|
||||
right?: Record<string, string>
|
||||
|
@ -4,16 +4,19 @@ import { defineCollection, z } from 'astro:content'
|
||||
// 2. Define your collection(s)
|
||||
const projectsCollection = defineCollection({
|
||||
type: 'content',
|
||||
schema: ({ image }) => z.object({
|
||||
schema: ({ image }) =>
|
||||
z.object({
|
||||
title: z.string(),
|
||||
description: z.string().optional(),
|
||||
image: image().optional(),
|
||||
link: z.object({
|
||||
link: z
|
||||
.object({
|
||||
href: z.string(),
|
||||
rel: z.string().optional(),
|
||||
text: z.string().optional(),
|
||||
target: z.string().optional()
|
||||
}).optional(),
|
||||
})
|
||||
.optional(),
|
||||
disabled: z.string().optional(),
|
||||
created: z.date().optional(),
|
||||
updated: z.date().optional(),
|
||||
@ -21,7 +24,6 @@ const projectsCollection = defineCollection({
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
// 3. Export a single `collections` object to register your collection(s)
|
||||
// This key should match your collection directory name in "src/content"
|
||||
export const collections = {
|
||||
|
6
src/env.d.ts
vendored
6
src/env.d.ts
vendored
@ -4,14 +4,12 @@
|
||||
/**
|
||||
* Environment variables declaration
|
||||
*/
|
||||
interface ImportMetaEnv {
|
||||
}
|
||||
interface ImportMetaEnv {}
|
||||
|
||||
interface ImportMeta {
|
||||
readonly env: ImportMetaEnv;
|
||||
readonly env: ImportMetaEnv
|
||||
}
|
||||
|
||||
|
||||
declare namespace App {
|
||||
/**
|
||||
* Middlewares variables
|
||||
|
@ -1,7 +1,7 @@
|
||||
---
|
||||
import Favicon from 'components/layouts/Favicon/Favicon.astro'
|
||||
import type IconPNG from 'assets/layouts/Head/favicon.png'
|
||||
import IconSVG from 'assets/layouts/Head/favicon.svg'
|
||||
import IconPNG from 'assets/layouts/Head/favicon.png'
|
||||
import Favicon from 'components/layouts/Favicon/Favicon.astro'
|
||||
|
||||
export interface Props {
|
||||
/**
|
||||
@ -29,7 +29,7 @@ export interface Props {
|
||||
*/
|
||||
twitter?: {
|
||||
title?: string | undefined
|
||||
card?: "summary" | "summary_large_image" | "app" | "player" | undefined
|
||||
card?: 'summary' | 'summary_large_image' | 'app' | 'player' | undefined
|
||||
site?: string | undefined
|
||||
creator?: string | undefined
|
||||
} | undefined
|
||||
@ -46,9 +46,14 @@ export interface Props {
|
||||
|
||||
const props = Astro.props
|
||||
|
||||
const image = props.image ? Array.isArray(props.image) ? props.image : [props.image] : undefined
|
||||
const image = props.image ? (Array.isArray(props.image) ? props.image : [props.image]) : undefined
|
||||
|
||||
const canonical = typeof Astro.props.canonical === 'string' ? Astro.props.canonical : Astro.props.canonical === false ? undefined : Astro.url.href
|
||||
const canonical =
|
||||
typeof Astro.props.canonical === 'string'
|
||||
? Astro.props.canonical
|
||||
: Astro.props.canonical === false
|
||||
? undefined
|
||||
: Astro.url.href
|
||||
---
|
||||
|
||||
<!-- Charset -->
|
||||
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
import Footer from 'components/layouts/Footer.astro'
|
||||
import Base, { type Props as BaseProps } from './Base.astro'
|
||||
import Header from 'components/layouts/Header.astro'
|
||||
import { Mail, Phone } from 'lucide-astro'
|
||||
import { Github, Linkedin } from 'simple-icons-astro'
|
||||
import Base, { type Props as BaseProps } from './Base.astro'
|
||||
|
||||
export interface Props extends BaseProps {
|
||||
/**
|
||||
|
@ -4,9 +4,7 @@ type Fn<T extends HTMLElement> = (el: Component<T>) => void | Promise<void>
|
||||
* Component client side initialisation class
|
||||
*/
|
||||
export default class Component<T extends HTMLElement> {
|
||||
private constructor(
|
||||
public element: T
|
||||
) {}
|
||||
private constructor(public element: T) {}
|
||||
|
||||
public handled(value: boolean): this
|
||||
public handled(): boolean
|
||||
|
@ -4,7 +4,6 @@
|
||||
* Following https://developer.mozilla.org/en-US/docs/Web/HTTP/Status an extension of the RFC9110
|
||||
*/
|
||||
enum StatusCode {
|
||||
|
||||
/****************
|
||||
* 1xx Requests *
|
||||
****************/
|
||||
@ -283,7 +282,7 @@ enum StatusCode {
|
||||
/**
|
||||
* Indicates that the client needs to authenticate to gain network access.
|
||||
*/
|
||||
NETWORK_AUTHENTIFICATION_REQUIRED,
|
||||
NETWORK_AUTHENTIFICATION_REQUIRED
|
||||
}
|
||||
|
||||
export default StatusCode
|
||||
|
@ -58,9 +58,13 @@ export default interface RFC7807 {
|
||||
* @param error the error (base items are type, status, title details and instance)
|
||||
* @returns
|
||||
*/
|
||||
export function buildRFC7807(error: RFC7807 & Record<string, any>, response: ResponseBuilder = new ResponseBuilder()): Response {
|
||||
response.addHeader('Content-Type', 'application/problem+json')
|
||||
export function buildRFC7807(
|
||||
error: RFC7807 & Record<string, any>,
|
||||
response: ResponseBuilder = new ResponseBuilder()
|
||||
): Response {
|
||||
return response
|
||||
.addHeader('Content-Type', 'application/problem+json')
|
||||
.body(JSON.stringify(error))
|
||||
.status(error.status ?? 500)
|
||||
return response.build()
|
||||
.build()
|
||||
}
|
||||
|
@ -5,7 +5,6 @@ import StatusCode from './HTTP/StatusCode'
|
||||
* Simple builde to create a new Response object
|
||||
*/
|
||||
export default class ResponseBuilder {
|
||||
|
||||
public static redirect(location: string, statusCode: number = StatusCode.FOUND) {
|
||||
const resp = new ResponseBuilder()
|
||||
resp.addHeader('Location', location)
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { sequence } from "astro/middleware"
|
||||
import { sequence } from 'astro/middleware'
|
||||
|
||||
import logger from './logger'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { defineMiddleware } from "astro/middleware"
|
||||
import { defineMiddleware } from 'astro/middleware'
|
||||
import ResponseBuilder from 'libs/ResponseBuilder'
|
||||
|
||||
/**
|
||||
@ -7,7 +7,10 @@ import ResponseBuilder from 'libs/ResponseBuilder'
|
||||
export default defineMiddleware(async ({ request, url }, next) => {
|
||||
const now = new Date()
|
||||
// Date of request User-Agent 32 first chars request Method
|
||||
let prefix = `\x1b[2m${now.toISOString()}\x1b[22m ${request.headers.get('user-agent')?.slice(0, 32).padEnd(32)} ${request.method.padEnd(7)}`
|
||||
let prefix = `\x1b[2m${now.toISOString()}\x1b[22m ${request.headers
|
||||
.get('user-agent')
|
||||
?.slice(0, 32)
|
||||
.padEnd(32)} ${request.method.padEnd(7)}`
|
||||
|
||||
const fullURL = url.toString()
|
||||
const path = fullURL.slice(fullURL.indexOf(url.pathname, fullURL.indexOf(url.host)))
|
||||
@ -26,14 +29,22 @@ export default defineMiddleware(async ({ request, url }, next) => {
|
||||
|
||||
if (import.meta.env.PROD) {
|
||||
// HTTP Status time to execute path of request
|
||||
console.log(`${prefix} \x1b[34m[${res.status}]\x1b[0m \x1b[2m${(new Date().getTime() - now.getTime()).toFixed(0).padStart(5, ' ')}ms\x1b[22m ${path}`)
|
||||
console.log(
|
||||
`${prefix} \x1b[34m[${res.status}]\x1b[0m \x1b[2m${(new Date().getTime() - now.getTime())
|
||||
.toFixed(0)
|
||||
.padStart(5, ' ')}ms\x1b[22m ${path}`
|
||||
)
|
||||
}
|
||||
|
||||
return res
|
||||
} catch (e) {
|
||||
if (import.meta.env.PROD) {
|
||||
// time to execute path of request
|
||||
console.log(`${prefix} \x1b[34m[500]\x1b[0m \x1b[2m${(new Date().getTime() - now.getTime()).toFixed(0).padStart(5, ' ')}ms\x1b[22m ${path}`)
|
||||
console.log(
|
||||
`${prefix} \x1b[34m[500]\x1b[0m \x1b[2m${(new Date().getTime() - now.getTime())
|
||||
.toFixed(0)
|
||||
.padStart(5, ' ')}ms\x1b[22m ${path}`
|
||||
)
|
||||
}
|
||||
|
||||
// add a full line dash to not miss it
|
||||
|
@ -4,7 +4,6 @@
|
||||
* you MUST call it through the `DaoFactory` file
|
||||
*/
|
||||
export default abstract class Dao<Object extends { id: any } = { id: any }> {
|
||||
|
||||
/**
|
||||
* insert a new object into the source
|
||||
*
|
||||
@ -19,7 +18,8 @@ export default abstract class Dao<Object extends { id: any } = { id: any }> {
|
||||
* @param obj the object to create
|
||||
* @returns the object with it's id filled if create or null otherwise
|
||||
*/
|
||||
public insert: Dao<Object>['create'] = (obj: Parameters<Dao<Object>['create']>[0]) => this.create(obj)
|
||||
public insert: Dao<Object>['create'] = (obj: Parameters<Dao<Object>['create']>[0]) =>
|
||||
this.create(obj)
|
||||
|
||||
/**
|
||||
* find the list of objects having elements from the query
|
||||
@ -35,7 +35,8 @@ export default abstract class Dao<Object extends { id: any } = { id: any }> {
|
||||
* @param query a partial object which filter depending on the elements, if not set it will fetch everything
|
||||
* @returns an array containing the list of elements that match with the query
|
||||
*/
|
||||
public find: Dao<Object>['findAll'] = (query: Parameters<Dao<Object>['findAll']>[0]) => this.findAll(query)
|
||||
public find: Dao<Object>['findAll'] = (query: Parameters<Dao<Object>['findAll']>[0]) =>
|
||||
this.findAll(query)
|
||||
|
||||
/**
|
||||
* find an object by it's id
|
||||
@ -46,7 +47,7 @@ export default abstract class Dao<Object extends { id: any } = { id: any }> {
|
||||
* @returns
|
||||
*/
|
||||
public findById(id: Object['id']): Promise<Object | null> {
|
||||
return this.findOne({id: id} as Partial<Object>)
|
||||
return this.findOne({ id: id } as Partial<Object>)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -91,14 +92,16 @@ export default abstract class Dao<Object extends { id: any } = { id: any }> {
|
||||
if (!query) {
|
||||
return null
|
||||
}
|
||||
return await this.update({...query, ...changes})
|
||||
return await this.update({ ...query, ...changes })
|
||||
}
|
||||
/**
|
||||
* update the remote reference of the object or create it if not found
|
||||
* @param obj the object to update/insert
|
||||
* @returns the object is updated/inserted or null otherwise
|
||||
*/
|
||||
public async upsert(object: Object | Omit<Object, 'id' | 'created' | 'updated'>): Promise<Object | null> {
|
||||
public async upsert(
|
||||
object: Object | Omit<Object, 'id' | 'created' | 'updated'>
|
||||
): Promise<Object | null> {
|
||||
if ('id' in object) {
|
||||
return this.update(object)
|
||||
}
|
||||
|
@ -9,8 +9,7 @@
|
||||
*
|
||||
* Touch this interface to define which key is linked to which Dao
|
||||
*/
|
||||
interface DaoItem {
|
||||
}
|
||||
interface DaoItem {}
|
||||
|
||||
/**
|
||||
* Class to get any DAO
|
||||
@ -48,7 +47,8 @@ export default class DaoFactory {
|
||||
*/
|
||||
private static initDao(item: keyof DaoItem): any | undefined {
|
||||
switch (item) {
|
||||
default: return undefined
|
||||
default:
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,9 @@
|
||||
---
|
||||
import MainLayout from 'layouts/MainLayout.astro'
|
||||
import I404 from 'assets/pages/404/404.svg'
|
||||
import I404Light from 'assets/pages/404/404.light.svg'
|
||||
import I404 from 'assets/pages/404/404.svg'
|
||||
import Button from 'components/global/Button.astro'
|
||||
import Picture from 'components/global/Picture.astro'
|
||||
import MainLayout from 'layouts/MainLayout.astro'
|
||||
---
|
||||
|
||||
<MainLayout>
|
||||
|
@ -7,7 +7,7 @@ module.exports = {
|
||||
theme: {
|
||||
fontFamily: {
|
||||
// add your default font below
|
||||
'sans': ['Font Name', ...defaultTheme.fontFamily.sans]
|
||||
sans: ['Font Name', ...defaultTheme.fontFamily.sans]
|
||||
},
|
||||
extend: {
|
||||
colors: {
|
||||
@ -21,7 +21,7 @@ module.exports = {
|
||||
// add a default padding to the container
|
||||
DEFAULT: '1rem'
|
||||
}
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ import { expect, test } from 'vitest'
|
||||
// Edit an assertion and save to see HMR in action
|
||||
|
||||
test('Math.sqrt()', () => {
|
||||
expect(Math.sqrt(4)).toBe(2);
|
||||
expect(Math.sqrt(144)).toBe(12);
|
||||
expect(Math.sqrt(2)).toBe(Math.SQRT2);
|
||||
});
|
||||
expect(Math.sqrt(4)).toBe(2)
|
||||
expect(Math.sqrt(144)).toBe(12)
|
||||
expect(Math.sqrt(2)).toBe(Math.SQRT2)
|
||||
})
|
||||
|
@ -4,10 +4,8 @@ import { getViteConfig } from 'astro/config'
|
||||
|
||||
export default getViteConfig({
|
||||
test: {
|
||||
include: [
|
||||
'./tests/**.ts'
|
||||
]
|
||||
include: ['./tests/**.ts']
|
||||
/* for example, use global to avoid globals imports (describe, test, expect): */
|
||||
// globals: true,
|
||||
},
|
||||
});
|
||||
}
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user