diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..d090ace --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,32 @@ + + +## Description / Motivation + + + + + +## How Has This Been Tested? + + + + + +## Types of changes + + + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to change) +- [ ] Documentation update (non-breaking change; modified files are limited to the `/docs` directory or other markdown files) + +## Checklist: + + + + +- [ ] I have read the Contributing guide. +- [ ] My code/comments/docs fully adhere to the Code of Conduct. +- [ ] My change is a code change. +- [ ] My change is a documentation change and there are NO other updates required. \ No newline at end of file diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..4fd0219 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +engine-strict=true \ No newline at end of file diff --git a/README.md b/README.md index 08bcc4e..251acc0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,6 @@ +![npm](https://img.shields.io/npm/dm/sitecore-cdp-serializer) +[![npm version](https://badge.fury.io/js/sitecore-cdp-serializer.svg)](https://badge.fury.io/js/sitecore-cdp-serializer) + ## Installation Sitecore CDP serializer requires [Node.js](https://nodejs.org) version 14 or above. To install, run the following commands from any directory in your terminal: diff --git a/docs/commands/api.md b/docs/commands/api.md index 0ce9166..0c96a52 100644 --- a/docs/commands/api.md +++ b/docs/commands/api.md @@ -4,9 +4,38 @@ The API commands should never be used by a public application. Your Sitecore CDP/Personalize API Username and Password should never be send to anyone you don't trust. It's recommended that you create a Service API account in your Sitecore CDP/Personalize tenant so you can have more control over revoking access in the future. -## Available Commands +## Authentication Commands -| Command | Description | Parameters | -| :---------: | :-------------------------------------------------------------- | :--------------------------------------------- | -| auth | Required command to create access token for future CLI commands | -u, --username, -p, --password, -l, --location | -| connections | Retrieve all connections from your connected tenant | \ | +All authentication commands start with `auth`. + +| Subcommand | Description | Parameters | +| :--------: | :-------------------------------------------------------------- | :-------------------------------------------------------------------------------------- | +| login | Required command to create access token for future CLI commands | -id, --clientId
-s, --clientSecret
-l, --location _optional_ (defaults to EU) | +| status | View Authentication/Service Url information | \ | +| logout | Logout of the API | \ | + +### Example + +```bash +npx sitecore-cdp-serializer auth login -id {Client Key} -s {API Token} -l {EU|US|APJ} +``` + +## Template Commands + +All template commands start with `templates`. + +| Subcommand | Description | Parameters | +| :--------: | :------------------------------------------------------- | :---------------------------------------------------------- | +| get | Gets a list of Templates from the CDP/Personalize tenant | --friendlyId _optional_
--templateRef _optional_
| +| create | Creates a New Template based on a JSON object | -t, --template | +| update | Updates an Existing Template based on a JSON object | -t, --template | + +### Example + +```bash +npx sitecore-cdp-serializer templates get --friendlyId 'sitecore_test_template_1' +``` + +### Notes + +In order to run a templates command, you must have already run an `auth login` command to authenticate to the tenant you wish to access templates from. diff --git a/docs/commands/deploy.md b/docs/commands/deploy.md index e69de29..c90151f 100644 --- a/docs/commands/deploy.md +++ b/docs/commands/deploy.md @@ -0,0 +1,19 @@ +# Deploy Commands + +## Usage + +This command is useful for taking physical files and deploying them to a CDP, Personalize or CDP/Personalize tenant. Details of this command are below: + +| Command | Description | Parameters | +| :-----: | :-------------------------------------------------- | :---------------------------------------------------- | +| deploy | Command to take physical files and deploy to Tenant | --artifactPath _optional_ (defaults to `./artifacts`) | + +### Example + +```bash +npx sitecore-cdp-serializer deploy +``` + +### Notes + +In order to run a deploy command, you must have already run an `auth login` command to authenticate to the tenant you wish to deploy the artifacts out to. diff --git a/package-lock.json b/package-lock.json index 652dcb4..5db9414 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "sitecore-cdp-serializer", - "version": "0.1.2", + "version": "0.1.6", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/src/commands/api/Base.service.ts b/src/commands/api/Base.service.ts new file mode 100644 index 0000000..837aaa2 --- /dev/null +++ b/src/commands/api/Base.service.ts @@ -0,0 +1,61 @@ +/** + * Base service for all API calls + */ + + import Configstore from "configstore"; + import { AuthToken } from './auth/Auth.interface.js'; + import fetch from 'node-fetch'; + + const BaseService = (config: Configstore) => { + const serviceUrl = config.get('serviceUrl'); + const credentials: AuthToken = config.get('credentials'); + + const Fetch = async(method: string, path: string, body: object | null | undefined) => { + if (!serviceUrl) { + throw 'Service URL not set, re-run auth command'; + } + + if (!credentials) { + throw 'You must run the auth command first to initialize the CLI'; + } + + let data = body !== null && body !== undefined + ? JSON.stringify(body) + : null; + + return await fetch(`https://${serviceUrl}/${path}`, { + method, + body: data, + headers: { + Authorization: `Bearer ${credentials.access_token}`, + 'Content-Type': 'application/json', + }, + }); + } + + const Get = async(path: string) => { + return await Fetch("get", path, null); + } + + const Post = async(path: string, body: object | null | undefined) => { + return await Fetch("post", path, body); + } + + const Put = async(path: string, body: object | null | undefined) => { + return await Fetch("put", path, body); + } + + const Delete = async(path: string, body: object | null | undefined) => { + return await Fetch("delete", path, body); + } + + return { + Fetch, + Get, + Post, + Put, + Delete, + }; + } + + export { BaseService }; \ No newline at end of file diff --git a/src/commands/api/auth/Auth.service.ts b/src/commands/api/auth/Auth.service.ts index ddac94d..a796671 100644 --- a/src/commands/api/auth/Auth.service.ts +++ b/src/commands/api/auth/Auth.service.ts @@ -3,7 +3,12 @@ import { AuthToken } from './Auth.interface.js'; import fetch, { Response } from 'node-fetch'; import chalk from 'chalk'; import { Command } from 'commander'; -import { initServiceLocation, log, logline } from '../../../utils/index.js'; +import { + initServiceLocation, + logline, + logSuccess, + logError, +} from '../../../utils/index.js'; let globalConfig: Configstore; @@ -35,10 +40,10 @@ const Authenticate = async (clientId: string, clientSecret: string) => { if (authToken) { globalConfig.set('credentials', authToken); - logline(chalk.green('Token Stored for future uses')); + logSuccess('Token Stored for future uses'); } } else { - logline(chalk.red('Authentication Failed')); + logError('Authentication Failed'); } }; diff --git a/src/commands/api/templates/Template.service.ts b/src/commands/api/templates/Template.service.ts index b25e551..c54e1ef 100644 --- a/src/commands/api/templates/Template.service.ts +++ b/src/commands/api/templates/Template.service.ts @@ -1,143 +1,92 @@ import Configstore from 'configstore'; -import fetch, { Response } from 'node-fetch'; -import chalk from 'chalk'; -import { AuthToken } from '../auth/Auth.interface.js'; +import { Response } from 'node-fetch'; import { Command } from 'commander'; import { Template } from './Template.interface.js'; -import { logline } from '../../../utils/index.js'; +import { + logline, + logSuccess, + logError, + logResponse, +} from '../../../utils/index.js'; +import { BaseService } from '../Base.service.js' const TemplateService = (config: Configstore) => { - const serviceUrl = config.get('serviceUrl'); - const credentials: AuthToken = config.get('credentials'); - + const baseService = BaseService(config); + const GetAllTemplates = async (templateType: string) => { - if (!serviceUrl) { - logline(chalk.red('Service URL not set, re-run auth command')); - return; - } - - if (!credentials) { - logline(chalk.red('You must run the auth command first to initialize the CLI')); - return; - } - - let servicePath = `https://${serviceUrl}/v3/templates`; - - const response: Response = await fetch(servicePath, { - method: 'get', - body: null, - headers: { - Authorization: `Bearer ${credentials.access_token}`, - }, - }); - - if (response.ok) { - logline(chalk.green('success')); - let templates: Template[] = (await response.json()) as Template[]; - - return templates; - } else { - console.log(chalk.red('Failed to retrieve templates')); + try { + const response: Response = await baseService.Get('v3/templates'); + + if (response.ok) { + logSuccess('success'); + let templates: Template[] = (await response.json()) as Template[]; + + return templates; + } else { + logResponse(response, 'Failed to retrieve templates'); + } + } catch (ex) { + logError(ex); } }; const GetByFriendlyId = async (friendlyId: string): Promise