From 45ebefef0a1c08085af35c215305ef4237dbe3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Lenon?= Date: Wed, 16 Aug 2023 15:16:00 -0300 Subject: [PATCH 1/2] fix(css): paint code links different --- docs/getting-started/configuration.mdx | 6 +- docs/rest-api-application/rate-limiting.mdx | 2 +- .../security-with-helmet.mdx | 2 +- .../swagger-documentation.mdx | 2 +- .../rest-api-application/tracing-requests.mdx | 2 +- docs/the-basics/helpers.mdx | 310 +++++++++++++++++- static/css/markdown.css | 16 +- 7 files changed, 325 insertions(+), 15 deletions(-) diff --git a/docs/getting-started/configuration.mdx b/docs/getting-started/configuration.mdx index 225beb33..249d76e1 100644 --- a/docs/getting-started/configuration.mdx +++ b/docs/getting-started/configuration.mdx @@ -478,7 +478,7 @@ await Config.loadAll(Path.stubs('config')) If you are using the [slim](https://athenna.io/docs/getting-started/installation#project-structure) project structure, or you are building your own project -structure, you are not going to have the config directory +structure, you are not going to have the `config` directory in your project root path. You will have two options now: @@ -493,7 +493,7 @@ The [slim](https://athenna.io/docs/getting-started/installation#project-structur project structure is using the second option above to specify to Athenna that the configuration files will be inside of `src/config` directory. Check the examples -above how this implementation works. +bellow to see how this implementation works. ::: @@ -505,7 +505,7 @@ defined. The `directories` property is an object that maps the directory base path that the [`Path`](https://athenna.io/docs/digging-deeper/helpers#path) -class will use to resolve your application paths: +helper will use to resolve your application paths: ```typescript import { Path } from '@athenna/common' diff --git a/docs/rest-api-application/rate-limiting.mdx b/docs/rest-api-application/rate-limiting.mdx index db04ac0c..53630aa4 100644 --- a/docs/rest-api-application/rate-limiting.mdx +++ b/docs/rest-api-application/rate-limiting.mdx @@ -1,6 +1,6 @@ --- title: Rate Limiting -sidebar_position: 7 +sidebar_position: 6 description: See how to create rate limiting rules for Athenna REST API application. tags: - REST API Application diff --git a/docs/rest-api-application/security-with-helmet.mdx b/docs/rest-api-application/security-with-helmet.mdx index 9892d178..3fd8e0a8 100644 --- a/docs/rest-api-application/security-with-helmet.mdx +++ b/docs/rest-api-application/security-with-helmet.mdx @@ -1,6 +1,6 @@ --- title: Security with Helmet -sidebar_position: 9 +sidebar_position: 8 description: See how to improve the security of your REST API with Helmet in Athenna. tags: - REST API Application diff --git a/docs/rest-api-application/swagger-documentation.mdx b/docs/rest-api-application/swagger-documentation.mdx index abc501e9..09706051 100644 --- a/docs/rest-api-application/swagger-documentation.mdx +++ b/docs/rest-api-application/swagger-documentation.mdx @@ -1,6 +1,6 @@ --- title: Swagger Documentation -sidebar_position: 6 +sidebar_position: 9 description: See how to create the Swagger documentation for Athenna REST API application. tags: - REST API Application diff --git a/docs/rest-api-application/tracing-requests.mdx b/docs/rest-api-application/tracing-requests.mdx index fd704b61..98498aea 100644 --- a/docs/rest-api-application/tracing-requests.mdx +++ b/docs/rest-api-application/tracing-requests.mdx @@ -1,6 +1,6 @@ --- title: Tracing Requests -sidebar_position: 8 +sidebar_position: 7 description: Understand how to trace requests in your REST API application of Athenna. tags: - REST API Application diff --git a/docs/the-basics/helpers.mdx b/docs/the-basics/helpers.mdx index 5861eda8..38d3441d 100644 --- a/docs/the-basics/helpers.mdx +++ b/docs/the-basics/helpers.mdx @@ -28,8 +28,6 @@ delete and get information about folders. ### `File` -Use the `File` class to create an instance of a file, it existing or not. - #### `File.load()` & `File.loadSync()` Creates the file is does not exist and also load the file information: @@ -339,4 +337,310 @@ const file = await File.createFileOfSize('fake.js', 1024 * 1024 * 100) 👈 ### `Folder` -Coming soon +#### `Folder.load()` & `Folder.loadSync()` + +Creates the folder if it does not exist and also load the folder information: + +```typescript +import { Folder } from '@athenna/common' + +const existent = new Folder(Path.storage('existent')) +const nonExistent = new Folder('./nonExistent') + +// Load the folder info with sub folders and with file contents. +await existent.load({ withSub: true, withContent: true }) 👈 + +// Create and load the folder info without the +// content (be careful when loading big files). +nonExistent.loadSync() 👈 +``` + +After loading process, the folder will contain new informations: + +- createdAt - The date when the folder was created. +- accessedAt - The date when the folder was last accessed. +- modifiedAt - The date when the folder was last modified. +- folderSize - The size of the folder in MB. + +#### `Folder.copy()` & `Folder.copySync()` + +Create a copy of the folder in other location or with other name: + +```typescript +import { Folder } from '@athenna/common' + +const copiedFolder = folder.copySync('./copy-of-folder') +const copiedFolder = await folder.copy(Path.storage('copy-of-folder')) +``` + +To copy the folder and load the sub folders and the content of the +copy set the `withSub` and `withContent` as `true`: + +```typescript +import { Folder } from '@athenna/common' + +const copiedFolder = await folder.copy(Path.storage('copy-of-folder'), { + withSub: true, 👈 + withContent: true 👈 +}) +``` + +When copying the folder you can set the `mockedValues` to `true` to copy the +files with fake names: + +```typescript +import { Folder } from '@athenna/common' + +const copiedFolder = await folder.copy(Path.storage('copy-of-file'), { + mockedValues: true 👈 +}) +``` + +#### `Folder.move()` & `Folder.moveSync()` + +Move the folder to other location: + +```typescript +import { Folder } from '@athenna/common' + +const movedFolder = folder.moveSync('./move-of-folder') 👈 +const movedFolder = await folder.move(Path.storage('move-of-folder')) 👈 +``` + +To move the folder and load the sub folders and the content of the +move set the `withSub` and `withContent` as `true`: + +```typescript +import { Folder } from '@athenna/common' + +const movedFolder = await folder.move(Path.storage('move-of-folder'), { + withSub: true, 👈 + withContent: true 👈 +}) +``` + +When moving the folder you can set the `mockedValues` to `true` to move the +files with fake names: + +```typescript +import { Folder } from '@athenna/common' + +const movedFolder = await folder.move(Path.storage('file-path'), { + mockedValues: true 👈 +}) +``` + +#### `Folder.remove()` & `Folder.removeSync()` + +Delete a folder from the folder system: + +```typescript +import { Folder } from '@athenna/common' + +folder.removeSync() 👈 +await folder.remove() 👈 +``` + +#### `Folder.setContent()` & `Folder.setContentSync()` + +Set the content of a folder overwriting the existing content: + +```typescript +import { Folder } from '@athenna/common' + +const folder = new Folder('./file') + +file.setContentSync('Hello World!') 👈 +await file.setContent('Hello World!') 👈 +``` + +#### `File.getContent()` & `File.getContentSync()` + +Get the content of a file as `Buffer`: + +```typescript +import { File } from '@athenna/common' + +const contentBuffer = file.getContentSync() 👈 +const contentBuffer = await file.getContent() 👈 +``` + +To save the content of the file in the instance set the `saveContent` as `true`: + +```typescript +import { File } from '@athenna/common' + +const content = await file.getContent({ saveContent: true }) 👈 +``` + +#### `File.getContentAsString()` & `File.getContentAsStringSync()` + +Same behavior of `getContent()`/`getContentSync()`, but return the content +as `string`: + +```typescript +import { File } from '@athenna/common' + +const contentString = file.getContentAsStringSync() 👈 +const contentString = await file.getContentAsString() 👈 +``` + +#### `File.getContentAsJson()` & `File.getContentAsJsonSync()` + +Same behavior of `getContent()`/`getContentSync()`, but return the content as +`object` if the content is a valid JSON string: + +```typescript +import { File } from '@athenna/common' + +const contentJSON = file.getContentAsJsonSync() 👈 +const contentJSON = await file.getContentAsJson() 👈 +``` + +#### `File.getContentAsBuilder()` & `File.getContentAsBuilderSync()` + +Same behavior of `getContent()`/`getContentSync()`, but return the content as +an [`ObjectBuilder`](/docs/the-basics/helpers#object-builder) instance if the +content is a valid JSON string: + +```typescript +import { File } from '@athenna/common' + +const contentObjectBuilder = file.getContentAsBuilderSync() 👈 +const contentObjectBuilder = await file.getContentAsBuilder() 👈 +``` + +#### `File.append()` & `File.appendSync()` + +Add content to the end of the file: + +```typescript +import { File } from '@athenna/common' + +const file = new File('./file.txt', 'Hello') + +file.appendSync(' World') 👈 +await file.append('!\n') 👈 +``` + +#### `File.prepend()` & `File.prependSync()` + +Add content to the top of the file: + +```typescript +import { File } from '@athenna/common' + +const file = new File('./file.txt', 'World') + +file.prependSync('ello ') 👈 +await file.prepend('H') 👈 +``` + +#### `File.createReadStream()` + +Create a [readable stream](https://nodejs.org/api/stream.html#readable-streams) +instance of the file: + +```typescript +const stream = file.createReadStream() +``` + +#### `File.createWriteStream()` + +Create a [writable stream](https://nodejs.org/api/stream.html#writable-streams) +instance of the file: + +```typescript +const stream = file.createWriteStream() +``` + +#### `File.toJSON()` + +Get the informations of the file as JSON: + +```typescript +const infos = file.toJSON() 👈 +``` + +#### `File.import()` + +Import the file path if is a valid module: + +```typescript +import { File } from '@athenna/common' + +const file = new File('./file.js', "console.log('hello')") + +const module = await file.import() 👈 +``` + +#### `File.safeImport()` + +Same as `import()` method, but if the file is not a valid module the exception +will be ignored: + +```typescript +import { File } from '@athenna/common' + +const file = new File('./file.txt', "console.log('hello')") + +const module = await file.safeImport() 👈 +``` + +Importing files that got any errors like syntax errors will also not throw: + +```typescript +import { File } from '@athenna/common' + +const file = new File('./file.js', "console.log('hello") + +const module = await file.safeImport() 👈 // Nothing happens +``` + +#### `File::safeRemove()` + +Call for a delete operation without worrying about exceptions because the file +does not exist: + +```typescript +import { File } from '@athenna/common' + +await File.safeRemove(Path.storage('file.txt')) 👈 +await File.safeRemove(Path.storage('not-found.txt')) 👈 // Will not throw +``` + +#### `File::exists()` & `File::existsSync()` + +Verify if a file exists or not: + +```typescript +if (File.existsSync('package.json')) { + // do something +} + +if (await File.exists('package.json')) { + // do something +} +``` + +#### `File::isFile()` & `File::isFileSync()` + +Verify if a file is a valid file or not: + +```typescript +if (File.isFileSync('package.json')) { + // do something +} + +if (await File.isFile('package.json')) { + // do something +} +``` + +#### `File::createFileOfSize()` + +Create a fake file with determined size for testing purposes: + +```typescript +const file = await File.createFileOfSize('fake.js', 1024 * 1024 * 100) 👈 +``` diff --git a/static/css/markdown.css b/static/css/markdown.css index 446c6f72..9dc71d9d 100644 --- a/static/css/markdown.css +++ b/static/css/markdown.css @@ -1,25 +1,31 @@ .markdown code { - color: #ff80bf !important; + color: #ff80bf; } .markdown a { color: #939300 !important; } +a code { + color: #939300 !important; +} + .markdown a:hover { - color: #ff80bf !important; + color: #ff80bf; } [data-theme='dark'] .markdown a { color: #ffff80 !important; } +[data-theme='dark'] a code { + color: #ffff80 !important; +} + [data-theme='dark'] .markdown a:hover { - color: #ff80bf !important; + color: #ff80bf; } .markdown h1, .markdown h2, .markdown h3, .markdown h4, .markdown h5, .markdown h6 { font-weight: 800 !important; } - - From 121351e9db90a6329bc8de452e2011cc552463ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Lenon?= Date: Wed, 16 Aug 2023 15:33:49 -0300 Subject: [PATCH 2/2] feat(docs): add more helpers descriptions --- docs/the-basics/helpers.mdx | 212 ++++++++++-------------------------- 1 file changed, 55 insertions(+), 157 deletions(-) diff --git a/docs/the-basics/helpers.mdx b/docs/the-basics/helpers.mdx index 38d3441d..587cf2eb 100644 --- a/docs/the-basics/helpers.mdx +++ b/docs/the-basics/helpers.mdx @@ -21,11 +21,35 @@ them in your own applications if you find them convenient. ## Available helpers +- [`Clean`](/docs/the-basics/helpers#clean) - Remove falsy values +from different data structures. +- [`Color`](/docs/the-basics/helpers#color) - The UI Kit of Athenna +command line applications. +- [`Exec`](/docs/the-basics/helpers#exec) - Simple helpers that executes +some operation, like executing a command in a child process. +- [`FakeApi`](/docs/the-basics/helpers#fakeapi) - Create a fake REST API +using `json` files to map the routes and their returns (similiar to [WireMock](https://wiremock.org/)). - [`File`](/docs/the-basics/helpers#file) - Create, copy, move, delete and get information about files. - [`Folder`](/docs/the-basics/helpers#folder) - Create, copy, move, delete and get information about folders. +### `Clean` + +Coming soon + +### `Color` + +Coming soon + +### `Exec` + +Coming soon + +### `FakeApi` + +Coming soon + ### `File` #### `File.load()` & `File.loadSync()` @@ -441,206 +465,80 @@ folder.removeSync() 👈 await folder.remove() 👈 ``` -#### `Folder.setContent()` & `Folder.setContentSync()` - -Set the content of a folder overwriting the existing content: - -```typescript -import { Folder } from '@athenna/common' - -const folder = new Folder('./file') - -file.setContentSync('Hello World!') 👈 -await file.setContent('Hello World!') 👈 -``` - -#### `File.getContent()` & `File.getContentSync()` - -Get the content of a file as `Buffer`: - -```typescript -import { File } from '@athenna/common' - -const contentBuffer = file.getContentSync() 👈 -const contentBuffer = await file.getContent() 👈 -``` - -To save the content of the file in the instance set the `saveContent` as `true`: - -```typescript -import { File } from '@athenna/common' - -const content = await file.getContent({ saveContent: true }) 👈 -``` - -#### `File.getContentAsString()` & `File.getContentAsStringSync()` - -Same behavior of `getContent()`/`getContentSync()`, but return the content -as `string`: - -```typescript -import { File } from '@athenna/common' - -const contentString = file.getContentAsStringSync() 👈 -const contentString = await file.getContentAsString() 👈 -``` - -#### `File.getContentAsJson()` & `File.getContentAsJsonSync()` - -Same behavior of `getContent()`/`getContentSync()`, but return the content as -`object` if the content is a valid JSON string: - -```typescript -import { File } from '@athenna/common' - -const contentJSON = file.getContentAsJsonSync() 👈 -const contentJSON = await file.getContentAsJson() 👈 -``` - -#### `File.getContentAsBuilder()` & `File.getContentAsBuilderSync()` - -Same behavior of `getContent()`/`getContentSync()`, but return the content as -an [`ObjectBuilder`](/docs/the-basics/helpers#object-builder) instance if the -content is a valid JSON string: - -```typescript -import { File } from '@athenna/common' - -const contentObjectBuilder = file.getContentAsBuilderSync() 👈 -const contentObjectBuilder = await file.getContentAsBuilder() 👈 -``` - -#### `File.append()` & `File.appendSync()` - -Add content to the end of the file: - -```typescript -import { File } from '@athenna/common' - -const file = new File('./file.txt', 'Hello') - -file.appendSync(' World') 👈 -await file.append('!\n') 👈 -``` - -#### `File.prepend()` & `File.prependSync()` - -Add content to the top of the file: - -```typescript -import { File } from '@athenna/common' - -const file = new File('./file.txt', 'World') - -file.prependSync('ello ') 👈 -await file.prepend('H') 👈 -``` - -#### `File.createReadStream()` - -Create a [readable stream](https://nodejs.org/api/stream.html#readable-streams) -instance of the file: - -```typescript -const stream = file.createReadStream() -``` - -#### `File.createWriteStream()` +#### `Folder.toJSON()` -Create a [writable stream](https://nodejs.org/api/stream.html#writable-streams) -instance of the file: +Get the informations of the folder as JSON: ```typescript -const stream = file.createWriteStream() +const infos = folder.toJSON() 👈 ``` -#### `File.toJSON()` +#### `Folder.getFilesByPattern()` -Get the informations of the file as JSON: +Get all the files of a folder using a glob pattern: ```typescript -const infos = file.toJSON() 👈 -``` - -#### `File.import()` - -Import the file path if is a valid module: - -```typescript -import { File } from '@athenna/common' - -const file = new File('./file.js', "console.log('hello')") - -const module = await file.import() 👈 +const files = folder.getFilesByPattern('**/*.js') 👈 ``` -#### `File.safeImport()` +#### `Folder.getFoldersByPattern()` -Same as `import()` method, but if the file is not a valid module the exception -will be ignored: +Get all the folders of a folder using a glob pattern: ```typescript -import { File } from '@athenna/common' - -const file = new File('./file.txt', "console.log('hello')") - -const module = await file.safeImport() 👈 +const folders = folder.getFoldersByPattern('**/*') 👈 ``` -Importing files that got any errors like syntax errors will also not throw: - -```typescript -import { File } from '@athenna/common' - -const file = new File('./file.js', "console.log('hello") - -const module = await file.safeImport() 👈 // Nothing happens -``` - -#### `File::safeRemove()` +#### `Folder::safeRemove()` -Call for a delete operation without worrying about exceptions because the file +Call for a delete operation without worrying about exceptions because the folder does not exist: ```typescript -import { File } from '@athenna/common' +import { Folder } from '@athenna/common' -await File.safeRemove(Path.storage('file.txt')) 👈 -await File.safeRemove(Path.storage('not-found.txt')) 👈 // Will not throw +await Folder.safeRemove(Path.storage('folder')) 👈 +await Folder.safeRemove(Path.storage('not-found')) 👈 // Will not throw ``` -#### `File::exists()` & `File::existsSync()` +#### `Folder::exists()` & `Folder::existsSync()` -Verify if a file exists or not: +Verify if a folder exists or not: ```typescript -if (File.existsSync('package.json')) { +if (Folder.existsSync('app')) { // do something } -if (await File.exists('package.json')) { +if (await Folder.exists('app')) { // do something } ``` -#### `File::isFile()` & `File::isFileSync()` +#### `Folder::isFolder()` & `Folder::isFolderSync()` -Verify if a file is a valid file or not: +Verify if a folder is a valid folder or not: ```typescript -if (File.isFileSync('package.json')) { +if (Folder.isFolderSync('app')) { // do something } -if (await File.isFile('package.json')) { +if (await Folder.isFolder('app')) { // do something } ``` -#### `File::createFileOfSize()` +#### `Folder::size()` & `Folder::sizeSync()` -Create a fake file with determined size for testing purposes: +Get the size of the folder in MB: ```typescript -const file = await File.createFileOfSize('fake.js', 1024 * 1024 * 100) 👈 +if (Folder.sizeSync('app') === 100) { + // do something +} + +if (await Folder.size('app') === 100) { + // do something +} ```