diff --git a/.changeset/silent-peas-act.md b/.changeset/silent-peas-act.md new file mode 100644 index 000000000..4281166ae --- /dev/null +++ b/.changeset/silent-peas-act.md @@ -0,0 +1,9 @@ +--- +"@studiocms/imagehandler": patch +"@studiocms/dashboard": patch +"@studiocms/renderers": patch +"@studiocms/auth": patch +"@studiocms/core": patch +--- + +Update `.d.ts` file generation (non breaking) diff --git a/.github/renovate.json b/.github/renovate.json index 1a0e6a54f..469e5f28e 100644 --- a/.github/renovate.json +++ b/.github/renovate.json @@ -7,14 +7,11 @@ "customManagers:biomeVersions" ], "dependencyDashboard": true, - "lockFileMaintenance": { - "enabled": true - }, "postUpdateOptions": ["pnpmDedupe"], "ignorePaths": ["**/node_modules/**", "**/bower_components/**"], "labels": ["dependencies"], "additionalBranchPrefix": "{{parentDir}}-", - "gitIgnoredAuthors": ["github+renovate@astro-studiocms.xyz"], + "gitIgnoredAuthors": ["github+renovate@studiocms.xyz"], "prHourlyLimit": 3, "rangeStrategy": "bump", "reviewers": ["team:exalted"], @@ -25,7 +22,10 @@ }, { "matchDepTypes": ["packageManager", "engines"], - "labels": ["dependencies"], + "enabled": false + }, + { + "matchFileNames": [".node-version"], "enabled": false } ] diff --git a/.github/workflows/renovate-changesets.yml b/.github/workflows/renovate-changesets.yml index 66c68611c..88e994a1a 100644 --- a/.github/workflows/renovate-changesets.yml +++ b/.github/workflows/renovate-changesets.yml @@ -17,4 +17,4 @@ jobs: token: ${{ secrets.DEPENDENCY_UPDATE_GITHUB_TOKEN }} use-conventional-commits: true author-name: Renovate Changesets - author-email: github+renovate@astro-studiocms.xyz \ No newline at end of file + author-email: github+renovate@studiocms.xyz \ No newline at end of file diff --git a/packages/studiocms_auth/package.json b/packages/studiocms_auth/package.json index ac52c21c3..0d4fb3851 100644 --- a/packages/studiocms_auth/package.json +++ b/packages/studiocms_auth/package.json @@ -37,6 +37,7 @@ "dependencies": { "@inox-tools/runtime-logger": "catalog:studiocms-shared", "@matthiesenxyz/astrolace": "catalog:studiocms-shared", + "@matthiesenxyz/astrodtsbuilder": "catalog:studiocms-shared", "@matthiesenxyz/integration-utils": "catalog:studiocms-shared", "@noble/hashes": "catalog:studiocms-shared", "@studiocms/assets": "workspace:*", diff --git a/packages/studiocms_auth/src/integration.ts b/packages/studiocms_auth/src/integration.ts index 0bb84fcec..4b41f340b 100644 --- a/packages/studiocms_auth/src/integration.ts +++ b/packages/studiocms_auth/src/integration.ts @@ -164,14 +164,8 @@ export default defineIntegration({ }, 'astro:config:done': async ({ injectTypes }) => { // Inject Types - injectTypes({ - filename: 'auth-config.d.ts', - content: authConfigDTS, - }); - injectTypes({ - filename: 'auth-helper.d.ts', - content: authHelperDTS, - }); + injectTypes(authConfigDTS); + injectTypes(authHelperDTS); }, }, }; diff --git a/packages/studiocms_auth/src/stubs/auth-config.ts b/packages/studiocms_auth/src/stubs/auth-config.ts index 99a27e185..08fcdcd09 100644 --- a/packages/studiocms_auth/src/stubs/auth-config.ts +++ b/packages/studiocms_auth/src/stubs/auth-config.ts @@ -1,16 +1,29 @@ -import fileFactory from '@matthiesenxyz/integration-utils/fileFactory'; +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; -const authConfigDTS = fileFactory(); +const authConfig = DTSBuilder(); -authConfigDTS.addLines('// This file is generated by StudioCMS\n\n'); - -authConfigDTS.addLines(`declare module 'studiocms:auth/config' {`); -authConfigDTS.addLines( - ` const AuthSecurityConfig: import('@studiocms/core').usernameAndPasswordConfig;` +authConfig.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' ); -authConfigDTS.addLines(' export default AuthSecurityConfig;'); -authConfigDTS.addLines('}'); -const DTSFile = authConfigDTS.text(); +authConfig.addModule('studiocms:auth/config', { + defaultExport: { + singleLineDescription: 'Auth Security Config for Username and Password Authentication.', + typeDef: `{ + salt: string | Uint8Array; + opts: { + N: number; + r: number; + p: number; + dkLen?: number; + asyncTick?: number; + maxmem?: number; + onProgress?: (progress: number) => void; + }; + }`, + }, +}); + +const dtsFile = authConfig.makeAstroInjectedType('auth-config.d.ts'); -export default DTSFile; +export default dtsFile; diff --git a/packages/studiocms_auth/src/stubs/auth-helpers.ts b/packages/studiocms_auth/src/stubs/auth-helpers.ts index 6392348c8..57e0a45ae 100644 --- a/packages/studiocms_auth/src/stubs/auth-helpers.ts +++ b/packages/studiocms_auth/src/stubs/auth-helpers.ts @@ -1,32 +1,36 @@ -import fileFactory from '@matthiesenxyz/integration-utils/fileFactory'; +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; import { createResolver } from 'astro-integration-kit'; const { resolve } = createResolver(import.meta.url); -const authHelperDTS = fileFactory(); - -authHelperDTS.addLines('// This file is generated by StudioCMS\n\n'); - -authHelperDTS.addLines(`declare module 'studiocms:auth/helpers' {`); - -authHelperDTS.addLines(` - /** - * # Auth Helper Function - * - * @param locals The Astro.locals object - * @returns The current user data and session information - * - * @example - * --- - * import { authHelper } from 'studiocms:auth/helpers' - * - * const { id, username, name, email, avatar, githubURL, permissionLevel, currentUserSession } = await authHelper(Astro.locals) - * --- - */ - export const authHelper: typeof import('${resolve('../helpers/authHelper.ts')}').default;`); - -authHelperDTS.addLines('}'); - -const DTSFile = authHelperDTS.text(); - -export default DTSFile; +const authHelper = DTSBuilder(); + +authHelper.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' +); + +authHelper.addModule('studiocms:auth/helpers', { + namedExports: [ + { + multiLineDescription: [ + '# Auth Helper Function', + '', + '@param locals The Astro.locals object', + '@returns The current user data and session information', + '', + '@example', + '---', + "import { authHelper } from 'studiocms:auth/helpers'", + '', + 'const { id, username, name, email, avatar, githubURL, permissionLevel, currentUserSession } = await authHelper(Astro.locals)', + '---', + ], + name: 'authHelper', + typeDef: `typeof import('${resolve('../helpers/authHelper.ts')}').default`, + }, + ], +}); + +const dtsFile = authHelper.makeAstroInjectedType('auth-helper.d.ts'); + +export default dtsFile; diff --git a/packages/studiocms_core/package.json b/packages/studiocms_core/package.json index 03ef240a4..0d08c04bf 100644 --- a/packages/studiocms_core/package.json +++ b/packages/studiocms_core/package.json @@ -48,6 +48,7 @@ "dependencies": { "@markdoc/markdoc": "catalog:studiocms-shared", "@matthiesenxyz/astrolace": "catalog:studiocms-shared", + "@matthiesenxyz/astrodtsbuilder": "catalog:studiocms-shared", "@matthiesenxyz/integration-utils": "catalog:studiocms-shared", "@noble/hashes": "catalog:studiocms-shared", "@studiocms/robotstxt": "workspace:*", diff --git a/packages/studiocms_core/src/integration.ts b/packages/studiocms_core/src/integration.ts index 80edb54cf..ee9dd0cae 100644 --- a/packages/studiocms_core/src/integration.ts +++ b/packages/studiocms_core/src/integration.ts @@ -1,4 +1,5 @@ import { integrationLogger } from '@matthiesenxyz/integration-utils/astroUtils'; +import type { InjectedType } from 'astro'; import { createResolver, defineIntegration } from 'astro-integration-kit'; import { version } from '../package.json'; import { name } from '../package.json'; @@ -11,7 +12,7 @@ export default defineIntegration({ optionsSchema, setup({ name, options }) { // Declaration for Core DTS File - let coreDtsFile: string; + let coreDtsFile: InjectedType; return { hooks: { @@ -47,10 +48,7 @@ export default defineIntegration({ }, 'astro:config:done': async ({ injectTypes }) => { // Inject the DTS File - injectTypes({ - filename: 'core.d.ts', - content: coreDtsFile, - }); + injectTypes(coreDtsFile); }, }, }; diff --git a/packages/studiocms_core/src/stubs/dts.ts b/packages/studiocms_core/src/stubs/dts.ts index a6e191544..74568b79a 100644 --- a/packages/studiocms_core/src/stubs/dts.ts +++ b/packages/studiocms_core/src/stubs/dts.ts @@ -1,4 +1,4 @@ -import { fileFactory } from '@matthiesenxyz/integration-utils/fileFactory'; +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; /** * Generate a d.ts file for the StudioCMS Core Components and Helpers @@ -22,296 +22,289 @@ export const dtsFile = ( routemap: string; } ) => { - // Create a new file for the core.d.ts file - const DTSFile = fileFactory(); + const dtsFile = DTSBuilder(); - DTSFile.addLines('// This file is generated by StudioCMS\n\n'); - - // Start of the components module - DTSFile.addLines(`declare module 'studiocms:components' {`); - - // Add the Avatar component to the module - DTSFile.addLines(` - /** - * # Avatar Component used for the Navigation Component - * - * This component has no props and will render the current user avatar or a default avatar if no user is logged in based on the Astro.locals object - */ - export const Avatar: typeof import('${components.Avatar}').default`); - - // Add the FormattedDate component to the module - DTSFile.addLines(` - /** - * # Formatted Date Component used for rendering dates in a human readable format - * - * This components locale will adapt to the current configuration of the StudioCMS 'dateLocale' settings configuration option. - * - * @props {string(Date)} date - Date String - */ - export const FormattedDate: typeof import('${components.FormattedDate}').default;`); - - // Add the GenericHeader component to the module - DTSFile.addLines(` - /** - * # Generic Header Component - * - * Generic Header Component used for rendering a generic header with a title and description from StudioCMS - */ - export const Genericheader: typeof import('${components.Genericheader}').default;`); - - // Add the NavigationBar component to the module - DTSFile.addLines(` - /** - * # Navigation Component used for rendering StudioCMS User Facing Navigation - * - * This component is a helper component that will render the StudioCMS user facing navigation to assist in easy navigation of your built front-end site - * - * @props {topLevelLinkCount} number - Number of top level links to display before collapsing into a dropdown - * @props {hideAvatar} boolean - Hide the user avatar/Login button in the navigation bar - */ - export const Navigation: typeof import('${components.Navigation}').default;`); - - // End of the components module - DTSFile.addLines('}'); - - // Start of the helpers modules - DTSFile.addLines(`declare module 'studiocms:helpers' {`); - - // Add the urlGenFactory helper to the module - DTSFile.addLines(` - /** - * # URL Generation Helper Function - * - * @param {boolean} isDashboardRoute - Is this a dashboard route? - * @param {string} path - The path to generate the URL for - * @param {string} DashboardRoute - The dashboard route to use (Default: 'dashboard') - */ - export const urlGenFactory: typeof import('${helpers.urlGenFactory}').default;`); - - // Add the Path Generators helpers to the module - DTSFile.addLines(` - /** - * # pathWithBase Helper Function - * - * Get the a root-relative URL path with the site's 'base' prefixed. - */ - export const pathWithBase: typeof import('${helpers.pathGenerators}').pathWithBase;`); - - DTSFile.addLines(` - /** - * # fileWithBase Helper Function - * - * Get the a root-relative file URL path with the site's 'base' prefixed. - */ - export const fileWithBase: typeof import('${helpers.pathGenerators}').fileWithBase;`); - - // End of the helpers module - DTSFile.addLines('}'); - - // Add the ContentHelper module - DTSFile.addLines(`declare module 'studiocms:helpers/contentHelper' {`); - - // Main contentHelper function - DTSFile.addLines(` - /** - * # A helper function to get the content of a page by its slug. - * - * @param slug The slug of the page to get the content of. Defined in the PageData table. - * @param lang **Not implemented yet.** The language to get the content in. Default is 'default'. - * @param package **Not implemented yet.** The package to get the content from. Default is '@astrolicious/studiocms'. - * @returns The data and content of the page. - * - * @example - * --- - * // Get the content of the index page: - * import { StudioCMSRenderer, contentHelper } from 'studiocms:components' - * - * const { title, description, heroImage, content } = await contentHelper("index") - * --- - * - *

{title}

- *

{description}

- * {title} - * - * - */ - export const contentHelper: typeof import('${helpers.contentHelper}').contentHelper;`); - - // getSiteConfig function - DTSFile.addLines(` - /** - * # Site Configuration helper function to get the site configuration data from Astro Studio's Database. - * - * @returns The site configuration data. (Title, Description) - */ - export const getSiteConfig: typeof import('${helpers.contentHelper}').getSiteConfig;`); - - // getPageList function - DTSFile.addLines(` - /** - * # Get page list helper function to get a list of all pages from Astro Studio's database. - * - * @returns A Array of all pages in the database in ascending order of their published date. - */ - export const getPageList: typeof import('${helpers.contentHelper}').getPageList;`); - - // getUserList function - DTSFile.addLines(` - /** - * # Get user list helper function to get a list of all users from Astro Studio's Database. - * - * @returns A Array of all users in the database. - */ - export const getUserList: typeof import('${helpers.contentHelper}').getUserList;`); - - // getUserById function - DTSFile.addLines(` - /** - * # Get user by ID helper function to get a user by their ID from Astro Studio's Database. - * - * @param userId The ID of the user to get. You can get this from 'Astro.locals.dbUser.id' when StudioCMS Auth middleware is used. - * @returns The user data. - */ - export const getUserById: typeof import('${helpers.contentHelper}').getUserById;`); - - // ContentHelperTempResponse type - DTSFile.addLines(` - /** - * # Content Helper Temp Response Type - * - * type ContentHelperTempResponse = { - * id: string; - * package: string; - * title: string; - * description: string; - * publishedAt: Date; - * updatedAt: Date | null; - * slug: string; - * heroImage: string; - * content: string; - * } - */ - export type ContentHelperTempResponse = import('${helpers.contentHelper}').ContentHelperTempResponse;`); - - // SiteConfigResponse type - DTSFile.addLines(` - /** - * # Site Config Response Type - * - * type SiteConfigResponse = { - * title: string; - * id: number; - * description: string; - * } - */ - export type SiteConfigResponse = import('${helpers.contentHelper}').SiteConfigResponse;`); - - // pageDataReponse type - DTSFile.addLines(` - /** - * # Page Data Response Type - * - * type pageDataReponse = { - * title: string; - * id: string; - * package: string; - * description: string; - * showOnNav: boolean; - * publishedAt: Date; - * updatedAt: Date | null; - * slug: string; - * contentLang: string | null; - * heroImage: string; - * } - */ - export type pageDataReponse = import('${helpers.contentHelper}').pageDataReponse;`); - - // UserResponse type - DTSFile.addLines(` - /** - * # User Response Type - * - * type UserResponse = { - * id: string; - * name: string; - * username: string; - * url: string | null; - * email: string | null; - * avatar: string | null; - * githubId: number | null; - * githubURL: string | null; - * discordId: string | null; - * googleId: string | null; - * auth0Id: string | null; - * password: string | null; - * updatedAt: Date | null; - * createdAt: Date | null; - * } - */ - export type UserResponse = import('${helpers.contentHelper}').UserResponse;`); - - // End of the contentHelper module - DTSFile.addLines('}'); - - // Add the headDefaults module - DTSFile.addLines(`declare module 'studiocms:helpers/headDefaults' {`); - - // headDefaults function - DTSFile.addLines(` - /** - * # Default Head Configuration - * - * A helper function to get the default head configuration for a page. - */ - export const headDefaults: typeof import('${helpers.headDefaults}').headDefaults;`); - - // End of the headDefaults module - DTSFile.addLines('}'); - - // Add the routemap module - DTSFile.addLines(`declare module 'studiocms:helpers/routemap' {`); - - // getSluggedRoute function - DTSFile.addLines( - `export const getSluggedRoute: typeof import('${helpers.routemap}').getSluggedRoute;` - ); - - // getEditRoute function - DTSFile.addLines(`export const getEditRoute: typeof import('${helpers.routemap}').getEditRoute;`); - - // getDeleteRoute function - DTSFile.addLines( - `export const getDeleteRoute: typeof import('${helpers.routemap}').getDeleteRoute;` - ); - - // makeNonDashboardRoute function - DTSFile.addLines( - `export const makeNonDashboardRoute: typeof import('${helpers.routemap}').makeNonDashboardRoute;` - ); - - // makeDashboardRoute function - DTSFile.addLines( - `export const makeDashboardRoute: typeof import('${helpers.routemap}').makeDashboardRoute;` - ); - - // makeAPIDashboardRoute function - DTSFile.addLines( - `export const makeAPIDashboardRoute: typeof import('${helpers.routemap}').makeAPIDashboardRoute;` + dtsFile.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' ); - // StudioCMSRoutes - DTSFile.addLines( - `export const StudioCMSRoutes: typeof import('${helpers.routemap}').StudioCMSRoutes;` - ); - - // SideBarLinkMap - DTSFile.addLines( - `export const sideBarLinkMap: typeof import('${helpers.routemap}').sideBarLinkMap;` - ); - - // End of the routemap module - DTSFile.addLines('}'); - - // Return the DTS File - return DTSFile.text(); + dtsFile.addModule('studiocms:components', { + namedExports: [ + { + name: 'Avatar', + multiLineDescription: [ + '# Avatar Component used for the Navigation Component', + '', + 'This component has no props and will render the current user avatar or a default avatar if no user is logged in based on the Astro.locals object', + ], + typeDef: `typeof import('${components.Avatar}').default`, + }, + { + name: 'FormattedDate', + multiLineDescription: [ + '# Formatted Date Component used for rendering dates in a human readable format', + '', + "This components locale will adapt to the current configuration of the StudioCMS 'dateLocale' settings configuration option.", + '', + '@props {string(Date)} date - Date String', + ], + typeDef: `typeof import('${components.FormattedDate}').default`, + }, + { + name: 'Genericheader', + multiLineDescription: [ + '# Generic Header Component ', + '', + 'Generic Header Component used for rendering a generic header with a title and description from StudioCMS', + ], + typeDef: `typeof import('${components.Genericheader}').default`, + }, + { + name: 'Navigation', + multiLineDescription: [ + '# Navigation Component used for rendering StudioCMS User Facing Navigation', + '', + 'This component is a helper component that will render the StudioCMS user facing navigation to assist in easy navigation of your built front-end site', + '', + '@props {topLevelLinkCount} number - Number of top level links to display before collapsing into a dropdown', + '@props {hideAvatar} boolean - Hide the user avatar/Login button in the navigation bar', + ], + typeDef: `typeof import('${components.Navigation}').default`, + }, + ], + }); + + dtsFile.addModule('studiocms:helpers', { + namedExports: [ + { + name: 'urlGenFactory', + multiLineDescription: [ + '# URL Generation Helper Function', + '', + '@param {boolean} isDashboardRoute - Is this a dashboard route?', + '@param {string} path - The path to generate the URL for', + "@param {string} DashboardRoute - The dashboard route to use (Default: 'dashboard')", + ], + typeDef: `typeof import('${helpers.urlGenFactory}').default`, + }, + { + name: 'pathWithBase', + multiLineDescription: [ + '# pathWithBase Helper Function', + '', + "Get the a root-relative URL path with the site's 'base' prefixed.", + ], + typeDef: `typeof import('${helpers.pathGenerators}').pathWithBase`, + }, + { + name: 'fileWithBase', + multiLineDescription: [ + '# fileWithBase Helper Function', + '', + "Get the a root-relative file URL path with the site's 'base' prefixed.", + ], + typeDef: `typeof import('${helpers.pathGenerators}').fileWithBase`, + }, + ], + }); + + dtsFile.addModule('studiocms:helpers/contentHelper', { + namedExports: [ + { + name: 'contentHelper', + multiLineDescription: [ + '# A helper function to get the content of a page by its slug.', + '', + '@param slug The slug of the page to get the content of. Defined in the PageData table.', + "@param lang **Not implemented yet.** The language to get the content in. Default is 'default'.", + "@param package **Not implemented yet.** The package to get the content from. Default is '@astrolicious/studiocms'.", + '@returns The data and content of the page.', + '', + '@example', + '---', + '// Get the content of the index page:', + "import { StudioCMSRenderer, contentHelper } from 'studiocms:components'", + '', + 'const { title, description, heroImage, content } = await contentHelper("index")', + '---', + '', + '

{title}

', + '

{description}

', + '{title}', + '', + ], + typeDef: `typeof import('${helpers.contentHelper}').contentHelper`, + }, + { + name: 'getSiteConfig', + multiLineDescription: [ + "# Site Configuration helper function to get the site configuration data from Astro Studio's Database.", + '', + '@returns The site configuration data. (Title, Description)', + ], + typeDef: `typeof import('${helpers.contentHelper}').getSiteConfig`, + }, + { + name: 'getPageList', + multiLineDescription: [ + "# Get page list helper function to get a list of all pages from Astro Studio's database.", + '', + '@returns A Array of all pages in the database in ascending order of their published date.', + ], + typeDef: `typeof import('${helpers.contentHelper}').getPageList`, + }, + { + name: 'getUserList', + multiLineDescription: [ + "# Get user list helper function to get a list of all users from Astro Studio's Database.", + '', + '@returns A Array of all users in the database.', + ], + typeDef: `typeof import('${helpers.contentHelper}').getUserList`, + }, + { + name: 'getUserById', + multiLineDescription: [ + "# Get user by ID helper function to get a user by their ID from Astro Studio's Database.", + '', + "@param userId The ID of the user to get. You can get this from 'Astro.locals.dbUser.id' when StudioCMS Auth middleware is used.", + '@returns The user data.', + ], + typeDef: `typeof import('${helpers.contentHelper}').getUserById`, + }, + ], + typeExports: [ + { + name: 'ContentHelperTempResponse', + typeDef: `import('${helpers.contentHelper}').ContentHelperTempResponse`, + multiLineDescription: [ + '# Content Helper Temp Response Type', + '', + 'type ContentHelperTempResponse = {', + ' id: string;', + ' package: string;', + ' title: string;', + ' description: string;', + ' publishedAt: Date;', + ' updatedAt: Date | null;', + ' slug: string;', + ' heroImage: string;', + ' content: string;', + '}', + ], + }, + { + name: 'SiteConfigResponse', + typeDef: `import('${helpers.contentHelper}').SiteConfigResponse`, + multiLineDescription: [ + '# Site Config Response Type', + '', + 'type SiteConfigResponse = {', + ' title: string;', + ' id: number;', + ' description: string;', + '}', + ], + }, + { + name: 'pageDataReponse', + typeDef: `import('${helpers.contentHelper}').pageDataReponse`, + multiLineDescription: [ + '# Page Data Response Type', + '', + 'type pageDataReponse = {', + ' title: string;', + ' id: string;', + ' package: string;', + ' description: string;', + ' showOnNav: boolean;', + ' publishedAt: Date;', + ' updatedAt: Date | null;', + ' slug: string;', + ' contentLang: string | null;', + ' heroImage: string;', + '}', + ], + }, + { + name: 'UserResponse', + typeDef: `import('${helpers.contentHelper}').UserResponse`, + multiLineDescription: [ + '# User Response Type', + '', + 'type UserResponse = {', + ' id: string;', + ' name: string;', + ' username: string;', + ' url: string | null;', + ' email: string | null;', + ' avatar: string | null;', + ' githubId: number | null;', + ' githubURL: string | null;', + ' discordId: string | null;', + ' googleId: string | null;', + ' auth0Id: string | null;', + ' password: string | null;', + ' updatedAt: Date | null;', + ' createdAt: Date | null;', + '}', + ], + }, + ], + }); + + dtsFile.addModule('studiocms:helpers/headDefaults', { + namedExports: [ + { + name: 'headDefaults', + multiLineDescription: [ + '# Default Head Configuration', + '', + 'A helper function to get the default head configuration for a page.', + ], + typeDef: `typeof import('${helpers.headDefaults}').headDefaults`, + }, + ], + }); + + dtsFile.addModule('studiocms:helpers/routemap', { + namedExports: [ + { + name: 'getSluggedRoute', + typeDef: `typeof import('${helpers.routemap}').getSluggedRoute`, + }, + { + name: 'getEditRoute', + typeDef: `typeof import('${helpers.routemap}').getEditRoute`, + }, + { + name: 'getDeleteRoute', + typeDef: `typeof import('${helpers.routemap}').getDeleteRoute`, + }, + { + name: 'makeNonDashboardRoute', + typeDef: `typeof import('${helpers.routemap}').makeNonDashboardRoute`, + }, + { + name: 'makeDashboardRoute', + typeDef: `typeof import('${helpers.routemap}').makeDashboardRoute`, + }, + { + name: 'makeAPIDashboardRoute', + typeDef: `typeof import('${helpers.routemap}').makeAPIDashboardRoute`, + }, + { + name: 'StudioCMSRoutes', + typeDef: `typeof import('${helpers.routemap}').StudioCMSRoutes`, + }, + { + name: 'sideBarLinkMap', + typeDef: `typeof import('${helpers.routemap}').sideBarLinkMap`, + }, + ], + }); + + const dtsFileAstroInjected = dtsFile.makeAstroInjectedType('core.d.ts'); + + return dtsFileAstroInjected; }; diff --git a/packages/studiocms_dashboard/package.json b/packages/studiocms_dashboard/package.json index b91b87027..f96f38f25 100644 --- a/packages/studiocms_dashboard/package.json +++ b/packages/studiocms_dashboard/package.json @@ -37,6 +37,7 @@ "type": "module", "dependencies": { "@inox-tools/runtime-logger": "catalog:studiocms-shared", + "@matthiesenxyz/astrodtsbuilder": "catalog:studiocms-shared", "@matthiesenxyz/integration-utils": "catalog:studiocms-shared", "@matthiesenxyz/unocss-preset-daisyui": "catalog:studiocms-shared", "@matthiesenxyz/astrolace": "catalog:studiocms-shared", diff --git a/packages/studiocms_dashboard/src/integration.ts b/packages/studiocms_dashboard/src/integration.ts index 769b4f141..1d6a891b2 100644 --- a/packages/studiocms_dashboard/src/integration.ts +++ b/packages/studiocms_dashboard/src/integration.ts @@ -4,6 +4,7 @@ import { addIntegrationArray } from '@matthiesenxyz/integration-utils/aikUtils'; import { integrationLogger } from '@matthiesenxyz/integration-utils/astroUtils'; import { presetDaisy } from '@matthiesenxyz/unocss-preset-daisyui'; import { DashboardStrings, DbErrors } from '@studiocms/core/strings'; +import type { InjectedType } from 'astro'; import { createResolver, defineIntegration } from 'astro-integration-kit'; import { presetTypography, @@ -31,7 +32,7 @@ export default defineIntegration({ const { resolve } = createResolver(import.meta.url); // Declaration for Web Vitals DTS File - let WEBVITALSDTSFILE: string; + let WEBVITALSDTSFILE: InjectedType; return { hooks: { @@ -210,10 +211,7 @@ export default defineIntegration({ }, 'astro:config:done': async ({ injectTypes }) => { // Inject the Web Vitals DTS File - injectTypes({ - filename: 'web-vitals.d.ts', - content: WEBVITALSDTSFILE, - }); + injectTypes(WEBVITALSDTSFILE); }, 'astro:server:start': async ({ logger }) => { // Display Console Message if dbStartPage(First Time DB Initialization) is enabled diff --git a/packages/studiocms_dashboard/src/utils/checkForWebVitalsPlugin.ts b/packages/studiocms_dashboard/src/utils/checkForWebVitalsPlugin.ts index 91877dabe..ccd4090fe 100644 --- a/packages/studiocms_dashboard/src/utils/checkForWebVitalsPlugin.ts +++ b/packages/studiocms_dashboard/src/utils/checkForWebVitalsPlugin.ts @@ -1,5 +1,5 @@ +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; import { integrationLogger } from '@matthiesenxyz/integration-utils/astroUtils'; -import { fileFactory } from '@matthiesenxyz/integration-utils/fileFactory'; import { webVitalStrings } from '@studiocms/core/strings'; import { addVirtualImports, @@ -46,20 +46,34 @@ export const checkForWebVitals = defineUtility('astro:config:setup')( }, }); - // Create the Web Vitals DTS File - const webVitalDTS = fileFactory(); + const dtsFile = DTSBuilder(); - webVitalDTS.addLines('// This file is generated by StudioCMS\n\n'); - - webVitalDTS.addLines(`declare module 'studiocms-dashboard:web-vitals' { - /** Type Definitions for getWebVitals helper function */ - export type WebVitalsResponseItem = import('${resolve('./webVital.ts')}').WebVitalsResponseItem; + dtsFile.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' + ); - /** Get Web Vitals Helper function */ - export const getWebVitals: typeof import('${resolve('./webVital.ts')}').getWebVitals; - };`); + dtsFile.addModule('studiocms-dashboard:web-vitals', { + namedExports: [ + { + name: 'getWebVitals', + multiLineDescription: [ + '# Web Vitals Helper Function', + '', + '@returns Promise', + ], + typeDef: `typeof import('${resolve('./webVital.ts')}').getWebVitals`, + }, + ], + typeExports: [ + { + singleLineDescription: 'Web Vitals Response Item', + typeDef: `import('${resolve('./webVital.ts')}').WebVitalsResponseItem`, + name: 'WebVitalsResponseItem', + }, + ], + }); - const webVitalDtsFile = webVitalDTS.text(); + const webVitalDtsFile = dtsFile.makeAstroInjectedType('web-vitals.d.ts'); return { webVitalDtsFile }; } diff --git a/packages/studiocms_imagehandler/package.json b/packages/studiocms_imagehandler/package.json index 9e24ff1a5..48d9d09b3 100644 --- a/packages/studiocms_imagehandler/package.json +++ b/packages/studiocms_imagehandler/package.json @@ -35,6 +35,7 @@ "type": "module", "dependencies": { "@cloudinary/url-gen": "catalog:studiocms-imagehandler", + "@matthiesenxyz/astrodtsbuilder": "catalog:studiocms-shared", "@matthiesenxyz/integration-utils": "catalog:studiocms-shared", "@studiocms/core": "workspace:*", "@unpic/astro": "catalog:studiocms-imagehandler", diff --git a/packages/studiocms_imagehandler/src/componentResolver.ts b/packages/studiocms_imagehandler/src/componentResolver.ts index 59da993b0..29ae6b1cb 100644 --- a/packages/studiocms_imagehandler/src/componentResolver.ts +++ b/packages/studiocms_imagehandler/src/componentResolver.ts @@ -1,3 +1,4 @@ +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; import { fileFactory } from '@matthiesenxyz/integration-utils/fileFactory'; import { addVirtualImports, createResolver, defineUtility } from 'astro-integration-kit'; @@ -46,8 +47,37 @@ export const componentResolver = defineUtility('astro:config:setup')( export const CustomImage: typeof import('${customImageResolved}').default; }`); + const dtsFile = DTSBuilder(); + + dtsFile.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' + ); + + dtsFile.addModule('studiocms:imageHandler', { + namedExports: [ + { + name: 'CustomImage', + multiLineDescription: [ + '# Custom Image Component for StudioCMS:imageHandler', + '', + 'This component will adapt to the current configuration of the StudioCMS image handler and will render the used image accordingly.', + '', + 'The default configuration will use `@unpic/astro` to allow for image optimization and lazy loading from most popular image hosting services.', + '', + '@props {string} src - Image Source', + '@props {string} alt - Image Alt', + '@props {number} width - Image Width', + '@props {number} height - Image Height', + ], + typeDef: `typeof import('${customImageResolved}').default`, + }, + ], + }); + + const dtsFileAstro = dtsFile.makeAstroInjectedType('imageHandler.d.ts'); + return { - imageHandlerDtsFile: customImageDTS.text(), + imageHandlerDtsFile: dtsFileAstro, }; } ); diff --git a/packages/studiocms_imagehandler/src/integration.ts b/packages/studiocms_imagehandler/src/integration.ts index 0fc073adb..87a50fcfd 100644 --- a/packages/studiocms_imagehandler/src/integration.ts +++ b/packages/studiocms_imagehandler/src/integration.ts @@ -1,6 +1,7 @@ import { integrationLogger } from '@matthiesenxyz/integration-utils/astroUtils'; import { imageHandlerStrings } from '@studiocms/core/strings'; import { addAstroEnvConfig } from '@studiocms/core/utils'; +import type { InjectedType } from 'astro'; import { addIntegration, defineIntegration } from 'astro-integration-kit'; import { envField } from 'astro/config'; import { loadEnv } from 'vite'; @@ -23,7 +24,7 @@ export default defineIntegration({ const env = loadEnv('all', process.cwd(), 'CMS'); // Define the DTS File - let dtsFile: string; + let dtsFile: InjectedType; return { hooks: { @@ -138,10 +139,7 @@ export default defineIntegration({ } }, 'astro:config:done': ({ injectTypes }) => { - injectTypes({ - filename: 'imageHandler.d.ts', - content: dtsFile, - }); + injectTypes(dtsFile); }, }, }; diff --git a/packages/studiocms_renderers/package.json b/packages/studiocms_renderers/package.json index f761d6801..55771f302 100644 --- a/packages/studiocms_renderers/package.json +++ b/packages/studiocms_renderers/package.json @@ -40,6 +40,7 @@ "dependencies": { "@astrojs/markdown-remark": "catalog:", "@inox-tools/runtime-logger": "catalog:studiocms-shared", + "@matthiesenxyz/astrodtsbuilder": "catalog:studiocms-shared", "@matthiesenxyz/integration-utils": "catalog:studiocms-shared", "@markdoc/markdoc": "catalog:studiocms-shared", "@mdx-js/mdx": "catalog:studiocms-renderer", diff --git a/packages/studiocms_renderers/src/integration.ts b/packages/studiocms_renderers/src/integration.ts index 36b18788b..8c6bbdb63 100644 --- a/packages/studiocms_renderers/src/integration.ts +++ b/packages/studiocms_renderers/src/integration.ts @@ -43,22 +43,13 @@ export default defineIntegration({ }, 'astro:config:done': async ({ injectTypes }) => { // Inject Types for Renderer - injectTypes({ - filename: 'renderer.d.ts', - content: rendererDTS(RendererComponent), - }); + injectTypes(rendererDTS(RendererComponent)); // Inject Types for Renderer Config - injectTypes({ - filename: 'config.d.ts', - content: rendererConfigDTS(), - }); + injectTypes(rendererConfigDTS()); // Inject Types for Astro Markdown Config - injectTypes({ - filename: 'astroMarkdownConfig.d.ts', - content: rendererAstroMarkdownDTS(), - }); + injectTypes(rendererAstroMarkdownDTS()); }, }, }; diff --git a/packages/studiocms_renderers/src/stubs/renderer-config.ts b/packages/studiocms_renderers/src/stubs/renderer-config.ts index ffc563fdb..117ebd868 100644 --- a/packages/studiocms_renderers/src/stubs/renderer-config.ts +++ b/packages/studiocms_renderers/src/stubs/renderer-config.ts @@ -1,4 +1,4 @@ -import { fileFactory } from '@matthiesenxyz/integration-utils/fileFactory'; +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; import { createResolver } from 'astro-integration-kit'; // Create resolver relative to this file @@ -8,16 +8,20 @@ const { resolve } = createResolver(import.meta.url); * Generate the `config.d.ts` file */ export const rendererConfigDTS = () => { - const renderer = fileFactory(); + const dtsFile = DTSBuilder(); - renderer.addLines('// This file is generated by StudioCMS\n\n'); + dtsFile.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' + ); - renderer.addLines(`declare module 'studiocms:renderer/config' {`); - renderer.addLines(`const Config: import('${resolve('../index')}').StudioCMSRendererConfig;`); - renderer.addLines('export default Config;'); - renderer.addLines('}'); + dtsFile.addModule('studiocms:renderer/config', { + defaultExport: { + singleLineDescription: 'Renderer Configuration', + typeDef: `import('${resolve('../index')}').StudioCMSRendererConfig`, + }, + }); - const rendererDTS = renderer.text(); + const dtsText = dtsFile.makeAstroInjectedType('config.d.ts'); - return rendererDTS; + return dtsText; }; diff --git a/packages/studiocms_renderers/src/stubs/renderer-markdownConfig.ts b/packages/studiocms_renderers/src/stubs/renderer-markdownConfig.ts index 7921b209f..d57753d04 100644 --- a/packages/studiocms_renderers/src/stubs/renderer-markdownConfig.ts +++ b/packages/studiocms_renderers/src/stubs/renderer-markdownConfig.ts @@ -1,19 +1,21 @@ -import { fileFactory } from '@matthiesenxyz/integration-utils/fileFactory'; - +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; /** * Generate the `astroMarkdownConfig.d.ts` file */ export const rendererAstroMarkdownDTS = () => { - const renderer = fileFactory(); + const dtsFile = DTSBuilder(); - renderer.addLines('// This file is generated by StudioCMS\n\n'); + dtsFile.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' + ); - renderer.addLines(`declare module 'studiocms:renderer/astroMarkdownConfig' {`); - renderer.addLines(`const Config: import('astro').AstroConfig['markdown'];`); - renderer.addLines('export default Config;'); - renderer.addLines('}'); + dtsFile.addModule('studiocms:renderer/astroMarkdownConfig', { + defaultExport: { + typeDef: `import('astro').AstroConfig['markdown']`, + }, + }); - const rendererDTS = renderer.text(); + const dtsText = dtsFile.makeAstroInjectedType('astroMarkdownConfig.d.ts'); - return rendererDTS; + return dtsText; }; diff --git a/packages/studiocms_renderers/src/stubs/renderer.ts b/packages/studiocms_renderers/src/stubs/renderer.ts index f8fc5be1d..200f6c088 100644 --- a/packages/studiocms_renderers/src/stubs/renderer.ts +++ b/packages/studiocms_renderers/src/stubs/renderer.ts @@ -1,22 +1,26 @@ -import { fileFactory } from '@matthiesenxyz/integration-utils/fileFactory'; +import DTSBuilder from '@matthiesenxyz/astrodtsbuilder'; /** * Generate the `renderer.d.ts` file */ export const rendererDTS = (rendererPath: string) => { - const renderer = fileFactory(); + const dtsFile = DTSBuilder(); - renderer.addLines('// This file is generated by StudioCMS\n\n'); + dtsFile.addSingleLineNote( + 'This file is generated by StudioCMS and should not be modified manually.' + ); - renderer.addLines(`declare module 'studiocms:renderer' {`); - renderer.addLines(` - /** - * StudioCMS Content Renderer component - */ - export const StudioCMSRenderer: typeof import('${rendererPath}').default;`); - renderer.addLines('}'); + dtsFile.addModule('studiocms:renderer', { + namedExports: [ + { + name: 'StudioCMSRenderer', + multiLineDescription: ['# StudioCMS Content Renderer component'], + typeDef: `typeof import('${rendererPath}').default`, + }, + ], + }); - const rendererDTS = renderer.text(); + const dtsText = dtsFile.makeAstroInjectedType('renderer.d.ts'); - return rendererDTS; + return dtsText; }; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e7f5ab3d0..437070a7d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -173,6 +173,9 @@ catalogs: '@markdoc/markdoc': specifier: ^0.4.0 version: 0.4.0 + '@matthiesenxyz/astrodtsbuilder': + specifier: ^0.1.2 + version: 0.1.2 '@matthiesenxyz/astrolace': specifier: ^0.3.2 version: 0.3.2 @@ -414,6 +417,9 @@ importers: '@inox-tools/runtime-logger': specifier: catalog:studiocms-shared version: 0.3.1(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) + '@matthiesenxyz/astrodtsbuilder': + specifier: catalog:studiocms-shared + version: 0.1.2(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) '@matthiesenxyz/astrolace': specifier: catalog:studiocms-shared version: 0.3.2(@types/react@18.3.5)(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) @@ -507,6 +513,9 @@ importers: '@markdoc/markdoc': specifier: catalog:studiocms-shared version: 0.4.0(@types/react@18.3.5)(react@18.3.1) + '@matthiesenxyz/astrodtsbuilder': + specifier: catalog:studiocms-shared + version: 0.1.2(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) '@matthiesenxyz/astrolace': specifier: catalog:studiocms-shared version: 0.3.2(@types/react@18.3.5)(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) @@ -562,6 +571,9 @@ importers: '@inox-tools/runtime-logger': specifier: catalog:studiocms-shared version: 0.3.1(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) + '@matthiesenxyz/astrodtsbuilder': + specifier: catalog:studiocms-shared + version: 0.1.2(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) '@matthiesenxyz/astrolace': specifier: catalog:studiocms-shared version: 0.3.2(@types/react@18.3.5)(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) @@ -642,6 +654,9 @@ importers: '@cloudinary/url-gen': specifier: catalog:studiocms-imagehandler version: 1.19.0 + '@matthiesenxyz/astrodtsbuilder': + specifier: catalog:studiocms-shared + version: 0.1.2(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) '@matthiesenxyz/integration-utils': specifier: catalog:studiocms-shared version: 0.2.0(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) @@ -682,6 +697,9 @@ importers: '@markdoc/markdoc': specifier: catalog:studiocms-shared version: 0.4.0(@types/react@18.3.5)(react@18.3.1) + '@matthiesenxyz/astrodtsbuilder': + specifier: catalog:studiocms-shared + version: 0.1.2(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) '@matthiesenxyz/integration-utils': specifier: catalog:studiocms-shared version: 0.2.0(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4)) @@ -1994,6 +2012,11 @@ packages: react: optional: true + '@matthiesenxyz/astrodtsbuilder@0.1.2': + resolution: {integrity: sha512-Sy8R9Kd4WIsYrHm0D+uHMf/5QLyttMdJSVrR4wdXSjVExLC/k4myBUh2mHzUVKbfCvtgsVl/EUEYJiQYeWscIQ==} + peerDependencies: + astro: ^4.14 + '@matthiesenxyz/astrolace@0.3.2': resolution: {integrity: sha512-w1fO4FGxf6xB57otJS1JdsLe8xv1R9og3ci3dTE0Nm2NsoKvv96nqC6HRX7BOEAWNthoprvkD1k1VxHOGpz/nw==} peerDependencies: @@ -6853,6 +6876,10 @@ snapshots: '@types/react': 18.3.5 react: 18.3.1 + '@matthiesenxyz/astrodtsbuilder@0.1.2(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4))': + dependencies: + astro: 4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4) + '@matthiesenxyz/astrolace@0.3.2(@types/react@18.3.5)(astro@4.15.1(@types/node@22.0.0)(rollup@4.21.0)(typescript@5.5.4))': dependencies: '@shoelace-style/shoelace': 2.16.0(@types/react@18.3.5) diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 512130258..71688dec2 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -51,6 +51,7 @@ catalogs: studiocms-shared: '@inox-tools/runtime-logger': ^0.3.1 "@matthiesenxyz/astrolace": ^0.3.2 + "@matthiesenxyz/astrodtsbuilder": ^0.1.2 "@matthiesenxyz/integration-utils": ^0.2.0 '@matthiesenxyz/unocss-preset-daisyui': ^0.1.2 '@markdoc/markdoc': ^0.4.0