auth0-deploy-cli 7.8.0 → 7.9.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.9.0] - 2022-04-19
11
+
12
+ ### Added
13
+
14
+ - Log streams support [#495]
15
+
16
+ ### Fixed
17
+
18
+ - `##` String keyword replacements now work when nested inside `@@` array replacements [#504]
19
+
10
20
  ## [7.8.0] - 2022-04-14
11
21
 
12
22
  ### Added
@@ -677,8 +687,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
677
687
  [#481]: https://github.com/auth0/auth0-deploy-cli/issues/481
678
688
  [#482]: https://github.com/auth0/auth0-deploy-cli/issues/482
679
689
  [#485]: https://github.com/auth0/auth0-deploy-cli/issues/485
690
+ [#495]: https://github.com/auth0/auth0-deploy-cli/issues/495
680
691
  [#497]: https://github.com/auth0/auth0-deploy-cli/issues/497
681
- [unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v7.8.0...HEAD
692
+ [#504]: https://github.com/auth0/auth0-deploy-cli/issues/504
693
+ [unreleased]: https://github.com/auth0/auth0-deploy-cli/compare/v7.9.0...HEAD
694
+ [7.9.0]: https://github.com/auth0/auth0-deploy-cli/compare/v7.8.0...v7.9.0
682
695
  [7.8.0]: https://github.com/auth0/auth0-deploy-cli/compare/v7.7.1...v7.8.0
683
696
  [7.7.1]: https://github.com/auth0/auth0-deploy-cli/compare/v7.7.0...v7.7.1
684
697
  [7.7.0]: https://github.com/auth0/auth0-deploy-cli/compare/v7.6.0...v7.7.0
package/README.md CHANGED
@@ -16,7 +16,7 @@ Supported Auth0 Management API resources
16
16
  - [x] [Grants](https://auth0.com/docs/api/management/v2#!/Grants/get_grants)
17
17
  - [x] [Hooks](https://auth0.com/docs/api/management/v2#!/Hooks/get_hooks)
18
18
  - [x] [Hook Secrets](https://auth0.com/docs/api/management/v2/#!/Hooks/get_secrets)
19
- - [ ] [Log Streams](https://auth0.com/docs/api/management/v2#!/Log_Streams/get_log_streams)
19
+ - [x] [Log Streams](https://auth0.com/docs/api/management/v2#!/Log_Streams/get_log_streams)
20
20
  - [ ] [Logs](https://auth0.com/docs/api/management/v2#!/Logs/get_logs)
21
21
  - [x] [Organizations](https://auth0.com/docs/api/management/v2#!/Organizations/get_organizations)
22
22
  - [ ] [Prompts](https://auth0.com/docs/api/management/v2#!/Prompts/get_prompts)
@@ -28,6 +28,7 @@ const organizations_1 = __importDefault(require("./organizations"));
28
28
  const triggers_1 = __importDefault(require("./triggers"));
29
29
  const attackProtection_1 = __importDefault(require("./attackProtection"));
30
30
  const branding_1 = __importDefault(require("./branding"));
31
+ const logStreams_1 = __importDefault(require("./logStreams"));
31
32
  const directoryHandlers = {
32
33
  rules: rules_1.default,
33
34
  rulesConfigs: rulesConfigs_1.default,
@@ -54,5 +55,6 @@ const directoryHandlers = {
54
55
  triggers: triggers_1.default,
55
56
  attackProtection: attackProtection_1.default,
56
57
  branding: branding_1.default,
58
+ logStreams: logStreams_1.default,
57
59
  };
58
60
  exports.default = directoryHandlers;
@@ -0,0 +1,7 @@
1
+ import { DirectoryHandler } from '.';
2
+ import { Asset } from '../../../types';
3
+ declare type ParsedLogStreams = {
4
+ logStreams: Asset[] | undefined;
5
+ };
6
+ declare const logStreamsHandler: DirectoryHandler<ParsedLogStreams>;
7
+ export default logStreamsHandler;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const fs_extra_1 = __importDefault(require("fs-extra"));
16
+ const path_1 = __importDefault(require("path"));
17
+ const tools_1 = require("../../../tools");
18
+ const utils_1 = require("../../../utils");
19
+ function parse(context) {
20
+ const logStreamsDirectory = path_1.default.join(context.filePath, tools_1.constants.LOG_STREAMS_DIRECTORY);
21
+ if (!(0, utils_1.existsMustBeDir)(logStreamsDirectory))
22
+ return { logStreams: undefined }; // Skip
23
+ const foundFiles = (0, utils_1.getFiles)(logStreamsDirectory, ['.json']);
24
+ const logStreams = foundFiles
25
+ .map((f) => (0, utils_1.loadJSON)(f, context.mappings))
26
+ .filter((p) => Object.keys(p).length > 0); // Filter out empty rulesConfigs
27
+ return {
28
+ logStreams,
29
+ };
30
+ }
31
+ function dump(context) {
32
+ return __awaiter(this, void 0, void 0, function* () {
33
+ const logStreams = context.assets.logStreams || [];
34
+ if (!logStreams)
35
+ return; // Skip, nothing to dump
36
+ // Create Rules folder
37
+ const logStreamsDirectory = path_1.default.join(context.filePath, tools_1.constants.LOG_STREAMS_DIRECTORY);
38
+ fs_extra_1.default.ensureDirSync(logStreamsDirectory);
39
+ logStreams.forEach((logStream) => {
40
+ const ruleFile = path_1.default.join(logStreamsDirectory, `${(0, utils_1.sanitize)(logStream.name)}.json`);
41
+ (0, utils_1.dumpJSON)(ruleFile, logStream);
42
+ });
43
+ });
44
+ }
45
+ const logStreamsHandler = {
46
+ parse,
47
+ dump,
48
+ };
49
+ exports.default = logStreamsHandler;
@@ -28,6 +28,7 @@ const actions_1 = __importDefault(require("./actions"));
28
28
  const triggers_1 = __importDefault(require("./triggers"));
29
29
  const attackProtection_1 = __importDefault(require("./attackProtection"));
30
30
  const branding_1 = __importDefault(require("./branding"));
31
+ const logStreams_1 = __importDefault(require("./logStreams"));
31
32
  const yamlHandlers = {
32
33
  rules: rules_1.default,
33
34
  hooks: hooks_1.default,
@@ -54,5 +55,6 @@ const yamlHandlers = {
54
55
  triggers: triggers_1.default,
55
56
  attackProtection: attackProtection_1.default,
56
57
  branding: branding_1.default,
58
+ logStreams: logStreams_1.default,
57
59
  };
58
60
  exports.default = yamlHandlers;
@@ -0,0 +1,7 @@
1
+ import { YAMLHandler } from '.';
2
+ import { Asset } from '../../../types';
3
+ declare type ParsedLogStreams = {
4
+ logStreams: Asset[] | null;
5
+ };
6
+ declare const logStreamsHandler: YAMLHandler<ParsedLogStreams>;
7
+ export default logStreamsHandler;
@@ -0,0 +1,23 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ function parseAndDump(context) {
13
+ return __awaiter(this, void 0, void 0, function* () {
14
+ return {
15
+ logStreams: context.assets.logStreams || [],
16
+ };
17
+ });
18
+ }
19
+ const logStreamsHandler = {
20
+ parse: parseAndDump,
21
+ dump: parseAndDump,
22
+ };
23
+ exports.default = logStreamsHandler;
package/lib/index.d.ts CHANGED
@@ -76,6 +76,7 @@ declare const _default: {
76
76
  DATABASE_SCRIPTS_IMPORT: string[];
77
77
  EMAIL_TEMPLATES_NAMES: string[];
78
78
  SUPPORTED_BRANDING_TEMPLATES: string[];
79
+ LOG_STREAMS_DIRECTORY: string;
79
80
  };
80
81
  deploy: typeof import("./tools").deploy;
81
82
  keywordReplace: typeof import("./tools").keywordReplace;
@@ -125,5 +125,10 @@ declare const _default: {
125
125
  excludeSchema?: any;
126
126
  schema: any;
127
127
  };
128
+ logStreams: {
129
+ default: typeof APIHandler;
130
+ excludeSchema?: any;
131
+ schema: any;
132
+ };
128
133
  };
129
134
  export default _default;
@@ -50,6 +50,7 @@ const actions = __importStar(require("./actions"));
50
50
  const triggers = __importStar(require("./triggers"));
51
51
  const organizations = __importStar(require("./organizations"));
52
52
  const attackProtection = __importStar(require("./attackProtection"));
53
+ const logStreams = __importStar(require("./logStreams"));
53
54
  const auth0ApiHandlers = {
54
55
  rules,
55
56
  rulesConfigs,
@@ -78,5 +79,6 @@ const auth0ApiHandlers = {
78
79
  triggers,
79
80
  organizations,
80
81
  attackProtection,
82
+ logStreams,
81
83
  };
82
84
  exports.default = auth0ApiHandlers; // TODO: apply stronger types to schema properties
@@ -0,0 +1,40 @@
1
+ import DefaultAPIHandler from './default';
2
+ import { Asset, Assets } from '../../../types';
3
+ export declare const schema: {
4
+ type: string;
5
+ items: {
6
+ type: string;
7
+ properties: {
8
+ id: {
9
+ type: string;
10
+ };
11
+ type: {
12
+ type: string;
13
+ };
14
+ name: {
15
+ type: string;
16
+ };
17
+ status: {
18
+ type: string;
19
+ enum: string[];
20
+ };
21
+ sink: {
22
+ type: string;
23
+ };
24
+ filters: {
25
+ type: string;
26
+ items: {
27
+ type: string;
28
+ };
29
+ };
30
+ };
31
+ required: string[];
32
+ };
33
+ };
34
+ export default class LogStreamsHandler extends DefaultAPIHandler {
35
+ existing: Asset[] | null;
36
+ constructor(config: DefaultAPIHandler);
37
+ objString(item: Asset): string;
38
+ getType(): Promise<Asset>;
39
+ processChanges(assets: Assets): Promise<void>;
40
+ }
@@ -0,0 +1,77 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.schema = void 0;
16
+ const default_1 = __importDefault(require("./default"));
17
+ exports.schema = {
18
+ type: 'array',
19
+ items: {
20
+ type: 'object',
21
+ properties: {
22
+ id: { type: 'string' },
23
+ type: { type: 'string' },
24
+ name: { type: 'string' },
25
+ status: { type: 'string', enum: ['active', 'paused', 'suspended'] },
26
+ sink: { type: 'object' },
27
+ filters: {
28
+ type: 'array',
29
+ items: {
30
+ type: 'object',
31
+ },
32
+ },
33
+ },
34
+ required: ['name'],
35
+ },
36
+ };
37
+ class LogStreamsHandler extends default_1.default {
38
+ constructor(config) {
39
+ super(Object.assign(Object.assign({}, config), { type: 'logStreams', stripUpdateFields: ['type'], stripCreateFields: ['status', 'sink.awsPartnerEventSource'], sensitiveFieldsToObfuscate: ['sink.httpAuthorization'] }));
40
+ }
41
+ objString(item) {
42
+ return super.objString(item.name);
43
+ }
44
+ getType() {
45
+ return __awaiter(this, void 0, void 0, function* () {
46
+ if (this.existing) {
47
+ return this.existing;
48
+ }
49
+ const logStreams = yield this.client.logStreams.getAll({ paginate: false });
50
+ const nonSuspendedLogStreams = logStreams.filter((logStream) => logStream.status !== 'suspended');
51
+ this.existing = nonSuspendedLogStreams;
52
+ return nonSuspendedLogStreams;
53
+ });
54
+ }
55
+ processChanges(assets) {
56
+ const _super = Object.create(null, {
57
+ processChanges: { get: () => super.processChanges }
58
+ });
59
+ return __awaiter(this, void 0, void 0, function* () {
60
+ const { logStreams } = assets;
61
+ // Do nothing if not set
62
+ if (!logStreams)
63
+ return;
64
+ // Figure out what needs to be updated vs created
65
+ const changes = yield this.calcChanges(assets).then((changes) => {
66
+ return Object.assign(Object.assign({}, changes), { update: changes.update.map((update) => {
67
+ if (update.type === 'eventbridge' || update.type === 'eventgrid') {
68
+ delete update.sink;
69
+ }
70
+ return update;
71
+ }) });
72
+ });
73
+ yield _super.processChanges.call(this, assets, changes);
74
+ });
75
+ }
76
+ }
77
+ exports.default = LogStreamsHandler;
@@ -67,5 +67,6 @@ declare const constants: {
67
67
  DATABASE_SCRIPTS_IMPORT: string[];
68
68
  EMAIL_TEMPLATES_NAMES: string[];
69
69
  SUPPORTED_BRANDING_TEMPLATES: string[];
70
+ LOG_STREAMS_DIRECTORY: string;
70
71
  };
71
72
  export default constants;
@@ -164,5 +164,6 @@ const constants = {
164
164
  `${EMAIL_USER_INVITATION}.html`,
165
165
  ],
166
166
  SUPPORTED_BRANDING_TEMPLATES: [UNIVERSAL_LOGIN_TEMPLATE],
167
+ LOG_STREAMS_DIRECTORY: 'log-streams',
167
168
  };
168
169
  exports.default = constants;
@@ -72,6 +72,7 @@ declare const _default: {
72
72
  DATABASE_SCRIPTS_IMPORT: string[];
73
73
  EMAIL_TEMPLATES_NAMES: string[];
74
74
  SUPPORTED_BRANDING_TEMPLATES: string[];
75
+ LOG_STREAMS_DIRECTORY: string;
75
76
  };
76
77
  deploy: typeof deploy;
77
78
  keywordReplace: typeof keywordReplace;
@@ -56,8 +56,8 @@ exports.keywordStringReplace = keywordStringReplace;
56
56
  function keywordReplace(input, mappings) {
57
57
  // Replace keywords with mappings within input.
58
58
  if (mappings && Object.keys(mappings).length > 0) {
59
- input = keywordStringReplace(input, mappings);
60
59
  input = keywordArrayReplace(input, mappings);
60
+ input = keywordStringReplace(input, mappings);
61
61
  }
62
62
  return input;
63
63
  }
package/lib/types.d.ts CHANGED
@@ -109,6 +109,7 @@ export declare type BaseAuth0APIClient = {
109
109
  }) => Promise<Promise<Asset[]>>;
110
110
  addSecrets: (arg0: {}, arg1: Asset) => Promise<void>;
111
111
  };
112
+ logStreams: APIClientBaseFunctions;
112
113
  migrations: APIClientBaseFunctions & {
113
114
  getMigrations: () => Promise<{
114
115
  flags: Asset[];
@@ -228,6 +229,7 @@ export declare type Assets = {
228
229
  policies: Asset[];
229
230
  };
230
231
  hooks: Asset[];
232
+ logStreams: Asset[];
231
233
  migrations: Asset[];
232
234
  organizations: Asset[];
233
235
  pages: Asset[];
@@ -248,7 +250,7 @@ export declare type CalculatedChanges = {
248
250
  conflicts: Asset[];
249
251
  create: Asset[];
250
252
  };
251
- export declare type AssetTypes = 'rules' | 'rulesConfigs' | 'hooks' | 'pages' | 'databases' | 'clientGrants' | 'resourceServers' | 'clients' | 'connections' | 'tenant' | 'emailProvider' | 'emailTemplates' | 'guardianFactors' | 'guardianFactorProviders' | 'guardianFactorTemplates' | 'migrations' | 'guardianPhoneFactorMessageTypes' | 'guardianPhoneFactorSelectedProvider' | 'guardianPolicies' | 'roles' | 'actions' | 'organizations' | 'triggers' | 'attackProtection' | 'branding';
253
+ export declare type AssetTypes = 'rules' | 'rulesConfigs' | 'hooks' | 'pages' | 'databases' | 'clientGrants' | 'resourceServers' | 'clients' | 'connections' | 'tenant' | 'emailProvider' | 'emailTemplates' | 'guardianFactors' | 'guardianFactorProviders' | 'guardianFactorTemplates' | 'migrations' | 'guardianPhoneFactorMessageTypes' | 'guardianPhoneFactorSelectedProvider' | 'guardianPolicies' | 'roles' | 'actions' | 'organizations' | 'triggers' | 'attackProtection' | 'branding' | 'logStreams';
252
254
  export declare type KeywordMappings = {
253
255
  [key: string]: (string | number)[] | string | number;
254
256
  };
package/lib/utils.d.ts CHANGED
@@ -30,6 +30,7 @@ export declare function stripIdentifiers(auth0: Auth0, assets: Assets): {
30
30
  policies: Asset[];
31
31
  };
32
32
  hooks: Asset[];
33
+ logStreams: Asset[];
33
34
  migrations: Asset[];
34
35
  organizations: Asset[];
35
36
  pages: Asset[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auth0-deploy-cli",
3
- "version": "7.8.0",
3
+ "version": "7.9.0",
4
4
  "description": "A command line tool for deploying updates to your Auth0 tenant",
5
5
  "main": "lib/index.js",
6
6
  "bin": {
@@ -40,20 +40,20 @@
40
40
  "global-agent": "^2.1.12",
41
41
  "js-yaml": "^4.1.0",
42
42
  "lodash": "^4.17.20",
43
- "mkdirp": "^0.5.1",
43
+ "mkdirp": "^0.5.6",
44
44
  "nconf": "^0.11.4",
45
45
  "promise-pool-executor": "^1.1.1",
46
46
  "sanitize-filename": "^1.6.1",
47
47
  "sinon": "^13.0.1",
48
48
  "sinon-chai": "^3.7.0",
49
- "winston": "^3.3.0",
49
+ "winston": "^3.6.0",
50
50
  "yargs": "^15.3.1"
51
51
  },
52
52
  "devDependencies": {
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.16.0",
56
+ "@typescript-eslint/parser": "^5.17.0",
57
57
  "chai-as-promised": "^7.1.1",
58
58
  "cross-env": "^3.1.4",
59
59
  "eslint": "^7.28.0",
@@ -69,6 +69,6 @@
69
69
  "rimraf": "^3.0.2",
70
70
  "rmdir-sync": "^1.0.1",
71
71
  "ts-mocha": "^9.0.2",
72
- "typescript": "^4.6.2"
72
+ "typescript": "^4.6.3"
73
73
  }
74
74
  }