From 3f6eeaa7ad5f846592f98a8d2af7e5d0a01a906a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Morel=20Se=CC=81bastien?= Date: Thu, 13 Feb 2025 15:53:23 -0800 Subject: [PATCH] feat(cli): documentation --- CHANGELOG.md | 6 + README.md | 187 ++++++++++++++++++++++++++++++- package.json | 2 +- src/command/doc.ts | 18 +++ src/content/completion_file.bash | 2 +- src/core/di.ts | 4 + 6 files changed, 211 insertions(+), 8 deletions(-) create mode 100644 src/command/doc.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 4eeebb5..971e463 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ All notable changes to this project will be documented in this file. +## [5.4.3] + +- fix the completion file +- add documentation +- add doc command + ## [5.4.2] - add the Furnitut boilerplate diff --git a/README.md b/README.md index 7c57a3a..558ccb2 100644 --- a/README.md +++ b/README.md @@ -1,17 +1,192 @@ # Crystallize CLI ---- +The ultimate CLI for managing your Crystallize project. -This repository is what we call a "subtree split": a read-only copy of one directory of the main repository. +## Context -If you want to report or contribute, you should do it on the main repository: https://github.com/CrystallizeAPI/tools +This new version is fully written in Bun and can be installed in a much more standard way. The CLI is built for the future of Crystallize, whether you're using it locally to enhance your Developer Experience or within your CI/CD pipelines to automate tasks. ---- +> **Fun fact:** You don't even need Node or Bun to run it—it's pre-compiled with everything included. -## Install the CLI +### Replacing Legacy CLIs + +Two older CLIs—`@crystallize/cli` and `@crystallize/cli-next`—are now deprecated. These were available on NPM and installable via `npx` (or similar), and while they still function, they are now primarily used for installing legacy templates. + +## Installation ```bash curl -LSs https://crystallizeapi.github.io/cli/install.bash | bash ``` -@todo! +> Concerned about what [this script](https://github.com/CrystallizeAPI/cli/blob/main/docs/install.bash) does? It's fully open-source, so you can review it yourself. It primarily detects your OS and platform to download the [latest version](https://github.com/CrystallizeAPI/cli/releases) of the CLI from GitHub. + +## Features + +The CLI enhances Developer Experience while also being CI/CD-friendly for automation. + +- **Boilerplate Installation:** Automates tedious setup steps: + + 1. Cloning the repository + 2. Creating the tenant + 3. Populating data in the tenant + 4. Setting up the `.env` file + 5. Installing dependencies + +- **Tenant Management:** Currently supports `create` for empty tenants and generating `invitations` for existing ones. Future contributions are welcome! + +- **Token Management:** Fetch and generate access tokens easily. + +- **Image Uploads:** Quickly upload and register images, whether a single file or an entire folder. + +- **Mass Operations:** Experimental but functional. You can `dump` your content model as JSON, `run` mass operations, and `execute` sets of mutations. + +## Interactivity + +Most commands are interactive. If credentials are missing, or input is required, the CLI will prompt you. To disable interactivity (e.g., in a CI environment), use `--no-interactive` where applicable. + +## Credentials + +The CLI stores credentials in `~/.crystallize/credentials.json` when saved interactively. It checks for credentials in the following order: + +1. **Environment variables:** `CRYSTALLIZE_ACCESS_TOKEN_ID` and `CRYSTALLIZE_ACCESS_TOKEN_SECRET` +2. **Command options:** `--token_id` and `--token_secret` +3. **Stored file:** `~/.crystallize/credentials.json` + +## Boilerplate Installation + +An interactive command designed to simplify setting up boilerplates. + +```bash +~/crystallize boilerplate install [tenant-identifier] [boilerplate-identifier] +``` + +- `folder` (required): The installation directory. +- `tenant-identifier` and `boilerplate-identifier` (optional): If omitted, a wizard will guide you. + +## Tenant Management + +### Creating a Tenant + +Creates a new tenant and removes default shapes for a clean setup. + +```bash +~/crystallize tenant create +``` + +- Runs non-interactively with `--no-interactive` if [credentials](#credentials) are available. +- If the identifier is taken, the CLI will inform you and suggest an alternative. + +### Inviting Users to a Tenant + +Generates invitation links for new users. + +```bash +~/crystallize tenant invite +``` + +Options: + +- `--role`: Default is `tenantAdmin`, but other roles are available. +- `--expiry`: Default is 6 hours; you can customize it. +- `--number`: Default is 1; you can generate multiple invites. + +## Image Upload + +Uploads and registers images in the Asset Organizer. + +```bash +~/crystallize image upload [output-file] +``` + +- `file` can be a single file or a folder (uploading all contained images). +- `output-file` (optional) stores mappings for automation. + +Example output: + +```json +{ + "clean-name-png": "crystallize-key", + "images-crystallize-png": "my-tenant/25/1/12/3435d2d0/images/crystallize.png" +} +``` + +Use `--force` to overwrite an existing `output-file`. + +## Mass Operations + +### Dumping the Content Model + +Creates a Mass Operation file containing the content model (_Shapes_ and _Pieces_). + +```bash +~/crystallize mass-operation dump-content-model +``` + +Use `--force` to overwrite an existing file. + +### Running a Mass Operation + +Executes a Mass Operation file by uploading it, registering the operation, and waiting for completion. + +```bash +~/crystallize mass-operation run +``` + +- Use `--legacy-spec` to convert an old Spec File to a Mass Operation file. + +### Executing Mutations + +A client-side utility to automate mutations. + +```bash +~/crystallize mass-operation execute-mutations [image-mapping-file] +``` + +- `file`: Contains the mutations (format below). +- `image-mapping-file` (optional): Injects image paths into variables. + +#### Mutation Format + +```json +{ + "create-products": { + "target": "pim", + "mutation": "mutation CreateProduct($input: CreateProductInput!) { product { create(language: \"en\", input: $input) { id } } }", + "sets": [] + }, + "publish-items": { + "mutation": "mutation PublishItems($ids: [ID!]!) { publishItems(language: \"en\", ids: $ids) { success { itemId } } }", + "target": "core", + "sets": [{ "ids": ["$create-products[0].product.create.id"] }] + } +} +``` + +#### Dependency Management + +Use references like `$create-products[0].product.create.id` to pass IDs from one operation to another. + +#### Injected Variables + +- `$root.TENANT_ID` +- `$root.TENANT_DEFAULT_VATTYPE_ID` +- `$root.TENANT_ROOT_ID` + +#### Image Mapping File + +```json +{ + "images": [ + { "key": "$images.crystallize-key" }, + { "key": "$images.my-tenant/25/1/12/3435d2d0/images/crystallize.png" } + ] +} +``` + +## Contributing + +The CLI resides in [CrystallizeAPI/tools](https://github.com/CrystallizeAPI/tools), a read-only split from the main repo. + +For issues or contributions, submit them to the main repository: [CrystallizeAPI/tools](https://github.com/CrystallizeAPI/tools). + +[crystallizeobject]: crystallize_marketing|folder|67ae7f698dcd1f699563c8d5 diff --git a/package.json b/package.json index 76f63b8..54bf747 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@crystallize/cli", - "version": "5.4.2", + "version": "5.4.3", "description": "Crystallize CLI", "module": "src/index.ts", "repository": "https://github.com/CrystallizeAPI/crystallize-cli", diff --git a/src/command/doc.ts b/src/command/doc.ts new file mode 100644 index 0000000..147d996 --- /dev/null +++ b/src/command/doc.ts @@ -0,0 +1,18 @@ +import { Command } from 'commander'; +import { marked } from 'marked'; +import { markedTerminal } from 'marked-terminal'; +//@ts-expect-error - This is a workaround to import the changelog file as text. It's working with bun. +import Doc from '../../README.md' with { type: 'text' }; +import { logo } from '..'; +// @ts-ignore +marked.use(markedTerminal()); + +export const createDocCommand = (): Command => { + const command = new Command('doc'); + command.description('Render the doc.'); + command.action(async () => { + console.log(logo); + console.log(marked.parse(Doc)); + }); + return command; +}; diff --git a/src/content/completion_file.bash b/src/content/completion_file.bash index 4ef6f9e..da9154b 100644 --- a/src/content/completion_file.bash +++ b/src/content/completion_file.bash @@ -4,7 +4,7 @@ _crystallize_completions() { local subcmd="${COMP_WORDS[2]}" local subsubcmd="${COMP_WORDS[3]}" - local commands="help changelog boilerplate tenant login whoami mass-operation" + local commands="help changelog doc boilerplate tenant login whoami mass-operation image" local program_options="--version" local default_options="--help" local i_login_options="--no-interactive --token_id= --token_secret=" diff --git a/src/core/di.ts b/src/core/di.ts index 1f8b09d..32eb1a5 100644 --- a/src/core/di.ts +++ b/src/core/di.ts @@ -43,6 +43,7 @@ import { createExecuteMutationsCommand } from '../command/mass-operation/execute import { createImageUploadCommand } from '../command/images/upload'; import { createUploadImagesHandler } from '../domain/use-cases/upload-images'; import { createExecuteMutationsHandler } from '../domain/use-cases/execute-extra-mutations'; +import { createDocCommand } from '../command/doc'; export const buildServices = () => { const logLevels = ( @@ -86,6 +87,7 @@ export const buildServices = () => { whoAmICommand: Command; runMassOperationCommand: Command; changeLogCommand: Command; + docCommand: Command; createTenantCommand: Command; createInviteTokenCommand: Command; getStaticAuthTokenCommand: Command; @@ -141,6 +143,7 @@ export const buildServices = () => { whoAmICommand: asFunction(createWhoAmICommand).singleton(), runMassOperationCommand: asFunction(createRunMassOperationCommand).singleton(), changeLogCommand: asFunction(createChangelogCommand).singleton(), + docCommand: asFunction(createDocCommand).singleton(), createTenantCommand: asFunction(createCreateTenantCommand).singleton(), createInviteTokenCommand: asFunction(createCreateInviteTokenCommand).singleton(), getStaticAuthTokenCommand: asFunction(createGetStaticAuthTokenCommand).singleton(), @@ -185,6 +188,7 @@ export const buildServices = () => { container.cradle.loginCommand, container.cradle.whoAmICommand, container.cradle.changeLogCommand, + container.cradle.docCommand, ], }, boilerplate: {