Skip to content

Commit

Permalink
Merge pull request #110 from thegalactiks/urls-fixes
Browse files Browse the repository at this point in the history
Urls fixes
  • Loading branch information
emmanuelgautier authored Nov 12, 2023
2 parents 3148f31 + 60fab99 commit 84443e1
Show file tree
Hide file tree
Showing 7 changed files with 191 additions and 148 deletions.
6 changes: 6 additions & 0 deletions .changeset/dry-roses-worry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@galactiks/astro-integration": patch
"@galactiks/explorer": patch
---

Urls computation fixes
4 changes: 3 additions & 1 deletion packages/adapters/astro/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"dependencies": {
"@galactiks/config": "workspace:^",
"@galactiks/explorer": "workspace:^",
"date-fns": "2.30.0"
"date-fns": "2.30.0",
"debug": "4.3.4"
},
"peerDependencies": {
"@astrojs/partytown": "2.0.2",
Expand All @@ -57,6 +58,7 @@
"@astrojs/react": "3.0.4",
"@astrojs/rss": "3.0.0",
"@astrojs/sitemap": "3.0.3",
"@types/debug": "4.1.12",
"@types/react": "18.2.37",
"@types/react-dom": "18.2.15",
"astro": "3.5.2",
Expand Down
62 changes: 19 additions & 43 deletions packages/adapters/astro/src/preset.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,54 +2,30 @@ import type { AstroIntegration } from 'astro';
import partytown from '@astrojs/partytown';
import react from '@astrojs/react';
import sitemap from '@astrojs/sitemap';
import { getConfig, getDefaultLanguage, getLanguages } from '@galactiks/config';
import { getPageByURL } from '@galactiks/explorer';
import { getDefaultLanguage, getLanguages } from '@galactiks/config';
import critters from 'astro-critters';
import robotsTxt from 'astro-robots-txt';
import { isValid } from 'date-fns';

const defaultLocale = getDefaultLanguage();
import { sitemapSerialize } from './sitemap.mjs';

export const integrationsPreset = (): AstroIntegration[] => [
react(),
partytown(),
sitemap({
i18n: defaultLocale
? {
defaultLocale,
export const integrationsPreset = (): AstroIntegration[] => {
const defaultLanguage = getDefaultLanguage();

return ([
react(),
partytown(),
sitemap({
i18n: defaultLanguage
? {
defaultLocale: defaultLanguage,
locales: Object.fromEntries(
getLanguages().map((lang) => [lang, lang])
),
}
: undefined,
serialize: async (item) => {
const page = await getPageByURL(item.url);
if (!page) {
return undefined;
}

return {
url: page.url,
lastmod: isValid(page.dateModified)
? page.dateModified.toISOString()
: undefined,
news: page.type === 'Article' && {
publication: {
name: getConfig().webManifest.name,
language: (page.inLanguage && getDefaultLanguage())
?.substring(0, 2)
.toLowerCase(),
},

publication_date: isValid(page.datePublished)
? page.datePublished.toISOString()
: undefined,
title: page.name,
keywords: page.keywords?.join(', '),
},
};
},
}),
robotsTxt(),
critters(),
];
: undefined,
serialize: sitemapSerialize(defaultLanguage),
}),
robotsTxt(),
critters(),
]);
};
39 changes: 39 additions & 0 deletions packages/adapters/astro/src/sitemap.mts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { SitemapItem } from '@astrojs/sitemap';
import { getConfig } from '@galactiks/config';
import { getPageByURL } from '@galactiks/explorer';
import { isValid } from 'date-fns';
import Debug from 'debug';

const debug = Debug('@galactiks/astro-integration:sitemap')

export const sitemapSerialize = (defaultLanguage?: string) => async (item: SitemapItem) => {
debug('serializing item', item);

const page = await getPageByURL(item.url);
if (!page) {
debug('page not found for the item', item);

return undefined;
}

return {
url: page.url,
lastmod: isValid(page.dateModified)
? page.dateModified.toISOString()
: undefined,
news: page.type === 'Article' && {
publication: {
name: getConfig().webManifest.name,
language: (page.inLanguage || defaultLanguage)
?.substring(0, 2)
.toLowerCase(),
},

publication_date: isValid(page.datePublished)
? page.datePublished.toISOString()
: undefined,
title: page.name,
keywords: page.keywords?.join(', '),
},
};
};
2 changes: 2 additions & 0 deletions packages/explorer/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,15 @@
"@galactiks/config": "workspace:^",
"@galactiks/contentlayer": "workspace:^",
"@std-uritemplate/std-uritemplate": "0.0.46",
"debug": "4.3.4",
"esbuild": "0.19.5",
"mdx-bundler": "9.2.1",
"react": "18.2.0",
"slugify": "1.6.6",
"zod": "3.22.4"
},
"devDependencies": {
"@types/debug": "4.1.12",
"@types/react": "18.2.37",
"schema-dts": "1.1.2"
}
Expand Down
208 changes: 107 additions & 101 deletions packages/explorer/src/core/content/urls.mts
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { StdUriTemplate } from '@std-uritemplate/std-uritemplate';
import { getConfig } from '@galactiks/config';
import { documentTypes } from '@galactiks/contentlayer';
import { join } from 'path';
import Debug from 'debug'

import type {
ContentlayerWebPageDocument,
ContentlayerWebsite,
} from './types/index.mjs';
import { homeIdentifier } from './consts.mjs';
import {
documentByIdentifierAndLanguageSelector,
documentsByLanguageSelector,
pageDepthSelector,
} from './selectors.mjs';
import type { ContentlayerWebPageDocumentWithRender } from './render.mjs';
import { homeIdentifier } from './consts.mjs';
import type {
ContentlayerWebPageDocument,
ContentlayerWebsite,
} from './types/index.mjs';

const debug = Debug('@galactiks/explorer:urls');

type WithRequired<T, K extends keyof T> = T & { [P in K]-?: T[P] };
type ContentlayerDocumentWithPath = WithRequired<
Expand All @@ -40,107 +43,110 @@ const makePathRelative = (path: string) =>

export const computeDocumentsUrl =
(websites: ContentlayerWebsite[]) =>
async (documents: ContentlayerWebPageDocumentWithRender[]) => {
const getDocumentByIdentifierAndLanguage =
documentByIdentifierAndLanguageSelector(documents);
const getWebsitesByLanguage = documentsByLanguageSelector(websites);

const { locales, pages, webManifest } = getConfig();

const _getPagePathTemplate = (
type: ContentlayerWebPageDocument['type'],
inLanguage?: string
) => {
const page = pages[documentTypes[type]] || pages[documentTypes.Page];
if (!page) {
return undefined;
}

if (typeof page.path === 'string') {
return page.path;
}

return page.path.find(
({ locale }) => locale === inLanguage || locale === locales?.default
)?.path;
};
async (documents: ContentlayerWebPageDocumentWithRender[]) => {
const getDocumentByIdentifierAndLanguage =
documentByIdentifierAndLanguageSelector(documents);
const getWebsitesByLanguage = documentsByLanguageSelector(websites);

const { locales, pages, webManifest } = getConfig();

const _getPagePathTemplate = (
type: ContentlayerWebPageDocument['type'],
inLanguage?: string
) => {
const page = pages[documentTypes[type]] || pages[documentTypes.Page];
if (!page) {
return undefined;
}

const _getDocumentUrl = (
document: ContentlayerDocumentWithPath
): string => {
if (document.url) {
return document.url;
}

let baseUrl = webManifest.start_url;
if (websites.length === 1 && websites[0].url) {
baseUrl = websites[0].url;
} else if (websites.length > 1 && document.inLanguage) {
const websitesByLanguage = getWebsitesByLanguage(document.inLanguage);
if (websitesByLanguage.length === 1 && websitesByLanguage[0].url) {
baseUrl = websitesByLanguage[0].url;
if (typeof page.path === 'string') {
return page.path;
}
}

return new URL(document.path, baseUrl).toString();
};
return page.path.find(
({ locale }) => locale === inLanguage || locale === locales?.default
)?.path;
};

const _getDocumentUrl = (
document: ContentlayerWebPageDocument, path: string
): string => {
if (document.url) {
return document.url;
}

let baseUrl = webManifest.start_url;
if (websites.length === 1 && websites[0].url) {
baseUrl = websites[0].url;
} else if (websites.length > 1 && document.inLanguage) {
const websitesByLanguage = getWebsitesByLanguage(document.inLanguage);
if (websitesByLanguage.length === 1 && websitesByLanguage[0].url) {
baseUrl = websitesByLanguage[0].url;
}
}

const _computePath = (
document: ContentlayerWebPageDocument
): string | undefined => {
if (document.path) {
return join('/', document.path);
}

const pathTemplate = _getPagePathTemplate(
document.type,
document.inLanguage
);
if (!pathTemplate) {
return undefined;
}

let isPartOfPath: string | undefined;
if (pathTemplate.indexOf('isPartOf') && document.isPartOf) {
// The page has been created if missing
const isPartOf = getDocumentByIdentifierAndLanguage(
document.isPartOf,
return new URL(path, baseUrl).toString();
};

const _computePath = (
document: ContentlayerWebPageDocument
): string | undefined => {
if (document.path) {
return join('/', document.path);
}

const pathTemplate = _getPagePathTemplate(
document.type,
document.inLanguage
) as ContentlayerDocumentWithPath;
isPartOfPath =
makePathRelative(_getPathWithoutTemplate(isPartOf)) || '';
}

const existingStringProperties: [string, string][] = Object.entries({
...document,
identifier:
document.identifier !== homeIdentifier ? document.identifier : '',
isPartOf: isPartOfPath,
}).filter(([, value]) => typeof value === 'string');
return join(
StdUriTemplate.expand(
pathTemplate,
Object.fromEntries(existingStringProperties)
)
);
};
);
if (!pathTemplate) {
return undefined;
}

const selectPageDepth = pageDepthSelector(documents);
return documents
.sort((_document) => selectPageDepth(_document))
.map((_document) => {
const path = _document.path || _computePath(_document);
let url: string | undefined = undefined;
if (path) {
url = _getDocumentUrl(_document as ContentlayerDocumentWithPath);
let isPartOfPath: string | undefined;
if (pathTemplate.indexOf('isPartOf') && document.isPartOf) {
// The page has been created if missing
const isPartOf = getDocumentByIdentifierAndLanguage(
document.isPartOf,
document.inLanguage
);
isPartOfPath = (isPartOf && makePathRelative(_getPathWithoutTemplate(isPartOf))) || '';
}

return {
..._document,
url,
path,
} as ContentlayerWebPageDocumentWithRender &
ContentlayerDocumentWithURL;
})
.filter((_document) => _document.path);
};
const existingStringProperties: [string, string][] = Object.entries({
...document,
identifier:
document.identifier !== homeIdentifier ? document.identifier : '',
isPartOf: isPartOfPath,
}).filter(([, value]) => typeof value === 'string');
return join(
StdUriTemplate.expand(
pathTemplate,
Object.fromEntries(existingStringProperties)
)
);
};

const selectPageDepth = pageDepthSelector(documents);
return documents
.sort((_document) => selectPageDepth(_document))
.map((_document) => {
const path = _document.path || _computePath(_document);
let url: string | undefined = undefined;
if (path) {
url = _getDocumentUrl(_document, path);
}

const _computed = {
..._document,
url,
path,
} as ContentlayerWebPageDocumentWithRender &
ContentlayerDocumentWithURL;

debug('computing document url', _computed);

return _computed;
})
.filter((_document) => _document.path);
};
Loading

0 comments on commit 84443e1

Please sign in to comment.