Fix ESLINT 9 configuration
This commit is contained in:
parent
6e72c02769
commit
e45c1eb8d9
@ -1,38 +0,0 @@
|
|||||||
{
|
|
||||||
"extends": "next/core-web-vitals",
|
|
||||||
"plugins": ["@typescript-eslint"],
|
|
||||||
"rules": {
|
|
||||||
"@next/next/no-img-element": "off",
|
|
||||||
"@typescript-eslint/no-unused-expressions": ["warn"],
|
|
||||||
"@typescript-eslint/no-unused-vars": [
|
|
||||||
"warn", {
|
|
||||||
"argsIgnorePattern": "^_",
|
|
||||||
"varsIgnorePattern": "^_"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"comma-dangle": [
|
|
||||||
"warn",
|
|
||||||
"always-multiline"
|
|
||||||
],
|
|
||||||
"indent": [
|
|
||||||
"warn",
|
|
||||||
2
|
|
||||||
],
|
|
||||||
"linebreak-style": [
|
|
||||||
"warn",
|
|
||||||
"unix"
|
|
||||||
],
|
|
||||||
"quotes": [
|
|
||||||
"warn",
|
|
||||||
"single"
|
|
||||||
],
|
|
||||||
"semi": [
|
|
||||||
"warn",
|
|
||||||
"always"
|
|
||||||
],
|
|
||||||
"max-len": [
|
|
||||||
"warn",
|
|
||||||
{ "code": 80 }
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
51
eslint.config.mjs
Normal file
51
eslint.config.mjs
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
import { dirname } from 'path';
|
||||||
|
import { fileURLToPath } from 'url';
|
||||||
|
import { FlatCompat } from '@eslint/eslintrc';
|
||||||
|
|
||||||
|
const __filename = fileURLToPath(import.meta.url);
|
||||||
|
const __dirname = dirname(__filename);
|
||||||
|
|
||||||
|
const compat = new FlatCompat({
|
||||||
|
baseDirectory: __dirname,
|
||||||
|
});
|
||||||
|
|
||||||
|
const eslintConfig = [
|
||||||
|
...compat.extends('next/core-web-vitals', 'next/typescript'), {
|
||||||
|
rules: {
|
||||||
|
'@next/next/no-img-element': 'off',
|
||||||
|
'@typescript-eslint/no-explicit-any': 'off',
|
||||||
|
'no-unused-expressions': 'warn',
|
||||||
|
'@typescript-eslint/no-unused-vars': [
|
||||||
|
'warn', {
|
||||||
|
'argsIgnorePattern': '^_',
|
||||||
|
'varsIgnorePattern': '^_',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
'comma-dangle': [
|
||||||
|
'warn',
|
||||||
|
'always-multiline',
|
||||||
|
],
|
||||||
|
'indent': [
|
||||||
|
'warn',
|
||||||
|
2,
|
||||||
|
],
|
||||||
|
'linebreak-style': [
|
||||||
|
'warn',
|
||||||
|
'unix',
|
||||||
|
],
|
||||||
|
'quotes': [
|
||||||
|
'warn',
|
||||||
|
'single',
|
||||||
|
],
|
||||||
|
'semi': [
|
||||||
|
'warn',
|
||||||
|
'always',
|
||||||
|
],
|
||||||
|
'max-len': [
|
||||||
|
'warn',
|
||||||
|
{ 'code': 80 },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
}];
|
||||||
|
|
||||||
|
export default eslintConfig;
|
||||||
@ -26,8 +26,6 @@
|
|||||||
"@types/react": "19.0.2",
|
"@types/react": "19.0.2",
|
||||||
"@types/react-dom": "19.0.2",
|
"@types/react-dom": "19.0.2",
|
||||||
"@types/sanitize-html": "^2.13.0",
|
"@types/sanitize-html": "^2.13.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^8.19.0",
|
|
||||||
"@typescript-eslint/parser": "^8.19.0",
|
|
||||||
"@upstash/ratelimit": "^2.0.5",
|
"@upstash/ratelimit": "^2.0.5",
|
||||||
"@vercel/analytics": "^1.4.1",
|
"@vercel/analytics": "^1.4.1",
|
||||||
"@vercel/blob": "^0.27.0",
|
"@vercel/blob": "^0.27.0",
|
||||||
|
|||||||
6
pnpm-lock.yaml
generated
6
pnpm-lock.yaml
generated
@ -59,12 +59,6 @@ importers:
|
|||||||
'@types/sanitize-html':
|
'@types/sanitize-html':
|
||||||
specifier: ^2.13.0
|
specifier: ^2.13.0
|
||||||
version: 2.13.0
|
version: 2.13.0
|
||||||
'@typescript-eslint/eslint-plugin':
|
|
||||||
specifier: ^8.19.0
|
|
||||||
version: 8.19.0(@typescript-eslint/parser@8.19.0(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2))(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2)
|
|
||||||
'@typescript-eslint/parser':
|
|
||||||
specifier: ^8.19.0
|
|
||||||
version: 8.19.0(eslint@9.17.0(jiti@1.21.7))(typescript@5.7.2)
|
|
||||||
'@upstash/ratelimit':
|
'@upstash/ratelimit':
|
||||||
specifier: ^2.0.5
|
specifier: ^2.0.5
|
||||||
version: 2.0.5(@upstash/redis@1.34.3)
|
version: 2.0.5(@upstash/redis@1.34.3)
|
||||||
|
|||||||
@ -58,7 +58,7 @@ export default function AdminAddAllUploads({
|
|||||||
for await (const data of readStreamableValue(stream)) {
|
for await (const data of readStreamableValue(stream)) {
|
||||||
setButtonText(addedUploadCount.current === 0
|
setButtonText(addedUploadCount.current === 0
|
||||||
? `Adding 1 of ${storageUrls.length}`
|
? `Adding 1 of ${storageUrls.length}`
|
||||||
: `Adding ${addedUploadCount.current + 1} of ${storageUrls.length}`
|
: `Adding ${addedUploadCount.current + 1} of ${storageUrls.length}`,
|
||||||
);
|
);
|
||||||
setUrlAddStatuses(current => {
|
setUrlAddStatuses(current => {
|
||||||
const update = current.map(status =>
|
const update = current.map(status =>
|
||||||
@ -70,7 +70,7 @@ export default function AdminAddAllUploads({
|
|||||||
statusMessage: data.statusMessage,
|
statusMessage: data.statusMessage,
|
||||||
progress: data.progress,
|
progress: data.progress,
|
||||||
}
|
}
|
||||||
: status
|
: status,
|
||||||
);
|
);
|
||||||
addedUploadCount.current = update
|
addedUploadCount.current = update
|
||||||
.filter(({ status }) => status === 'added')
|
.filter(({ status }) => status === 'added')
|
||||||
|
|||||||
@ -48,7 +48,7 @@ export default function AdminOutdatedClient({
|
|||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
if (window.confirm(
|
if (window.confirm(
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
`Are you sure you want to sync the oldest ${updateBatchSize} photos? This action cannot be undone.`
|
`Are you sure you want to sync the oldest ${updateBatchSize} photos? This action cannot be undone.`,
|
||||||
)) {
|
)) {
|
||||||
const photosToSync = photos
|
const photosToSync = photos
|
||||||
.slice(0, updateBatchSize)
|
.slice(0, updateBatchSize)
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { BiTrash } from 'react-icons/bi';
|
|||||||
export default function DeleteFormButton (
|
export default function DeleteFormButton (
|
||||||
props: ComponentProps<typeof SubmitButtonWithStatus> & {
|
props: ComponentProps<typeof SubmitButtonWithStatus> & {
|
||||||
clearLocalState?: boolean
|
clearLocalState?: boolean
|
||||||
}
|
},
|
||||||
) {
|
) {
|
||||||
const {
|
const {
|
||||||
onFormSubmit: onFormSubmitProps,
|
onFormSubmit: onFormSubmitProps,
|
||||||
|
|||||||
@ -9,7 +9,7 @@ import { CONFIG_CHECKLIST_STATUS } from '@/site/config';
|
|||||||
|
|
||||||
const scanForError = (
|
const scanForError = (
|
||||||
shouldCheck: boolean,
|
shouldCheck: boolean,
|
||||||
promise: () => Promise<any>
|
promise: () => Promise<any>,
|
||||||
): Promise<string> =>
|
): Promise<string> =>
|
||||||
shouldCheck
|
shouldCheck
|
||||||
? promise()
|
? promise()
|
||||||
|
|||||||
@ -184,7 +184,7 @@ export default function ComponentsPage() {
|
|||||||
{DEBUG_LINES.map((_, i) =>
|
{DEBUG_LINES.map((_, i) =>
|
||||||
<div key={i}>
|
<div key={i}>
|
||||||
Line {(i + 1).toString().padStart(2, '0')}
|
Line {(i + 1).toString().padStart(2, '0')}
|
||||||
</div>
|
</div>,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</DivDebugBaselineGrid>
|
</DivDebugBaselineGrid>
|
||||||
|
|||||||
@ -28,13 +28,13 @@ export default async function PhotoEditPage({
|
|||||||
// Only generate image thumbnails when AI generation is enabled
|
// Only generate image thumbnails when AI generation is enabled
|
||||||
const imageThumbnailBase64 = AI_TEXT_GENERATION_ENABLED
|
const imageThumbnailBase64 = AI_TEXT_GENERATION_ENABLED
|
||||||
? await resizeImageFromUrl(
|
? await resizeImageFromUrl(
|
||||||
getNextImageUrlForManipulation(photo.url, IS_PREVIEW)
|
getNextImageUrlForManipulation(photo.url, IS_PREVIEW),
|
||||||
)
|
)
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
const blurData = BLUR_ENABLED
|
const blurData = BLUR_ENABLED
|
||||||
? await blurImageFromUrl(
|
? await blurImageFromUrl(
|
||||||
getNextImageUrlForManipulation(photo.url, IS_PREVIEW)
|
getNextImageUrlForManipulation(photo.url, IS_PREVIEW),
|
||||||
)
|
)
|
||||||
: '';
|
: '';
|
||||||
|
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export async function GET(
|
|||||||
CURRENT_STORAGE === 'cloudflare-r2'
|
CURRENT_STORAGE === 'cloudflare-r2'
|
||||||
? cloudflareR2PutObjectCommandForKey(key)
|
? cloudflareR2PutObjectCommandForKey(key)
|
||||||
: awsS3PutObjectCommandForKey(key),
|
: awsS3PutObjectCommandForKey(key),
|
||||||
{ expiresIn: 3600 }
|
{ expiresIn: 3600 },
|
||||||
);
|
);
|
||||||
return new Response(
|
return new Response(
|
||||||
url,
|
url,
|
||||||
|
|||||||
@ -58,7 +58,7 @@ export const cameraFromPhoto = (
|
|||||||
export const formatCameraText = (
|
export const formatCameraText = (
|
||||||
{ make: makeRaw, model: modelRaw }: Camera,
|
{ make: makeRaw, model: modelRaw }: Camera,
|
||||||
includeMake: 'always' | 'never' | 'if-not-apple' = 'if-not-apple',
|
includeMake: 'always' | 'never' | 'if-not-apple' = 'if-not-apple',
|
||||||
removeIPhoneOnLongModels?: boolean
|
removeIPhoneOnLongModels?: boolean,
|
||||||
) => {
|
) => {
|
||||||
// Remove 'Corporation' from makes like 'Nikon Corporation'
|
// Remove 'Corporation' from makes like 'Nikon Corporation'
|
||||||
const make = makeRaw.replace(/ Corporation/i, '');
|
const make = makeRaw.replace(/ Corporation/i, '');
|
||||||
|
|||||||
@ -70,7 +70,7 @@ export default function FieldSetWithStatus({
|
|||||||
</span>}
|
</span>}
|
||||||
{isModified && !error &&
|
{isModified && !error &&
|
||||||
<span className={clsx(
|
<span className={clsx(
|
||||||
'text-main font-medium text-[0.9rem] -ml-1.5 translate-y-[-1px]'
|
'text-main font-medium text-[0.9rem] -ml-1.5 translate-y-[-1px]',
|
||||||
)}>
|
)}>
|
||||||
*
|
*
|
||||||
</span>}
|
</span>}
|
||||||
|
|||||||
@ -104,7 +104,7 @@ export default function ImageInput({
|
|||||||
|
|
||||||
// Specify wide gamut to avoid data loss while resizing
|
// Specify wide gamut to avoid data loss while resizing
|
||||||
const ctx = canvas?.getContext(
|
const ctx = canvas?.getContext(
|
||||||
'2d', { colorSpace: 'display-p3' }
|
'2d', { colorSpace: 'display-p3' },
|
||||||
);
|
);
|
||||||
|
|
||||||
if ((shouldResize || isPng) && canvas && ctx) {
|
if ((shouldResize || isPng) && canvas && ctx) {
|
||||||
|
|||||||
@ -47,7 +47,7 @@ import { formatCount, formatCountDescriptive } from '@/utility/string';
|
|||||||
import CommandKItem from './CommandKItem';
|
import CommandKItem from './CommandKItem';
|
||||||
import { GRID_HOMEPAGE_ENABLED } from '@/site/config';
|
import { GRID_HOMEPAGE_ENABLED } from '@/site/config';
|
||||||
import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog';
|
import { DialogDescription, DialogTitle } from '@radix-ui/react-dialog';
|
||||||
import * as VisuallyHidden from "@radix-ui/react-visually-hidden";
|
import * as VisuallyHidden from '@radix-ui/react-visually-hidden';
|
||||||
|
|
||||||
const DIALOG_TITLE = 'Global Command-K Menu';
|
const DIALOG_TITLE = 'Global Command-K Menu';
|
||||||
const DIALOG_DESCRIPTION = 'For searching photos, views, and settings';
|
const DIALOG_DESCRIPTION = 'For searching photos, views, and settings';
|
||||||
|
|||||||
@ -46,7 +46,7 @@ export default function MoreMenu({
|
|||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
{items.map(props =>
|
{items.map(props =>
|
||||||
<MoreMenuItem key={`${props.label}`} {...props} />
|
<MoreMenuItem key={`${props.label}`} {...props} />,
|
||||||
)}
|
)}
|
||||||
</DropdownMenu.Content>
|
</DropdownMenu.Content>
|
||||||
</DropdownMenu.Portal>
|
</DropdownMenu.Portal>
|
||||||
|
|||||||
@ -44,7 +44,7 @@ export default function LabeledIcon({
|
|||||||
{children && type !== 'icon-only' &&
|
{children && type !== 'icon-only' &&
|
||||||
<span className={clsx(
|
<span className={clsx(
|
||||||
'uppercase',
|
'uppercase',
|
||||||
debug && 'bg-gray-700'
|
debug && 'bg-gray-700',
|
||||||
)}>
|
)}>
|
||||||
{children}
|
{children}
|
||||||
</span>}
|
</span>}
|
||||||
|
|||||||
@ -80,7 +80,7 @@ export default function ImagePhotoGrid({
|
|||||||
objectFit: 'cover',
|
objectFit: 'cover',
|
||||||
},
|
},
|
||||||
}} />
|
}} />
|
||||||
</div>
|
</div>,
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -27,7 +27,7 @@ export default function PhotoGridPage({
|
|||||||
|
|
||||||
useEffect(
|
useEffect(
|
||||||
() => () => setSelectedPhotoIds?.(undefined),
|
() => () => setSelectedPhotoIds?.(undefined),
|
||||||
[setSelectedPhotoIds]
|
[setSelectedPhotoIds],
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -176,7 +176,7 @@ export const addAllUploadsAction = async ({
|
|||||||
})();
|
})();
|
||||||
|
|
||||||
if (shouldRevalidateAllKeysAndPaths) {
|
if (shouldRevalidateAllKeysAndPaths) {
|
||||||
after(revalidateAllKeysAndPaths)
|
after(revalidateAllKeysAndPaths);
|
||||||
}
|
}
|
||||||
|
|
||||||
return stream.value;
|
return stream.value;
|
||||||
@ -355,7 +355,7 @@ export const syncPhotoAction = async (photoId: string) =>
|
|||||||
semanticDescription: aiSemanticDescription,
|
semanticDescription: aiSemanticDescription,
|
||||||
} = await generateAiImageQueries(
|
} = await generateAiImageQueries(
|
||||||
imageResizedBase64,
|
imageResizedBase64,
|
||||||
AI_TEXT_AUTO_GENERATED_FIELDS
|
AI_TEXT_AUTO_GENERATED_FIELDS,
|
||||||
);
|
);
|
||||||
|
|
||||||
const photoFormDbInsert = convertFormDataToPhotoDbInsert({
|
const photoFormDbInsert = convertFormDataToPhotoDbInsert({
|
||||||
|
|||||||
@ -81,7 +81,7 @@ const getPhotosCacheKeys = (options: GetPhotosOptions = {}) => {
|
|||||||
Object.keys(options).forEach(key => {
|
Object.keys(options).forEach(key => {
|
||||||
const tag = getPhotosCacheKeyForOption(
|
const tag = getPhotosCacheKeyForOption(
|
||||||
options,
|
options,
|
||||||
key as keyof GetPhotosOptions
|
key as keyof GetPhotosOptions,
|
||||||
);
|
);
|
||||||
if (tag) { tags.push(tag); }
|
if (tag) { tags.push(tag); }
|
||||||
});
|
});
|
||||||
@ -181,7 +181,7 @@ export const getPhotosMostRecentUpdateCached =
|
|||||||
export const getPhotoCached = (...args: Parameters<typeof getPhoto>) =>
|
export const getPhotoCached = (...args: Parameters<typeof getPhoto>) =>
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
getPhoto,
|
getPhoto,
|
||||||
[KEY_PHOTOS, KEY_PHOTO]
|
[KEY_PHOTOS, KEY_PHOTO],
|
||||||
)(...args).then(photo => photo ? parseCachedPhotoDates(photo) : undefined);
|
)(...args).then(photo => photo ? parseCachedPhotoDates(photo) : undefined);
|
||||||
|
|
||||||
export const getUniqueTagsCached =
|
export const getUniqueTagsCached =
|
||||||
@ -193,19 +193,19 @@ export const getUniqueTagsCached =
|
|||||||
export const getUniqueTagsHiddenCached =
|
export const getUniqueTagsHiddenCached =
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
getUniqueTagsHidden,
|
getUniqueTagsHidden,
|
||||||
[KEY_PHOTOS, KEY_TAGS, KEY_HIDDEN]
|
[KEY_PHOTOS, KEY_TAGS, KEY_HIDDEN],
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getUniqueCamerasCached =
|
export const getUniqueCamerasCached =
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
getUniqueCameras,
|
getUniqueCameras,
|
||||||
[KEY_PHOTOS, KEY_CAMERAS]
|
[KEY_PHOTOS, KEY_CAMERAS],
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getUniqueLensesCached =
|
export const getUniqueLensesCached =
|
||||||
unstable_cache(
|
unstable_cache(
|
||||||
getUniqueLenses,
|
getUniqueLenses,
|
||||||
[KEY_PHOTOS, KEY_LENSES]
|
[KEY_PHOTOS, KEY_LENSES],
|
||||||
);
|
);
|
||||||
|
|
||||||
export const getUniqueFilmSimulationsCached =
|
export const getUniqueFilmSimulationsCached =
|
||||||
|
|||||||
@ -21,7 +21,7 @@ export const areOptionsSensitive = (options: GetPhotosOptions) =>
|
|||||||
|
|
||||||
export const getWheresFromOptions = (
|
export const getWheresFromOptions = (
|
||||||
options: GetPhotosOptions,
|
options: GetPhotosOptions,
|
||||||
initialValuesIndex = 1
|
initialValuesIndex = 1,
|
||||||
) => {
|
) => {
|
||||||
const {
|
const {
|
||||||
hidden = 'exclude',
|
hidden = 'exclude',
|
||||||
|
|||||||
@ -80,7 +80,7 @@ const runMigration02 = () =>
|
|||||||
// Wrapper for most queries for JIT table creation/migration running
|
// Wrapper for most queries for JIT table creation/migration running
|
||||||
const safelyQueryPhotos = async <T>(
|
const safelyQueryPhotos = async <T>(
|
||||||
callback: () => Promise<T>,
|
callback: () => Promise<T>,
|
||||||
debugMessage: string
|
debugMessage: string,
|
||||||
): Promise<T> => {
|
): Promise<T> => {
|
||||||
let result: T;
|
let result: T;
|
||||||
|
|
||||||
@ -370,8 +370,6 @@ export const getPhotos = async (options: GetPhotosOptions = {}) =>
|
|||||||
lastValuesIndex,
|
lastValuesIndex,
|
||||||
} = getWheresFromOptions(options);
|
} = getWheresFromOptions(options);
|
||||||
|
|
||||||
let valuesIndex = lastValuesIndex;
|
|
||||||
|
|
||||||
if (wheres) {
|
if (wheres) {
|
||||||
sql.push(wheres);
|
sql.push(wheres);
|
||||||
values.push(...wheresValues);
|
values.push(...wheresValues);
|
||||||
@ -382,7 +380,7 @@ export const getPhotos = async (options: GetPhotosOptions = {}) =>
|
|||||||
const {
|
const {
|
||||||
limitAndOffset,
|
limitAndOffset,
|
||||||
limitAndOffsetValues,
|
limitAndOffsetValues,
|
||||||
} = getLimitAndOffsetFromOptions(options, valuesIndex);
|
} = getLimitAndOffsetFromOptions(options, lastValuesIndex);
|
||||||
|
|
||||||
// LIMIT + OFFSET
|
// LIMIT + OFFSET
|
||||||
sql.push(limitAndOffset);
|
sql.push(limitAndOffset);
|
||||||
@ -421,7 +419,7 @@ export const getPhotosNearId = async (
|
|||||||
WHERE twi.row_number >= current.row_number - 1
|
WHERE twi.row_number >= current.row_number - 1
|
||||||
LIMIT $${valuesIndex++}
|
LIMIT $${valuesIndex++}
|
||||||
`,
|
`,
|
||||||
[...wheresValues, photoId, limit]
|
[...wheresValues, photoId, limit],
|
||||||
)
|
)
|
||||||
.then(({ rows }) => {
|
.then(({ rows }) => {
|
||||||
const photo = rows.find(({ id }) => id === photoId);
|
const photo = rows.find(({ id }) => id === photoId);
|
||||||
|
|||||||
@ -133,7 +133,7 @@ export const convertFormKeysToLabels = (keys: (keyof PhotoFormData)[]) =>
|
|||||||
keys.map(key => FORM_METADATA()[key].label.toUpperCase());
|
keys.map(key => FORM_METADATA()[key].label.toUpperCase());
|
||||||
|
|
||||||
export const getFormErrors = (
|
export const getFormErrors = (
|
||||||
formData: Partial<PhotoFormData>
|
formData: Partial<PhotoFormData>,
|
||||||
): Partial<Record<keyof PhotoFormData, string>> =>
|
): Partial<Record<keyof PhotoFormData, string>> =>
|
||||||
Object.keys(formData).reduce((acc, key) => ({
|
Object.keys(formData).reduce((acc, key) => ({
|
||||||
...acc,
|
...acc,
|
||||||
@ -147,7 +147,7 @@ export const isFormValid = (formData: Partial<PhotoFormData>) =>
|
|||||||
(!required || Boolean(formData[key])) &&
|
(!required || Boolean(formData[key])) &&
|
||||||
(!validate?.(formData[key])) &&
|
(!validate?.(formData[key])) &&
|
||||||
// eslint-disable-next-line max-len
|
// eslint-disable-next-line max-len
|
||||||
(!validateStringMaxLength || (formData[key]?.length ?? 0) <= validateStringMaxLength)
|
(!validateStringMaxLength || (formData[key]?.length ?? 0) <= validateStringMaxLength),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const formHasTextContent = ({
|
export const formHasTextContent = ({
|
||||||
@ -302,12 +302,12 @@ export const getChangedFormFields = (
|
|||||||
.keys(current)
|
.keys(current)
|
||||||
.filter(key =>
|
.filter(key =>
|
||||||
(original[key as keyof PhotoFormData] ?? '') !==
|
(original[key as keyof PhotoFormData] ?? '') !==
|
||||||
(current[key as keyof PhotoFormData] ?? '')
|
(current[key as keyof PhotoFormData] ?? ''),
|
||||||
) as (keyof PhotoFormData)[];
|
) as (keyof PhotoFormData)[];
|
||||||
};
|
};
|
||||||
|
|
||||||
export const generateTakenAtFields = (
|
export const generateTakenAtFields = (
|
||||||
form?: Partial<PhotoFormData>
|
form?: Partial<PhotoFormData>,
|
||||||
): { takenAt: string, takenAtNaive: string } => ({
|
): { takenAt: string, takenAtNaive: string } => ({
|
||||||
takenAt: form?.takenAt || generateLocalPostgresString(),
|
takenAt: form?.takenAt || generateLocalPostgresString(),
|
||||||
takenAtNaive: form?.takenAtNaive || generateLocalNaivePostgresString(),
|
takenAtNaive: form?.takenAtNaive || generateLocalNaivePostgresString(),
|
||||||
|
|||||||
@ -112,7 +112,7 @@ export interface PhotoSetAttributes {
|
|||||||
|
|
||||||
export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
|
export const parsePhotoFromDb = (photoDbRaw: PhotoDb): Photo => {
|
||||||
const photoDb = camelcaseKeys(
|
const photoDb = camelcaseKeys(
|
||||||
photoDbRaw as unknown as Record<string, unknown>
|
photoDbRaw as unknown as Record<string, unknown>,
|
||||||
) as unknown as PhotoDb;
|
) as unknown as PhotoDb;
|
||||||
return {
|
return {
|
||||||
...photoDb,
|
...photoDb,
|
||||||
@ -193,7 +193,7 @@ export const generateOgImageMetaForPhotos = (photos: Photo[]): Metadata => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const PHOTO_ID_FORWARDING_TABLE: Record<string, string> = JSON.parse(
|
const PHOTO_ID_FORWARDING_TABLE: Record<string, string> = JSON.parse(
|
||||||
process.env.PHOTO_ID_FORWARDING_TABLE || '{}'
|
process.env.PHOTO_ID_FORWARDING_TABLE || '{}',
|
||||||
);
|
);
|
||||||
|
|
||||||
export const translatePhotoId = (id: string) =>
|
export const translatePhotoId = (id: string) =>
|
||||||
@ -251,7 +251,7 @@ export const descriptionForPhotoSet = (
|
|||||||
|
|
||||||
const sortPhotosByDate = (
|
const sortPhotosByDate = (
|
||||||
photos: Photo[],
|
photos: Photo[],
|
||||||
order: 'ASC' | 'DESC' = 'DESC'
|
order: 'ASC' | 'DESC' = 'DESC',
|
||||||
) =>
|
) =>
|
||||||
[...photos].sort((a, b) => order === 'DESC'
|
[...photos].sort((a, b) => order === 'DESC'
|
||||||
? b.takenAt.getTime() - a.takenAt.getTime()
|
? b.takenAt.getTime() - a.takenAt.getTime()
|
||||||
|
|||||||
@ -117,14 +117,14 @@ const generateBase64 = async (
|
|||||||
|
|
||||||
const resizeImage = async (image: ArrayBuffer) =>
|
const resizeImage = async (image: ArrayBuffer) =>
|
||||||
generateBase64(image, sharp => sharp
|
generateBase64(image, sharp => sharp
|
||||||
.resize(IMAGE_WIDTH_RESIZE)
|
.resize(IMAGE_WIDTH_RESIZE),
|
||||||
);
|
);
|
||||||
|
|
||||||
const blurImage = async (image: ArrayBuffer) =>
|
const blurImage = async (image: ArrayBuffer) =>
|
||||||
generateBase64(image, sharp => sharp
|
generateBase64(image, sharp => sharp
|
||||||
.resize(IMAGE_WIDTH_BLUR)
|
.resize(IMAGE_WIDTH_BLUR)
|
||||||
.modulate({ saturation: 1.15 })
|
.modulate({ saturation: 1.15 })
|
||||||
.blur(4)
|
.blur(4),
|
||||||
);
|
);
|
||||||
|
|
||||||
export const resizeImageFromUrl = async (url: string) =>
|
export const resizeImageFromUrl = async (url: string) =>
|
||||||
|
|||||||
@ -25,7 +25,7 @@ export const convertUploadToPhoto = async ({
|
|||||||
if (shouldStripGpsData) {
|
if (shouldStripGpsData) {
|
||||||
const fileWithoutGps = await removeGpsData(
|
const fileWithoutGps = await removeGpsData(
|
||||||
fileBytes ?? await fetch(urlOrigin, { cache: 'no-store' })
|
fileBytes ?? await fetch(urlOrigin, { cache: 'no-store' })
|
||||||
.then(res => res.arrayBuffer())
|
.then(res => res.arrayBuffer()),
|
||||||
);
|
);
|
||||||
return putFile(fileWithoutGps, photoPath).then(async url => {
|
return putFile(fileWithoutGps, photoPath).then(async url => {
|
||||||
if (url && shouldDeleteOrigin) { await deleteFile(urlOrigin); }
|
if (url && shouldDeleteOrigin) { await deleteFile(urlOrigin); }
|
||||||
|
|||||||
@ -1,5 +1,3 @@
|
|||||||
/* eslint-disable max-len */
|
|
||||||
|
|
||||||
const INTRINSIC_WIDTH = 28;
|
const INTRINSIC_WIDTH = 28;
|
||||||
const INTRINSIC_HEIGHT = 24;
|
const INTRINSIC_HEIGHT = 24;
|
||||||
|
|
||||||
|
|||||||
@ -262,7 +262,7 @@ export default function SiteChecklistClient({
|
|||||||
)}
|
)}
|
||||||
{' '}
|
{' '}
|
||||||
and connect to project
|
and connect to project
|
||||||
</>
|
</>,
|
||||||
)}
|
)}
|
||||||
{hasCloudflareR2Storage
|
{hasCloudflareR2Storage
|
||||||
? renderSubStatus('checked', 'Cloudflare R2: connected')
|
? renderSubStatus('checked', 'Cloudflare R2: connected')
|
||||||
|
|||||||
@ -14,7 +14,7 @@ const getFontData = async () => {
|
|||||||
} else {
|
} else {
|
||||||
data = await fetch(new URL(
|
data = await fetch(new URL(
|
||||||
'/public/fonts/IBMPlexMono-Medium.ttf',
|
'/public/fonts/IBMPlexMono-Medium.ttf',
|
||||||
import.meta.url
|
import.meta.url,
|
||||||
)).then(res => res.arrayBuffer());
|
)).then(res => res.arrayBuffer());
|
||||||
}
|
}
|
||||||
return data;
|
return data;
|
||||||
|
|||||||
@ -7,7 +7,7 @@ export const getOffsetFromExif = (data: ExifData) =>
|
|||||||
Object.values(data.tags as any)
|
Object.values(data.tags as any)
|
||||||
.find((value: any) =>
|
.find((value: any) =>
|
||||||
typeof value === 'string' &&
|
typeof value === 'string' &&
|
||||||
OFFSET_REGEX.test(value)
|
OFFSET_REGEX.test(value),
|
||||||
) as string | undefined;
|
) as string | undefined;
|
||||||
|
|
||||||
export const getAspectRatioFromExif = (data: ExifData): number => {
|
export const getAspectRatioFromExif = (data: ExifData): number => {
|
||||||
@ -32,7 +32,7 @@ export const getAspectRatioFromExif = (data: ExifData): number => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const convertApertureValueToFNumber = (
|
export const convertApertureValueToFNumber = (
|
||||||
apertureValue?: string
|
apertureValue?: string,
|
||||||
): string | undefined => {
|
): string | undefined => {
|
||||||
if (apertureValue) {
|
if (apertureValue) {
|
||||||
const aperture = parseInt(apertureValue);
|
const aperture = parseInt(apertureValue);
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import { useEffect } from 'react';
|
|||||||
|
|
||||||
export default function useOnVisible(
|
export default function useOnVisible(
|
||||||
ref: React.RefObject<HTMLElement | null>,
|
ref: React.RefObject<HTMLElement | null>,
|
||||||
onVisible?: () => void
|
onVisible?: () => void,
|
||||||
) {
|
) {
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (onVisible && ref.current) {
|
if (onVisible && ref.current) {
|
||||||
|
|||||||
@ -9,7 +9,7 @@ const safelyGetMediaQuery = () => typeof window !== 'undefined'
|
|||||||
|
|
||||||
const usePrefersReducedMotion = () => {
|
const usePrefersReducedMotion = () => {
|
||||||
const [prefersReducedMotion, setPrefersReducedMotion] = useState<boolean>(
|
const [prefersReducedMotion, setPrefersReducedMotion] = useState<boolean>(
|
||||||
safelyGetMediaQuery()?.matches ?? false
|
safelyGetMediaQuery()?.matches ?? false,
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
|||||||
2
src/vendors/fujifilm/index.ts
vendored
2
src/vendors/fujifilm/index.ts
vendored
@ -233,7 +233,7 @@ export const labelForFilmSimulation = (simulation: FujifilmSimulation) =>
|
|||||||
|
|
||||||
const parseFujifilmMakerNote = (
|
const parseFujifilmMakerNote = (
|
||||||
bytes: Buffer,
|
bytes: Buffer,
|
||||||
valueForTagUInt: (tagId: number, value: number) => void
|
valueForTagUInt: (tagId: number, value: number) => void,
|
||||||
) => {
|
) => {
|
||||||
const tagCount = bytes.readUint16LE(BYTE_INDEX_TAG_COUNT);
|
const tagCount = bytes.readUint16LE(BYTE_INDEX_TAG_COUNT);
|
||||||
for (let i = 0; i < tagCount; i++) {
|
for (let i = 0; i < tagCount; i++) {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user