diff --git a/docs.users/README.md b/docs.users/README.md index a6d89cd..4e92940 100644 --- a/docs.users/README.md +++ b/docs.users/README.md @@ -13,9 +13,80 @@ User installation and setup instructions can in the [root README.md](https://git ### Technical documentation +- **`blocksTerminalLogger` (Utility & Interface)** + + A specialized terminal logging utility for the `@build-in-blocks` ecosystem. It provides standardized error formatting, separates internal framework issues from user application errors, and can provide contextual suggestions before optionally terminating the process. + + **Syntax** + + ```` + blocksTerminalLogger({ ...options }); + ```` + + **Interface definition** + + ```` + export interface BlocksTerminalLogger { + internalPackage?: { + fullName?: string; + errorMessage?: string; + }; + userApp?: { + fullName?: string; + errorMessage?: string; + }; + errorSource?: boolean; + suggestion?: { + blocksConfig?: { + showCurrentState?: boolean; + referenceMessage?: string; + }; + messageList?: string[]; + }; + originalErrorMessage?: Error; + processExit?: boolean; + } + ```` + + **Parameters / Properties** + + |Property | Type| Required| Description| + |:-- |:-- |:-- |:-- | + |`internalPackage` |`object` |No |Has optional properties `fullName` and `errorMessage`, useful for logging a custom internal framework error.| + |`userApp` |`object` |No |Has optional properties `fullName` and `errorMessage`, useful for logging a custom message for a blocks web app.| + |`errorSource` |`boolean` |No |If `true`, explicitly prints the source of the error pointing to the internal package.| + |`suggestion` |`object` |No |Provides info helpful for troubleshooting. Has optional properties: `messageList` of strings to be printed as individual lines (and `blocksConfig` which is for helping users to track the state of their wep app's blocks config file).| + |`originalErrorMessage` |`Error` |No |Prints the raw JavaScript Error object/stack trace for deep debugging.| + |`processExit` |`boolean` |No |If `true`, executes `process.exit(1)` immediately after logging.| + + **Usage Example** + + ```` + import { blocksTerminalLogger } from '@build-in-blocks/dev.resources'; + try { + // Some internal logic... + } catch (err) { + blocksTerminalLogger({ + userApp: { + fullName: 'my-web-app', + errorMessage: 'Could not find the entry file "main.ts".' + }, + suggestion: { + messageList: [ + 'Ensure "main.ts" exists in your src folder.', + 'Update your BlocksConfig to match your file name.' + ] + }, + processExit: true // Stops the build process + }); + } + ```` + + # + - **`BlocksConfig` (Interface)** - The `BlocksConfig` interface defines the structure for a app's **@build-in-blocks** configuration object. It also allows developers to override default build behaviors, specifically for development environments. + The `BlocksConfig` interface defines the structure for a web app or web lobrary's **@build-in-blocks** configuration object. It also allows developers to override default build behaviors, specifically for development environments. **Definition** @@ -24,6 +95,10 @@ User installation and setup instructions can in the [root README.md](https://git devBuild?: { srcCodeFolder?: string; entryFileName?: string; + devServer?: { + port?: number; + open?: boolean; + }; }; } ```` @@ -32,9 +107,12 @@ User installation and setup instructions can in the [root README.md](https://git |Property | Type| Required| Description| |:-- |:-- |:-- |:-- | - |`devBuild` |`object` |No |A nested object containing settings specific to the development build process. | - |`devBuild.srcCodeFolder` |`string` |No |The path to the source directory. Overrides the default `'src'`. | - |`devBuild.entryFileName` |`string` |No | The name of the main entry file (without extension). Overrides the default `'index'`.| + |`devBuild` |`object` |No |Settings for the development build process.| + |`devBuild.srcCodeFolder` |`string` |No |The path to the source directory. Overrides the default 'src'.| + |`devBuild.entryFileName` |`string` |No |The name of the main entry file (without extension). Overrides the default 'index'.| + |`devBuild.devServer` |`object` |No |Configuration for the local development server.| + |`devBuild.devServer.port` |`number` |No |The port the dev server should run on. Overrides the default `3000`.| + |`devBuild.devServer.open` |`boolean` |No |Whether to automatically open the browser on start. Set to `true`, to override the default.| **Usage Example** @@ -48,8 +126,12 @@ User installation and setup instructions can in the [root README.md](https://git const myConfig: BlocksConfig = { devBuild: { srcCodeFolder: 'app', - entryFileName: 'main' - } + entryFileName: 'main', + devServer: { + port: 5800, + open: true, + }, + }, }; ```` diff --git a/src/shared/index.ts b/src/shared/index.ts index d74ff20..673046b 100644 --- a/src/shared/index.ts +++ b/src/shared/index.ts @@ -1,3 +1,4 @@ +export * from './node.blocks-terminal-logger'; export * from './node.file-system'; export * from './web.blocks-app'; export * from './types'; diff --git a/src/shared/node.blocks-terminal-logger.ts b/src/shared/node.blocks-terminal-logger.ts new file mode 100644 index 0000000..b243768 --- /dev/null +++ b/src/shared/node.blocks-terminal-logger.ts @@ -0,0 +1,74 @@ +import { BlocksTerminalLogger } from './types/node.blocks-logger.types'; + +export const blocksTerminalLogger = ({ internalPackage, userApp, errorSource, suggestion, originalErrorMessage, processExit }: BlocksTerminalLogger) => { + //- + const messageListDisplay = ({ noNewLineAtEnd }: { noNewLineAtEnd?: boolean }) => { + //- + const messageList = suggestion?.messageList; + if (!messageList) return; + //- + messageList.forEach((message, index) => { + const isLastMessage = index === messageList.length - 1; + const isAppendNewLineRequested = isLastMessage && !noNewLineAtEnd; + console.error(`${message}${isAppendNewLineRequested ? '\n' : ''}`); + }); + }; + //- + try { + const isInternalPackageErrorRequested = internalPackage?.fullName && internalPackage.errorMessage; + const isUserAppErrorRequested = userApp?.fullName && userApp.errorMessage; + const isSuggestionRequested = suggestion?.messageList?.length; + //- + const internalPackageNameText = `${internalPackage?.fullName} (internal)`; + const suggestionSectionTitle = `Suggestion${suggestion?.blocksConfig?.showCurrentState ? ' (based on current state)' : ''}:`; + //- + if (isInternalPackageErrorRequested) { + console.error('--------------------------'); + console.error('ERROR |', `${internalPackageNameText}:`); + console.error('Type generation failed.'); + } + //- + if (isUserAppErrorRequested) { + console.error('--------------------------'); + console.error('ERROR |', `${userApp?.fullName} (your app):`); + console.error(userApp.errorMessage); + } + //- + if (errorSource) { + console.error('--------------------------'); + console.error(`ERROR SOURCE => ${internalPackageNameText}`); + } + //- + if (isSuggestionRequested && !suggestion?.blocksConfig?.showCurrentState) { + console.error('--------------------------'); + console.error(suggestionSectionTitle); + messageListDisplay({}); + } + //- + if (isSuggestionRequested && suggestion?.blocksConfig?.showCurrentState) { + console.error('--------------------------'); + console.error(`Your blocks config current state:`); + console.error(suggestion?.blocksConfig.referenceMessage); + console.error('--------------------------'); + console.error(suggestionSectionTitle); + messageListDisplay({ + noNewLineAtEnd: true, + }); + } + //- + if (originalErrorMessage) { + console.error('--------------------------'); + console.error('ORIGINAL ERROR:\n', originalErrorMessage); + } + } catch (error) { + console.error('--------------------------'); + console.error('ERROR |', `@build-in-blocks/dev.resources (internal):`); + console.error('Error log failed.'); + console.error('--------------------------'); + console.error('ORIGINAL ERROR:\n', error); + } + //- + if (processExit) { + process.exit(1); + } +}; diff --git a/src/shared/types/index.ts b/src/shared/types/index.ts index d76edd9..8c084eb 100644 --- a/src/shared/types/index.ts +++ b/src/shared/types/index.ts @@ -1 +1,2 @@ +export * from './node.blocks-logger.types'; export * from './web.blocks-app.types'; diff --git a/src/shared/types/node.blocks-logger.types.ts b/src/shared/types/node.blocks-logger.types.ts new file mode 100644 index 0000000..56b5233 --- /dev/null +++ b/src/shared/types/node.blocks-logger.types.ts @@ -0,0 +1,20 @@ +export interface BlocksTerminalLogger { + internalPackage?: { + fullName?: string; + errorMessage?: string; + }; + userApp?: { + fullName?: string; + errorMessage?: string; + }; + errorSource?: boolean; + suggestion?: { + blocksConfig?: { + showCurrentState?: boolean; + referenceMessage?: string; + }; + messageList?: string[]; + }; + originalErrorMessage?: Error; // TODO: Check that this error type is correct later + processExit?: boolean; +} diff --git a/src/shared/types/web.blocks-app.types.ts b/src/shared/types/web.blocks-app.types.ts index cb8c780..5a2aca0 100644 --- a/src/shared/types/web.blocks-app.types.ts +++ b/src/shared/types/web.blocks-app.types.ts @@ -2,5 +2,9 @@ export interface BlocksConfig { devBuild?: { srcCodeFolder?: string; entryFileName?: string; + devServer?: { + port?: number; + open?: boolean; + }; }; } diff --git a/tsconfig.json b/tsconfig.json index d9d2248..64b6212 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,14 +1,16 @@ { "compilerOptions": { "target": "es2016", - "module": "commonjs", - "moduleResolution": "node", - "declaration": true, + "module": "Node16", + "moduleResolution": "node16", + "declaration": true, "outDir": "./build", + "rootDir": "./src", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true, "noImplicitAny": true, + "types": ["node"], }, "include": ["src/**/*", "**/*.ts"], "exclude": ["node_modules", "build"]