diff --git a/.astro/types.d.ts b/.astro/types.d.ts index d56cfaf4..652a1df5 100644 --- a/.astro/types.d.ts +++ b/.astro/types.d.ts @@ -1,208 +1,3 @@ -declare module 'astro:content' { - interface Render { - '.mdx': Promise<{ - Content: import('astro').MarkdownInstance<{}>['Content']; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - }>; - } -} - -declare module 'astro:content' { - interface Render { - '.md': Promise<{ - Content: import('astro').MarkdownInstance<{}>['Content']; - headings: import('astro').MarkdownHeading[]; - remarkPluginFrontmatter: Record; - }>; - } -} - -declare module 'astro:content' { - type Flatten = T extends { [K: string]: infer U } ? U : never; - - export type CollectionKey = keyof AnyEntryMap; - export type CollectionEntry = Flatten; - - export type ContentCollectionKey = keyof ContentEntryMap; - export type DataCollectionKey = keyof DataEntryMap; - - type AllValuesOf = T extends any ? T[keyof T] : never; - type ValidContentEntrySlug = AllValuesOf< - ContentEntryMap[C] - >['slug']; - - export function getEntryBySlug< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - // Note that this has to accept a regular string too, for SSR - entrySlug: E - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - - export function getDataEntryById( - collection: C, - entryId: E - ): Promise>; - - export function getCollection>( - collection: C, - filter?: (entry: CollectionEntry) => entry is E - ): Promise; - export function getCollection( - collection: C, - filter?: (entry: CollectionEntry) => unknown - ): Promise[]>; - - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >(entry: { - collection: C; - slug: E; - }): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >(entry: { - collection: C; - id: E; - }): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - export function getEntry< - C extends keyof ContentEntryMap, - E extends ValidContentEntrySlug | (string & {}), - >( - collection: C, - slug: E - ): E extends ValidContentEntrySlug - ? Promise> - : Promise | undefined>; - export function getEntry< - C extends keyof DataEntryMap, - E extends keyof DataEntryMap[C] | (string & {}), - >( - collection: C, - id: E - ): E extends keyof DataEntryMap[C] - ? Promise - : Promise | undefined>; - - /** Resolve an array of entry references from the same collection */ - export function getEntries( - entries: { - collection: C; - slug: ValidContentEntrySlug; - }[] - ): Promise[]>; - export function getEntries( - entries: { - collection: C; - id: keyof DataEntryMap[C]; - }[] - ): Promise[]>; - - export function reference( - collection: C - ): import('astro/zod').ZodEffects< - import('astro/zod').ZodString, - C extends keyof ContentEntryMap - ? { - collection: C; - slug: ValidContentEntrySlug; - } - : { - collection: C; - id: keyof DataEntryMap[C]; - } - >; - // Allow generic `string` to avoid excessive type errors in the config - // if `dev` is not running to update as you edit. - // Invalid collection names will be caught at build time. - export function reference( - collection: C - ): import('astro/zod').ZodEffects; - - type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; - type InferEntrySchema = import('astro/zod').infer< - ReturnTypeOrOriginal['schema']> - >; - - type ContentEntryMap = { - "post": { -"2022-02-16-example-article-1.mdx": { - id: "2022-02-16-example-article-1.mdx"; - slug: "2022-02-16-example-article-1"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"2022-03-17-example-article-2.mdx": { - id: "2022-03-17-example-article-2.mdx"; - slug: "2022-03-17-example-article-2"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"2023-01-19-example-article-3.mdx": { - id: "2023-01-19-example-article-3.mdx"; - slug: "2023-01-19-example-article-3"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"2024-01-20-example-article-4.mdx": { - id: "2024-01-20-example-article-4.mdx"; - slug: "2024-01-20-example-article-4"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -"2024-01-21-example-article-5.mdx": { - id: "2024-01-21-example-article-5.mdx"; - slug: "2024-01-21-example-article-5"; - body: string; - collection: "post"; - data: InferEntrySchema<"post"> -} & { render(): Render[".mdx"] }; -}; -"project": { -"2024-02-13-example-project-1.mdx": { - id: "2024-02-13-example-project-1.mdx"; - slug: "2024-02-13-example-project-1"; - body: string; - collection: "project"; - data: InferEntrySchema<"project"> -} & { render(): Render[".mdx"] }; -"2024-03-15-example-project-2.mdx": { - id: "2024-03-15-example-project-2.mdx"; - slug: "2024-03-15-example-project-2"; - body: string; - collection: "project"; - data: InferEntrySchema<"project"> -} & { render(): Render[".mdx"] }; -"2024-05-16-example-project-3.mdx": { - id: "2024-05-16-example-project-3.mdx"; - slug: "2024-05-16-example-project-3"; - body: string; - collection: "project"; - data: InferEntrySchema<"project"> -} & { render(): Render[".mdx"] }; -}; - - }; - - type DataEntryMap = { - - }; - - type AnyEntryMap = ContentEntryMap & DataEntryMap; - - export type ContentConfig = typeof import("../src/content/config.js"); -} +/// +/// +/// \ No newline at end of file diff --git a/.github/workflows/bash__deploy-nginx.yml b/.github/workflows/bash__deploy-nginx.yml index 05d23252..cc29b03b 100644 --- a/.github/workflows/bash__deploy-nginx.yml +++ b/.github/workflows/bash__deploy-nginx.yml @@ -8,7 +8,7 @@ on: - 'v[0-9]+.[0-9]+.[0-9]+' pull_request: branches: - - 'main' + - 'disabled-main' workflow_dispatch: env: diff --git a/astro.config.ts b/astro.config.ts index a32ee33e..184e89ab 100644 --- a/astro.config.ts +++ b/astro.config.ts @@ -6,41 +6,34 @@ import { defineConfig } from 'astro/config'; // must use relative imports, and their entire import subtrees import { remarkReadingTime } from './plugins/remark-reading-time.mjs'; +// // all relative imports in subtree -import { CONFIG } from './src/config'; +// any of these files must not import CONFIG with env vars +import { envSchema, PROCESS_ENV } from './src/config/process-env'; import { expressiveCodeIntegration } from './src/libs/integrations/expressive-code'; import { sitemapIntegration } from './src/libs/integrations/sitemap'; -const { SITE_URL } = CONFIG; +const { SITE_URL } = PROCESS_ENV; const remarkPlugins = [remarkReadingTime]; export default defineConfig({ site: SITE_URL, + experimental: { env: envSchema }, trailingSlash: 'ignore', // default compressHTML: true, - server: { - port: 3000, - }, - devToolbar: { - enabled: false, - }, + server: { port: 3000 }, + devToolbar: { enabled: false }, integrations: [ expressiveCodeIntegration(), sitemapIntegration(), react(), - // applyBaseStyles: false prevents double loading of tailwind - tailwind({ - applyBaseStyles: false, - }), mdx(), - icon({ - iconDir: 'src/assets/icons', - }), + // applyBaseStyles: false prevents double loading of tailwind + tailwind({ applyBaseStyles: false }), + icon({ iconDir: 'src/assets/icons' }), ], - markdown: { - remarkPlugins, - }, + markdown: { remarkPlugins }, vite: { build: { sourcemap: false, diff --git a/docs/working-notes/my-old-code/config.ts b/docs/working-notes/my-old-code/config.ts new file mode 100644 index 00000000..9a2bc336 --- /dev/null +++ b/docs/working-notes/my-old-code/config.ts @@ -0,0 +1,46 @@ +import { SITE_URL } from 'astro:env/client'; +import { NODE_ENV, PREVIEW_MODE } from 'astro:env/server'; + +import { configSchema } from './schemas/config'; +import { prettyPrintObject } from './utils/log'; +import { validateData } from './utils/validation'; + +import type { ConfigType } from './types/config'; + +/*-------------------- configData -------------------*/ + +// const { SITE_URL, NODE_ENV, PREVIEW_MODE } = import.meta.env; +// const { SITE_URL, NODE_ENV, PREVIEW_MODE } = { +// SITE_URL: 'http://localhost:3000', +// NODE_ENV: 'development', +// PREVIEW_MODE: false, +// } as const; + +console.log('SITE_URL', SITE_URL, 'NODE_ENV', NODE_ENV, 'PREVIEW_MODE', PREVIEW_MODE); + +/** SSG - all env vars are build time only. */ +const configData: ConfigType = { + NODE_ENV, + PREVIEW_MODE, + /** all urls without '/' */ + SITE_URL, + SITE_TITLE: 'Nemanja Mitic', + SITE_DESCRIPTION: 'I am Nemanja, full stack developer', + PAGE_SIZE_POST_CARD: 3, + PAGE_SIZE_POST_CARD_SMALL: 6, + MORE_POSTS_COUNT: 3, + DEFAULT_MODE: 'light', + DEFAULT_THEME: 'default-light', + AUTHOR_NAME: 'Nemanja Mitic', + AUTHOR_EMAIL: 'email@email.com', + AUTHOR_GITHUB: 'https://github.com/nemanjam', + AUTHOR_LINKEDIN: 'https://www.linkedin.com/in/nemanja-mitic', + AUTHOR_TWITTER: 'https://x.com/nemanja_codes', + AUTHOR_YOUTUBE: 'https://www.youtube.com/@nemanja_codes', + REPO_URL: 'https://github.com/nemanjam/nemanjam.github.io', +}; + +// todo: Config should go into import.meta.env in astro.config.ts +export const CONFIG = validateData(configData, configSchema); + +// prettyPrintObject(CONFIG, 'parsed CONFIG'); diff --git a/docs/working-notes/todo3.md b/docs/working-notes/todo3.md index b793798a..e8252df5 100644 --- a/docs/working-notes/todo3.md +++ b/docs/working-notes/todo3.md @@ -505,5 +505,13 @@ a href open in new tab fix links page links color for history back view transition refactor theme script, osDefaultMode, appDefaultMode, storedMode +change meta theme bg color with js, astro-paper + +replace import config with import.meta.env.VAR +ask about app start handler for log env vars + +fix image sizes for gallery and other +update bg color meta tag +fix links page on user dark mode preference text color ------------ ``` diff --git a/package.json b/package.json index 432c741b..7472c6d1 100644 --- a/package.json +++ b/package.json @@ -30,7 +30,7 @@ "@astrojs/tailwind": "^5.1.0", "@fontsource-variable/inter": "^5.0.20", "@tailwindcss/typography": "^0.5.13", - "astro": "^4.13.1", + "astro": "^4.14.4", "astro-embed": "^0.7.2", "astro-expressive-code": "^0.35.6", "astro-icon": "^1.1.0", diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index d12aaff0..68a2c356 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -7,13 +7,13 @@ import { ViewTransitions } from 'astro:transitions'; import ThemeScript from '@/components/ThemeScript.astro'; import { DEFAULT_METADATA } from '@/constants/metadata'; import { ROUTES } from '@/constants/routes'; -import { CONFIG } from '@/config'; +import { CONFIG_CLIENT } from '@/config/client'; import { handleTitle } from '@/utils/metadata'; import { filterUndefined } from '@/utils/objects'; import type { Metadata } from '@/types/common'; -const { AUTHOR_NAME } = CONFIG; +const { AUTHOR_NAME } = CONFIG_CLIENT; export interface BaseHeadProps { metadata: Metadata; @@ -110,6 +110,7 @@ const ogImageUrl = new URL(image, url); --> + {/* MUST be inside to avoid white flash, IMPORTANT */} diff --git a/src/components/Footer.astro b/src/components/Footer.astro index 0ea3855a..f317b3f8 100644 --- a/src/components/Footer.astro +++ b/src/components/Footer.astro @@ -3,12 +3,12 @@ import { Icon } from 'astro-icon/components'; import Link from '@/components/Link.astro'; import { ROUTES } from '@/constants/routes'; -import { CONFIG } from '@/config'; +import { CONFIG_CLIENT } from '@/config/client'; import { getLatestCommitInfo } from '@/libs/git'; import { shortDate } from '@/utils/datetime'; import { limitString, trimHttpProtocol } from '@/utils/strings'; -const { SITE_URL, AUTHOR_LINKEDIN, AUTHOR_GITHUB, REPO_URL } = CONFIG; +const { SITE_URL, AUTHOR_LINKEDIN, AUTHOR_GITHUB, REPO_URL } = CONFIG_CLIENT; const domain = trimHttpProtocol(SITE_URL); const messageLength = 20 as const; diff --git a/src/components/Giscus.astro b/src/components/Giscus.astro index dc0abac7..57fd2d5e 100644 --- a/src/components/Giscus.astro +++ b/src/components/Giscus.astro @@ -34,8 +34,9 @@ const { class: className } = Astro.props; import 'giscus'; import { SELECTORS } from '@/constants/dom'; - import { THEME_CONFIG } from '@/constants/themes'; - import { getCurrentMode, sendModeToGiscus } from '@/utils/dom'; + import { THEME_CONFIG } from '@/constants/theme'; + import { sendModeToGiscus } from '@/utils/dom'; + import { getCurrentMode } from '@/utils/theme'; import type { ChangeThemeCustomEvent } from '@/types/constants'; diff --git a/src/components/Header.astro b/src/components/Header.astro index de1fb390..854ed434 100644 --- a/src/components/Header.astro +++ b/src/components/Header.astro @@ -10,7 +10,7 @@ import { SELECTORS } from '@/constants/dom'; import { IMAGE_SIZES } from '@/constants/image'; import { NAVIGATION_ITEMS } from '@/constants/navigation'; import { ROUTES } from '@/constants/routes'; -import { CONFIG } from '@/config'; +import { CONFIG_CLIENT } from '@/config/client'; import { getActiveNavItemPath } from '@/utils/navigation'; import Avatar from '@/assets/images/avatar.jpg'; @@ -43,7 +43,7 @@ const activeNavItemPath = getActiveNavItemPath(routePathname); alt="Profile picture" /> - {CONFIG.AUTHOR_NAME} + {CONFIG_CLIENT.AUTHOR_NAME} diff --git a/src/components/Share.astro b/src/components/Share.astro index 9454ac0e..c3c0c422 100644 --- a/src/components/Share.astro +++ b/src/components/Share.astro @@ -9,7 +9,7 @@ import { } from 'astro-social-share'; import { DEFAULT_METADATA } from '@/constants/metadata'; -import { CONFIG } from '@/config'; +import { CONFIG_CLIENT } from '@/config/client'; import { cn } from '@/utils/styles'; import type { ComponentProps } from 'astro/types'; @@ -21,7 +21,7 @@ export interface Props extends SocialShareProps { const { class: className, ...shareProps } = Astro.props; const { title, description } = DEFAULT_METADATA; -const { AUTHOR_TWITTER } = CONFIG; +const { AUTHOR_TWITTER } = CONFIG_CLIENT; // via is only for twitter const defaultProps = { description, title, via: AUTHOR_TWITTER }; diff --git a/src/components/ThemeScript.astro b/src/components/ThemeScript.astro index 6a83aeb2..ed80b536 100644 --- a/src/components/ThemeScript.astro +++ b/src/components/ThemeScript.astro @@ -1,43 +1,92 @@ --- -import * as themeConstants from '@/constants/themes'; +import * as themeConstants from '@/constants/theme'; +import { CONFIG_CLIENT } from '@/config/client'; +import { getDefaultThemes } from '@/utils/theme'; + +// can not import server vars, is:inline + +const { DEFAULT_MODE } = CONFIG_CLIENT; +const defaultThemes = getDefaultThemes(); --- {/* Inlined to avoid flash of white content. */} - diff --git a/src/components/ThemeToggle.astro b/src/components/ThemeToggle.astro index b42f2d8a..492248a2 100644 --- a/src/components/ThemeToggle.astro +++ b/src/components/ThemeToggle.astro @@ -10,8 +10,8 @@ import { Icon } from 'astro-icon/components';