UNPKG

studiocms

Version:

Astro Native CMS for AstroDB. Built from the ground up by the Astro community.

229 lines (228 loc) 7.93 kB
import { eq } from "astro:db"; import { CMSMailerConfigId, CMSNotificationSettingsId, CMSSiteConfigId, Next_MailerConfigId, Next_NotificationSettingsId, Next_SiteConfigId, TemplateConfigId } from "../../../consts.js"; import { Deepmerge, Effect } from "../../../effect.js"; import defaultTemplates from "../../template-engine/default-templates.js"; import { CURRENT_CONFIG_VERSION, TEMPLATE_CONFIG_VERSION } from "../consts.js"; import { AstroDB } from "../effect/db.js"; import { tsDynamicConfigSettings, tsMailerConfig, tsNotificationSettings, tsSiteConfig } from "../tables.js"; const castType = ({ data, id }) => ({ id, data }); const migrateLegacySiteConfig = ({ id, gridItems, ...legacyConfig }) => ({ ...legacyConfig, gridItems: gridItems ?? [], _config_version: CURRENT_CONFIG_VERSION }); const migrateLegacyMailerConfig = ({ id, ...legacyConfig }) => ({ ...legacyConfig, _config_version: CURRENT_CONFIG_VERSION }); const migrateLegacyNotificationSettings = ({ id, ...legacyConfig }) => ({ ...legacyConfig, _config_version: CURRENT_CONFIG_VERSION }); class SDKCore_CONFIG extends Effect.Service()( "studiocms/sdk/modules/SDKCore_CONFIG", { dependencies: [AstroDB.Default, Deepmerge.Default], effect: Effect.gen(function* () { const [dbService, { merge }] = yield* Effect.all([AstroDB, Deepmerge]); const _insert = dbService.makeQuery( (ex, entry) => ex((db) => db.insert(tsDynamicConfigSettings).values(entry).returning().get()) ); const _select = dbService.makeQuery( (ex, id) => ex( (db) => db.select().from(tsDynamicConfigSettings).where(eq(tsDynamicConfigSettings.id, id)).get() ) ); const _update = dbService.makeQuery( (ex, entry) => ex( (db) => db.update(tsDynamicConfigSettings).set(entry).where(eq(tsDynamicConfigSettings.id, entry.id)).returning().get() ) ); const create = Effect.fn(function* (id, data) { const entry = castType({ id, data }); return yield* _insert(entry); }); const get = Effect.fn(function* (id) { const entry = yield* _select(id); if (!entry) return void 0; return castType(entry); }); const update = Effect.fn(function* (id, data) { const entry = castType({ id, data }); return yield* _update(entry); }); const runMigration = Effect.fn(function* (opts) { const { table, legacyId, migrate, newId } = opts; const legacyConfig = yield* dbService.execute( (db) => db.select().from(table).where(eq(table.id, legacyId)).get() ); if (!legacyConfig) return; const newConfig = migrate(legacyConfig); return yield* create(newId, newConfig); }); const dynamicGet = Effect.fn(function* (id, migrationOpts) { const entry = yield* get(id); if (!entry) { return yield* runMigration(migrationOpts); } if (entry.data._config_version !== CURRENT_CONFIG_VERSION) { return yield* update(id, { ...entry.data, _config_version: CURRENT_CONFIG_VERSION }); } return entry; }); const dynamicUpdate = Effect.fn(function* (id, data) { const entry = yield* get(id); if (!entry) return void 0; const updatedEntry = yield* merge((m) => m(entry.data, data)); return yield* update(id, updatedEntry); }); const siteConfig = { /** * Retrieves the current site configuration. */ get: () => dynamicGet(Next_SiteConfigId, { table: tsSiteConfig, legacyId: CMSSiteConfigId, migrate: migrateLegacySiteConfig, newId: Next_SiteConfigId }), /** * Updates the site configuration with the provided data. * @param data The new configuration data, excluding the internal version field. * @returns The updated site configuration. */ update: (data) => dynamicUpdate(Next_SiteConfigId, { ...data, _config_version: CURRENT_CONFIG_VERSION }), /** * Initializes the site configuration with the provided data. * @param data The initial configuration data, excluding the internal version field. * @returns The created site configuration. */ init: (data) => create(Next_SiteConfigId, { ...data, _config_version: CURRENT_CONFIG_VERSION }) }; const mailerConfig = { /** * Retrieves the current mailer configuration. */ get: () => dynamicGet(Next_MailerConfigId, { table: tsMailerConfig, legacyId: CMSMailerConfigId, migrate: migrateLegacyMailerConfig, newId: Next_MailerConfigId }), /** * Updates the mailer configuration with the provided data. * @param data The new configuration data, excluding the internal version field. * @returns The updated mailer configuration. */ update: (data) => dynamicUpdate(Next_MailerConfigId, { ...data, _config_version: CURRENT_CONFIG_VERSION }), /** * Initializes the mailer configuration with the provided data. * @param data The initial configuration data, excluding the internal version field. * @returns The created mailer configuration. */ init: (data) => create(Next_MailerConfigId, { ...data, _config_version: CURRENT_CONFIG_VERSION }) }; const notificationConfig = { /** * Retrieves the current notification settings. */ get: () => dynamicGet(Next_NotificationSettingsId, { table: tsNotificationSettings, legacyId: CMSNotificationSettingsId, migrate: migrateLegacyNotificationSettings, newId: Next_NotificationSettingsId }), /** * Updates the notification settings with the provided data. * @param data The new notification settings, excluding the `_config_version` property. * @returns A promise resolving to the updated `StudioCMSNotificationSettings`. */ update: (data) => dynamicUpdate(Next_NotificationSettingsId, { ...data, _config_version: CURRENT_CONFIG_VERSION }), /** * Initializes the notification settings with the provided data. * @param data The initial configuration data, excluding the internal version field. * @returns The created notification settings. */ init: (data) => create(Next_NotificationSettingsId, { ...data, _config_version: CURRENT_CONFIG_VERSION }) }; const templateConfig = { get: () => get(TemplateConfigId), update: (data) => Effect.gen(function* () { const currentData = yield* get(TemplateConfigId); if (!currentData) { const updatedData2 = yield* merge((m) => m(defaultTemplates, data)); return yield* create(TemplateConfigId, { ...updatedData2, _config_version: TEMPLATE_CONFIG_VERSION }); } const updatedData = yield* merge((m) => m(currentData.data, data)); return yield* update(TemplateConfigId, { ...updatedData, _config_version: TEMPLATE_CONFIG_VERSION }); }), init: (data) => create(TemplateConfigId, { ...data, _config_version: TEMPLATE_CONFIG_VERSION }) }; return { siteConfig, mailerConfig, notificationConfig, templateConfig }; }) } ) { } export { SDKCore_CONFIG, castType, migrateLegacyMailerConfig, migrateLegacyNotificationSettings, migrateLegacySiteConfig };