diff --git a/packages/studiocms_core/src/sdk-utils/getDatabase.ts b/packages/studiocms_core/src/sdk-utils/get/getDatabase.ts similarity index 69% rename from packages/studiocms_core/src/sdk-utils/getDatabase.ts rename to packages/studiocms_core/src/sdk-utils/get/getDatabase.ts index 168674af..930ebfbf 100644 --- a/packages/studiocms_core/src/sdk-utils/getDatabase.ts +++ b/packages/studiocms_core/src/sdk-utils/get/getDatabase.ts @@ -1,9 +1,15 @@ /// import { db, eq } from 'astro:db'; -import { CMSSiteConfigId } from '../consts'; -import { tsPageData, tsSiteConfig, tsUsers } from '../db/tsTables'; -import type { CombinedPageData, CombinedUserData, SimplifiedTables } from './types'; -import { collectPageData, collectUserData } from './utils'; +import { CMSSiteConfigId } from '../../consts'; +import { tsPageData, tsSiteConfig, tsUsers } from '../../db/tsTables'; +import type { + CombinedPageData, + CombinedUserData, + GetDatabase, + SimplifiedTables, + SiteConfig, +} from '../types'; +import { collectPageData, collectUserData } from '../utils'; /** * Retrieves data from the database based on the specified table. @@ -19,7 +25,7 @@ import { collectPageData, collectUserData } from './utils'; * * @throws Will throw an error if the specified database table is not recognized. */ -export async function getDatabase(database: SimplifiedTables) { +export async function getDatabase(database: SimplifiedTables): Promise { switch (database) { case 'users': { const combinedUserData: CombinedUserData[] = []; @@ -48,9 +54,19 @@ export async function getDatabase(database: SimplifiedTables) { return pages; } case 'config': { - return await db.select().from(tsSiteConfig).where(eq(tsSiteConfig.id, CMSSiteConfigId)).get(); + const siteConfig = await db + .select() + .from(tsSiteConfig) + .where(eq(tsSiteConfig.id, CMSSiteConfigId)) + .get(); + + if (!siteConfig) return undefined; + + return siteConfig as SiteConfig; } default: throw new Error(`Database table '${database}' not recognized.`); } } + +export default getDatabase; diff --git a/packages/studiocms_core/src/sdk-utils/getDatabaseEntry.ts b/packages/studiocms_core/src/sdk-utils/get/getDatabaseEntry.ts similarity index 95% rename from packages/studiocms_core/src/sdk-utils/getDatabaseEntry.ts rename to packages/studiocms_core/src/sdk-utils/get/getDatabaseEntry.ts index 9ec9df31..f1860db0 100644 --- a/packages/studiocms_core/src/sdk-utils/getDatabaseEntry.ts +++ b/packages/studiocms_core/src/sdk-utils/get/getDatabaseEntry.ts @@ -1,8 +1,13 @@ /// import { and, db, eq } from 'astro:db'; -import { tsPageData, tsUsers } from '../db/tsTables'; -import type { CombinedPageData, CombinedUserData, DatabaseEntryTables } from './types'; -import { collectPageData, collectUserData } from './utils'; +import { tsPageData, tsUsers } from '../../db/tsTables'; +import type { + CombinedPageData, + CombinedUserData, + DatabaseEntryTables, + GetDatabaseEntry, +} from '../types'; +import { collectPageData, collectUserData } from '../utils'; /** * Retrieves a database entry based on the specified table. @@ -33,7 +38,7 @@ import { collectPageData, collectUserData } from './utils'; * } * ``` */ -export function getDatabaseEntry(database: DatabaseEntryTables) { +export function getDatabaseEntry(database: DatabaseEntryTables): GetDatabaseEntry { switch (database) { case 'users': { return { @@ -204,3 +209,5 @@ export function getDatabaseEntry(database: DatabaseEntryTables) { } } } + +export default getDatabaseEntry; diff --git a/packages/studiocms_core/src/sdk-utils/getDatabaseRaw.ts b/packages/studiocms_core/src/sdk-utils/get/getDatabaseTable.ts similarity index 85% rename from packages/studiocms_core/src/sdk-utils/getDatabaseRaw.ts rename to packages/studiocms_core/src/sdk-utils/get/getDatabaseTable.ts index 807acb69..dbf4c143 100644 --- a/packages/studiocms_core/src/sdk-utils/getDatabaseRaw.ts +++ b/packages/studiocms_core/src/sdk-utils/get/getDatabaseTable.ts @@ -1,6 +1,6 @@ /// import { db, eq } from 'astro:db'; -import { CMSSiteConfigId } from '../consts'; +import { CMSSiteConfigId } from '../../consts'; import { tsDiffTracking, tsOAuthAccounts, @@ -12,8 +12,8 @@ import { tsSessionTable, tsSiteConfig, tsUsers, -} from '../db/tsTables'; -import type { CurrentTables } from './types'; +} from '../../db/tsTables'; +import type { CurrentTables, DatabaseTables } from '../types'; /** * Retrieves raw data from the specified database table. @@ -28,7 +28,7 @@ import type { CurrentTables } from './types'; * console.log(users); * ``` */ -export async function getDatabaseRaw(database: CurrentTables) { +export async function getDatabaseTable(database: CurrentTables): Promise { switch (database) { case 'users': return await db.select().from(tsUsers); @@ -54,3 +54,5 @@ export async function getDatabaseRaw(database: CurrentTables) { throw new Error(`Unknown database table: ${database}`); } } + +export default getDatabaseTable; diff --git a/packages/studiocms_core/src/sdk-utils/get/index.ts b/packages/studiocms_core/src/sdk-utils/get/index.ts new file mode 100644 index 00000000..a14d9369 --- /dev/null +++ b/packages/studiocms_core/src/sdk-utils/get/index.ts @@ -0,0 +1,3 @@ +export { default as getDatabase } from './getDatabase'; +export { default as getDatabaseEntry } from './getDatabaseEntry'; +export { default as getDatabaseTable } from './getDatabaseTable'; diff --git a/packages/studiocms_core/src/sdk-utils/index.ts b/packages/studiocms_core/src/sdk-utils/index.ts index 567954cf..85a4f9ab 100644 --- a/packages/studiocms_core/src/sdk-utils/index.ts +++ b/packages/studiocms_core/src/sdk-utils/index.ts @@ -1,6 +1,29 @@ -export * from './getDatabase'; -export * from './getDatabaseEntry'; -export * from './getDatabaseRaw'; +import { getDatabase, getDatabaseEntry, getDatabaseTable } from './get'; +import type { STUDIOCMS_SDK } from './types'; -export * from './utils'; -export * from './types'; +/** + * ## The StudioCMS SDK + * + * The StudioCMS SDK provides a set of utility functions to interact with the StudioCMS database. + * + * @example + * ```typescript + * // Install and import the SDK `npm install @studiocms/core` + * import StudioCMS_SDK from '@studiocms/core/sdk-utils'; + * // or using the virtual module (Included by default in StudioCMS) + * import StudioCMS_SDK from 'studiocms:sdk'; + * + * const users = await StudioCMS_SDK.GET.database('users'); + * + * console.log(users); + * ``` + */ +export const StudioCMS_SDK: STUDIOCMS_SDK = { + GET: { + database: async (database) => await getDatabase(database), + databaseEntry: (database) => getDatabaseEntry(database), + databaseTable: async (database) => await getDatabaseTable(database), + }, +}; + +export default StudioCMS_SDK; diff --git a/packages/studiocms_core/src/sdk-utils/types.ts b/packages/studiocms_core/src/sdk-utils/types.ts index 1a6abfeb..168232bf 100644 --- a/packages/studiocms_core/src/sdk-utils/types.ts +++ b/packages/studiocms_core/src/sdk-utils/types.ts @@ -1,4 +1,5 @@ import type { + tsDiffTracking, tsOAuthAccounts, tsPageContent, tsPageData, @@ -6,6 +7,7 @@ import type { tsPageDataTags, tsPermissions, tsSessionTable, + tsSiteConfig, tsUsers, } from '../db/tsTables'; @@ -111,6 +113,8 @@ export type tsPageDataTagsSelect = typeof tsPageDataTags.$inferSelect; */ export type tsPageDataCategoriesSelect = typeof tsPageDataCategories.$inferSelect; +export type tsDiffTrackingSelect = typeof tsDiffTracking.$inferSelect; + /** * Type alias for the inferred select type of `tsPageContent`. * @@ -119,6 +123,26 @@ export type tsPageDataCategoriesSelect = typeof tsPageDataCategories.$inferSelec */ export type tsPageContentSelect = typeof tsPageContent.$inferSelect; +/** + * Type representing the selection of site configuration data. + * + * This type is inferred from the `$inferSelect` property of the `tsSiteConfig` object. + */ +export type tsSiteConfigSelect = typeof tsSiteConfig.$inferSelect; + +/** + * Type representing the insertion of site configuration data. + * + * This type is inferred from the `$inferInsert` property of the `tsSiteConfig` object. + */ +export type tsSiteConfigInsert = typeof tsSiteConfig.$inferInsert; + +/** + * Represents a stripped-down version of the `tsSiteConfigSelect` type, + * excluding the property 'id'. + */ +export type SiteConfig = Omit; + /** * Represents a stripped-down version of the `tsPageDataSelect` type, * excluding the properties 'catagories', 'categories', 'tags', and 'contributorIds'. @@ -163,3 +187,103 @@ export interface CombinedPageData extends PageDataStripped { multiLangContent: tsPageContentSelect[]; defaultContent: tsPageContentSelect | undefined; } + +interface GetDatabaseEntryUser { + byId: (id: string) => Promise; + byUsername: (username: string) => Promise; + byEmail: (email: string) => Promise; +} + +interface GetDatabaseEntryPage { + byId: (id: string) => Promise; + bySlug: (slug: string, pkg: string) => Promise; +} + +export type GetDatabaseEntry = GetDatabaseEntryUser | GetDatabaseEntryPage; + +export type DatabaseTables = + | tsUsersSelect[] + | tsOAuthAccountsSelect[] + | tsSessionTableSelect[] + | tsPermissionsSelect[] + | tsSiteConfigSelect + | tsPageDataSelect[] + | tsPageDataTagsSelect[] + | tsPageDataCategoriesSelect[] + | tsPageContentSelect[] + | tsDiffTrackingSelect[] + | undefined; + +export type GetDatabase = SiteConfig | CombinedUserData[] | CombinedPageData[] | undefined; + +/** + * Interface representing the STUDIOCMS SDK. + */ +export interface STUDIOCMS_SDK { + /** + * Contains methods for getting data from the database. + */ + GET: { + /** + * Retrieves data from the database based on the specified table. + * + * @param database - The name of the database table to retrieve data from. + * It can be one of the following values: 'users', 'pages', or 'config'. + * + * @returns A promise that resolves to the data retrieved from the specified table. + * + * - If `database` is 'users', it returns an array of `CombinedUserData` objects. + * - If `database` is 'pages', it returns an array of `CombinedPageData` objects. + * - If `database` is 'config', it returns the site configuration object. + * + * @throws Will throw an error if the specified database table is not recognized. + */ + database: (database: SimplifiedTables) => Promise; + + /** + * Retrieves a database entry based on the specified table. + * + * @param database - The name of the database table to retrieve the entry from. + * @returns An object containing methods to retrieve entries by different criteria. + * + * The function supports the following tables: + * - 'users': Provides methods to retrieve user data by ID, username, or email. + * - 'pages': Provides methods to retrieve page data by ID or slug and optionally package. + * + * @example + * ```typescript + * const userEntry = getDatabaseEntry('users'); + * const userData = await userEntry.byId('example-id'); + * if (userData) { + * console.log(userData); + * } else { + * console.log('User not found'); + * } + * + * const pageEntry = getDatabaseEntry('pages'); + * const pageData = await pageEntry.byId('example-id'); + * if (pageData) { + * console.log(pageData); + * } else { + * console.log('Page not found'); + * } + * ``` + */ + databaseEntry: (database: DatabaseEntryTables) => GetDatabaseEntry; + + /** + * Retrieves raw data from the specified database table. + * + * @param database - The name of the database table to retrieve data from. + * @returns A promise that resolves to the data from the specified database table. + * @throws An error if the specified database table is unknown. + * + * @example + * ```typescript + * const users = await getDatabaseRaw('users'); + * console.log(users); + * ``` + */ + databaseTable: (database: CurrentTables) => Promise; + }; +}