auth0-deploy-cli 7.9.0 → 7.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,16 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [7.10.0] - 2022-04-26
11
+
12
+ ### Added
13
+
14
+ - Branding support for directory format [#505]
15
+
16
+ ### Fixed
17
+
18
+ - More comprehensive support for deletions through `AUTH0_ALLOW_DELETE` [#509]
19
+
10
20
  ## [7.9.0] - 2022-04-19
11
21
 
12
22
  ### Added
@@ -690,7 +700,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
690
700
  [#495]: https://github.com/auth0/auth0-deploy-cli/issues/495
691
701
  [#497]: https://github.com/auth0/auth0-deploy-cli/issues/497
692
702
  [#504]: https://github.com/auth0/auth0-deploy-cli/issues/504
693
- [unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v7.9.0...HEAD
703
+ [#505]: https://github.com/auth0/auth0-deploy-cli/issues/505
704
+ [#509]: https://github.com/auth0/auth0-deploy-cli/issues/509
705
+ [unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v7.10.0...HEAD
706
+ [7.10.0]: https://github.com/auth0/auth0-deploy-cli/compare/v7.9.0...v7.10.0
694
707
  [7.9.0]: https://github.com/auth0/auth0-deploy-cli/compare/v7.8.0...v7.9.0
695
708
  [7.8.0]: https://github.com/auth0/auth0-deploy-cli/compare/v7.7.1...v7.8.0
696
709
  [7.7.1]: https://github.com/auth0/auth0-deploy-cli/compare/v7.7.0...v7.7.1
package/README.md CHANGED
@@ -7,7 +7,7 @@ The `auth0-deploy-cli` tool supports the importing and exporting of Auth0 Tenant
7
7
  Supported Auth0 Management API resources
8
8
 
9
9
  - [x] [Actions](https://auth0.com/docs/api/management/v2/#!/Actions/get_actions)
10
- - [ ] [Branding](https://auth0.com/docs/api/management/v2/#!/Branding/get_branding)
10
+ - [x] [Branding](https://auth0.com/docs/api/management/v2/#!/Branding/get_branding)
11
11
  - [x] [Clients (Applications)](https://auth0.com/docs/api/management/v2#!/Clients/get_clients)
12
12
  - [x] [Client Grants](https://auth0.com/docs/api/management/v2#!/Client_Grants/get_client_grants)
13
13
  - [x] [Connections](https://auth0.com/docs/api/management/v2#!/Connections/get_connections)
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
24
  };
@@ -17,7 +28,11 @@ const path_1 = __importDefault(require("path"));
17
28
  const tools_1 = require("../../../tools");
18
29
  const utils_1 = require("../../../utils");
19
30
  function parse(context) {
20
- const brandingTemplatesFolder = path_1.default.join(context.filePath, tools_1.constants.BRANDING_DIRECTORY, tools_1.constants.BRANDING_TEMPLATES_DIRECTORY);
31
+ const brandingDirectory = path_1.default.join(context.filePath, tools_1.constants.BRANDING_DIRECTORY);
32
+ if (!(0, utils_1.existsMustBeDir)(brandingDirectory))
33
+ return { branding: undefined };
34
+ const branding = (0, utils_1.loadJSON)(path_1.default.join(brandingDirectory, 'branding.json'), context.mappings);
35
+ const brandingTemplatesFolder = path_1.default.join(brandingDirectory, tools_1.constants.BRANDING_TEMPLATES_DIRECTORY);
21
36
  if (!(0, utils_1.existsMustBeDir)(brandingTemplatesFolder))
22
37
  return { branding: context.assets.branding };
23
38
  const templatesDefinitionFiles = (0, utils_1.getFiles)(brandingTemplatesFolder, ['.json']);
@@ -27,32 +42,51 @@ function parse(context) {
27
42
  return definition;
28
43
  }, {});
29
44
  return {
30
- branding: {
31
- templates,
32
- },
45
+ branding: Object.assign(Object.assign({}, branding), { templates }),
33
46
  };
34
47
  }
35
48
  function dump(context) {
36
49
  return __awaiter(this, void 0, void 0, function* () {
37
- const { branding } = context.assets;
38
- if (!branding || !branding.templates || !branding.templates)
39
- return; // Skip, nothing to dump
40
- const brandingTemplatesFolder = path_1.default.join(context.filePath, tools_1.constants.BRANDING_DIRECTORY, tools_1.constants.BRANDING_TEMPLATES_DIRECTORY);
41
- fs_extra_1.default.ensureDirSync(brandingTemplatesFolder);
42
- branding.templates.forEach((templateDefinition) => {
43
- const markup = templateDefinition.body;
44
- try {
45
- fs_extra_1.default.writeFileSync(path_1.default.join(brandingTemplatesFolder, `${templateDefinition.template}.html`), markup);
46
- }
47
- catch (e) {
48
- throw new Error(`Error writing template file: ${templateDefinition.template}, because: ${e.message}`);
49
- }
50
- // save the location as relative file.
51
- templateDefinition.body = `.${path_1.default.sep}${templateDefinition.template}.html`;
52
- (0, utils_1.dumpJSON)(path_1.default.join(brandingTemplatesFolder, `${templateDefinition.template}.json`), templateDefinition);
53
- });
50
+ const _a = context.assets.branding, { templates = [] } = _a, branding = __rest(_a, ["templates"]);
51
+ if (!!branding)
52
+ dumpBranding(context);
53
+ if (!!templates)
54
+ dumpBrandingTemplates(context);
54
55
  });
55
56
  }
57
+ const dumpBrandingTemplates = ({ filePath, assets }) => {
58
+ if (!assets || !assets.branding)
59
+ return;
60
+ const { branding: { templates = [] }, } = assets;
61
+ const brandingTemplatesFolder = path_1.default.join(filePath, tools_1.constants.BRANDING_DIRECTORY, tools_1.constants.BRANDING_TEMPLATES_DIRECTORY);
62
+ fs_extra_1.default.ensureDirSync(brandingTemplatesFolder);
63
+ templates.forEach((templateDefinition) => {
64
+ const markup = templateDefinition.body;
65
+ try {
66
+ fs_extra_1.default.writeFileSync(path_1.default.join(brandingTemplatesFolder, `${templateDefinition.template}.html`), markup);
67
+ }
68
+ catch (e) {
69
+ throw new Error(`Error writing template file: ${templateDefinition.template}, because: ${e.message}`);
70
+ }
71
+ // save the location as relative file.
72
+ templateDefinition.body = `.${path_1.default.sep}${templateDefinition.template}.html`;
73
+ (0, utils_1.dumpJSON)(path_1.default.join(brandingTemplatesFolder, `${templateDefinition.template}.json`), templateDefinition);
74
+ });
75
+ };
76
+ const dumpBranding = ({ filePath, assets }) => {
77
+ if (!assets || !assets.branding)
78
+ return;
79
+ const { branding } = assets;
80
+ const brandingWithoutTemplates = (() => {
81
+ const newBranding = Object.assign({}, branding);
82
+ delete newBranding.templates;
83
+ return newBranding;
84
+ })();
85
+ const brandingDirectory = path_1.default.join(filePath, tools_1.constants.BRANDING_DIRECTORY);
86
+ fs_extra_1.default.ensureDirSync(brandingDirectory);
87
+ const brandingFilePath = path_1.default.join(brandingDirectory, 'branding.json');
88
+ (0, utils_1.dumpJSON)(brandingFilePath, brandingWithoutTemplates);
89
+ };
56
90
  const brandingHandler = {
57
91
  parse,
58
92
  dump,
@@ -1,6 +1,13 @@
1
1
  import { YAMLHandler } from '.';
2
+ declare type BrandingTemplate = {
3
+ template: string;
4
+ body: string;
5
+ };
2
6
  declare type ParsedBranding = {
3
- branding: unknown;
7
+ branding: {
8
+ templates?: BrandingTemplate[];
9
+ [key: string]: unknown;
10
+ };
4
11
  };
5
12
  declare const brandingHandler: YAMLHandler<ParsedBranding>;
6
13
  export default brandingHandler;
@@ -8,6 +8,17 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  step((generator = generator.apply(thisArg, _arguments || [])).next());
9
9
  });
10
10
  };
11
+ var __rest = (this && this.__rest) || function (s, e) {
12
+ var t = {};
13
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
14
+ t[p] = s[p];
15
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
16
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
17
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
18
+ t[p[i]] = s[p[i]];
19
+ }
20
+ return t;
21
+ };
11
22
  var __importDefault = (this && this.__importDefault) || function (mod) {
12
23
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
24
  };
@@ -18,24 +29,30 @@ const tools_1 = require("../../../tools");
18
29
  function parse(context) {
19
30
  return __awaiter(this, void 0, void 0, function* () {
20
31
  // Load the HTML file for each page
21
- const { branding } = context.assets;
22
- if (!branding || !branding.templates)
32
+ if (!context.assets.branding)
33
+ return {
34
+ branding: {
35
+ templates: [],
36
+ },
37
+ };
38
+ const _a = context.assets.branding, { templates } = _a, branding = __rest(_a, ["templates"]);
39
+ if (!branding && !branding['templates'])
23
40
  return { branding };
24
- const templates = branding.templates.map((templateDefinition) => {
25
- const markupFile = path_1.default.join(templateDefinition.body);
41
+ const parsedTemplates = templates.map((templateDefinition) => {
42
+ const markupFile = path_1.default.join(context.basePath, templateDefinition.body);
26
43
  return {
27
44
  template: templateDefinition.template,
28
45
  body: (0, tools_1.loadFileAndReplaceKeywords)(markupFile, context.mappings),
29
46
  };
30
47
  });
31
48
  return {
32
- branding: Object.assign(Object.assign({}, branding), { templates }),
49
+ branding: Object.assign(Object.assign({}, branding), { templates: parsedTemplates }),
33
50
  };
34
51
  });
35
52
  }
36
53
  function dump(context) {
37
54
  return __awaiter(this, void 0, void 0, function* () {
38
- const { branding } = context.assets || { branding: undefined };
55
+ const { branding } = context.assets;
39
56
  branding.templates = branding.templates || [];
40
57
  // create templates folder
41
58
  if (branding.templates.length) {
@@ -92,6 +92,7 @@ class APIHandler {
92
92
  return (0, calculateChanges_1.calculateChanges)({
93
93
  handler: this,
94
94
  assets: typeAssets,
95
+ allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
95
96
  //@ts-ignore TODO: investigate what happens when `existing` is null
96
97
  existing,
97
98
  identifiers: this.identifiers,
@@ -237,7 +237,7 @@ class OrganizationsHandler extends default_1.default {
237
237
  assets: organizations,
238
238
  existing,
239
239
  identifiers: ['id', 'name'],
240
- allowDelete: false, //TODO: actually pass in correct allowDelete value
240
+ allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
241
241
  });
242
242
  logger_1.default.debug(`Start processChanges for organizations [delete:${changes.del.length}] [update:${changes.update.length}], [create:${changes.create.length}]`);
243
243
  const myChanges = [
@@ -83,7 +83,7 @@ class ResourceServersHandler extends default_1.default {
83
83
  assets: resourceServers,
84
84
  existing,
85
85
  identifiers: ['id', 'identifier'],
86
- allowDelete: false, //TODO: actually pass in correct allowDelete value
86
+ allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
87
87
  });
88
88
  });
89
89
  }
@@ -210,7 +210,7 @@ class RolesHandler extends default_1.default {
210
210
  assets: roles,
211
211
  existing,
212
212
  identifiers: ['id', 'name'],
213
- allowDelete: false, //TODO: actually pass in correct allowDelete value
213
+ allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
214
214
  });
215
215
  logger_1.default.debug(`Start processChanges for roles [delete:${changes.del.length}] [update:${changes.update.length}], [create:${changes.create.length}]`);
216
216
  const myChanges = [
@@ -89,7 +89,7 @@ class RulesHandler extends default_1.default {
89
89
  assets: rules,
90
90
  existing,
91
91
  identifiers: ['id', 'name'],
92
- allowDelete: false, //TODO: actually pass in correct allowDelete value
92
+ allowDelete: !!this.config('AUTH0_ALLOW_DELETE'),
93
93
  });
94
94
  // Figure out the rules that need to be re-ordered
95
95
  const futureRules = [...create, ...update];
@@ -6,14 +6,14 @@ import { Asset, CalculatedChanges } from '../types';
6
6
  * @param {T} desiredAssetState
7
7
  * @param {T} currentAssetState
8
8
  * @param {string[]} [objectFields=[]]
9
- * @param {boolean} [allowDelete=false]
9
+ * @param {boolean} [allowDelete]
10
10
  * @returns T
11
11
  */
12
12
  export declare function processChangedObjectFields({ handler, desiredAssetState, currentAssetState, allowDelete, }: {
13
13
  handler: APIHandler;
14
14
  desiredAssetState: Asset;
15
15
  currentAssetState: Asset;
16
- allowDelete?: boolean;
16
+ allowDelete: boolean;
17
17
  }): {
18
18
  [x: string]: any;
19
19
  };
@@ -11,10 +11,10 @@ const logger_1 = __importDefault(require("../logger"));
11
11
  * @param {T} desiredAssetState
12
12
  * @param {T} currentAssetState
13
13
  * @param {string[]} [objectFields=[]]
14
- * @param {boolean} [allowDelete=false]
14
+ * @param {boolean} [allowDelete]
15
15
  * @returns T
16
16
  */
17
- function processChangedObjectFields({ handler, desiredAssetState, currentAssetState, allowDelete = false, }) {
17
+ function processChangedObjectFields({ handler, desiredAssetState, currentAssetState, allowDelete, }) {
18
18
  const desiredAssetStateWithChanges = Object.assign({}, desiredAssetState);
19
19
  // eslint-disable-next-line no-restricted-syntax
20
20
  for (const fieldName of handler.objectFields) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auth0-deploy-cli",
3
- "version": "7.9.0",
3
+ "version": "7.10.0",
4
4
  "description": "A command line tool for deploying updates to your Auth0 tenant",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -53,7 +53,7 @@
53
53
  "@types/expect": "^24.3.0",
54
54
  "@types/mocha": "^9.1.0",
55
55
  "chai": "^4.3.6",
56
- "@typescript-eslint/parser": "^5.17.0",
56
+ "@typescript-eslint/parser": "^5.18.0",
57
57
  "chai-as-promised": "^7.1.1",
58
58
  "cross-env": "^3.1.4",
59
59
  "eslint": "^7.28.0",
@@ -64,7 +64,7 @@
64
64
  "kacl": "^1.1.1",
65
65
  "mocha": "^9.2.2",
66
66
  "nyc": "^15.0.1",
67
- "prettier": "^2.6.1",
67
+ "prettier": "^2.6.2",
68
68
  "pretty-quick": "^3.1.3",
69
69
  "rimraf": "^3.0.2",
70
70
  "rmdir-sync": "^1.0.1",