studiocms
Version:
Astro Native CMS for AstroDB. Built from the ground up by the Astro community.
119 lines (98 loc) • 3.48 kB
text/typescript
import { loadChangelog, semverCategories } from '@withstudiocms/internal_helpers/utils';
import type { APIContext } from 'astro';
import type { List, Root } from 'mdast';
import { toMarkdown } from 'mdast-util-to-markdown';
import { Effect, genLogger, HTTPClient, Platform, readAPIContextJson } from '../../../../effect.js';
export class ProcessChangelog extends Effect.Service<ProcessChangelog>()('ProcessChangelog', {
effect: genLogger('routes/sdk/utils/changelog/ProcessChangelog/effect')(function* () {
const httpClient = yield* HTTPClient;
const getRawChangelog = () =>
genLogger('routes/sdk/utils/changelog/ProcessChangelog/effect.getRawChangelog')(function* () {
return yield* httpClient
.get(
'https://raw.githubusercontent.com/withstudiocms/studiocms/refs/heads/main/packages/studiocms/CHANGELOG.md'
)
.pipe(
Effect.flatMap((res) =>
res.status === 200
? res.text
: Effect.fail(
new Error(`Failed to fetch CHANGELOG.md: ${res.status} ${res.toString()}`)
)
)
);
});
const generateChangelog = (raw: string) =>
genLogger('routes/sdk/utils/changelog/ProcessChangelog/effect.generateChangelog')(
function* () {
const ToProcess = yield* Effect.try(() => loadChangelog({ raw }));
const output: string[] = [];
const astEnd: Root = {
type: 'root',
children: [],
};
for (const version of ToProcess.versions) {
const versionChanges: List = { type: 'list', children: [] };
for (const semverCategory of semverCategories) {
for (const listItem of version.changes[semverCategory].children) {
versionChanges.children.push(listItem);
}
}
if (version.includes.size) {
versionChanges.children.push({
type: 'listItem',
children: [
{
type: 'paragraph',
children: [
{ type: 'text', value: `Includes: ${[...version.includes].join(', ')} ` },
],
},
],
});
}
if (!versionChanges.children.length) continue;
astEnd.children.push({
type: 'heading',
depth: 2,
children: [{ type: 'text', value: version.version }],
});
astEnd.children.push(versionChanges);
}
const outputData = yield* Effect.try(() => toMarkdown(astEnd, { bullet: '-' }));
output.push(outputData);
const markdownString = output.join('\n');
return markdownString;
}
);
const renderChangelog = (content: string, context: APIContext) =>
genLogger('routes/sdk/utils/changelog/ProcessChangelog/effect.renderChangelog')(function* () {
const currentRequestJson = yield* readAPIContextJson<{
currentURLOrigin: string;
}>(context);
const currentURLOrigin = currentRequestJson.currentURLOrigin;
const partialUrl = new URL(
context.locals.StudioCMS?.routeMap.endpointLinks.partials.render,
currentURLOrigin
);
return yield* Platform.HttpClientRequest.post(partialUrl).pipe(
Platform.HttpClientRequest.setHeaders({
'Content-Type': 'application/json',
}),
Platform.HttpClientRequest.bodyJson({
content,
}),
Effect.flatMap(httpClient.execute),
Effect.flatMap((response) => response.text)
);
});
return {
getRawChangelog,
generateChangelog,
renderChangelog,
};
}),
dependencies: [HTTPClient.Default],
}) {
static Provide = Effect.provide(this.Default);
}