@knocklabs/cli 1.0.0 → 1.0.2

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.
@@ -0,0 +1,106 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return AudienceOpen;
9
+ }
10
+ });
11
+ const _core = require("@oclif/core");
12
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _browser = require("../../lib/helpers/browser");
14
+ const _error = require("../../lib/helpers/error");
15
+ const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
16
+ const _request = require("../../lib/helpers/request");
17
+ const _urls = require("../../lib/urls");
18
+ function _define_property(obj, key, value) {
19
+ if (key in obj) {
20
+ Object.defineProperty(obj, key, {
21
+ value: value,
22
+ enumerable: true,
23
+ configurable: true,
24
+ writable: true
25
+ });
26
+ } else {
27
+ obj[key] = value;
28
+ }
29
+ return obj;
30
+ }
31
+ function _interop_require_default(obj) {
32
+ return obj && obj.__esModule ? obj : {
33
+ default: obj
34
+ };
35
+ }
36
+ function _getRequireWildcardCache(nodeInterop) {
37
+ if (typeof WeakMap !== "function") return null;
38
+ var cacheBabelInterop = new WeakMap();
39
+ var cacheNodeInterop = new WeakMap();
40
+ return (_getRequireWildcardCache = function(nodeInterop) {
41
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
42
+ })(nodeInterop);
43
+ }
44
+ function _interop_require_wildcard(obj, nodeInterop) {
45
+ if (!nodeInterop && obj && obj.__esModule) {
46
+ return obj;
47
+ }
48
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
49
+ return {
50
+ default: obj
51
+ };
52
+ }
53
+ var cache = _getRequireWildcardCache(nodeInterop);
54
+ if (cache && cache.has(obj)) {
55
+ return cache.get(obj);
56
+ }
57
+ var newObj = {
58
+ __proto__: null
59
+ };
60
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
61
+ for(var key in obj){
62
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
63
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
64
+ if (desc && (desc.get || desc.set)) {
65
+ Object.defineProperty(newObj, key, desc);
66
+ } else {
67
+ newObj[key] = obj[key];
68
+ }
69
+ }
70
+ }
71
+ newObj.default = obj;
72
+ if (cache) {
73
+ cache.set(obj, newObj);
74
+ }
75
+ return newObj;
76
+ }
77
+ class AudienceOpen extends _basecommand.default {
78
+ async run() {
79
+ const whoamiResp = await this.apiV1.whoami();
80
+ if (!(0, _request.isSuccessResp)(whoamiResp)) {
81
+ const message = (0, _request.formatErrorRespMessage)(whoamiResp);
82
+ _core.ux.error(new _error.ApiError(message));
83
+ }
84
+ const { account_slug } = whoamiResp.data;
85
+ const { audienceKey } = this.props.args;
86
+ const { environment, branch } = this.props.flags;
87
+ const envOrBranch = branch !== null && branch !== void 0 ? branch : environment;
88
+ const url = (0, _urls.viewAudienceUrl)(this.sessionContext.dashboardOrigin, account_slug, envOrBranch, audienceKey);
89
+ this.log(`‣ Opening audience \`${audienceKey}\` in the Knock dashboard...`);
90
+ this.log(` ${url}`);
91
+ await _browser.browser.openUrl(url);
92
+ }
93
+ }
94
+ _define_property(AudienceOpen, "summary", "Open an audience in the Knock dashboard.");
95
+ _define_property(AudienceOpen, "flags", {
96
+ environment: _core.Flags.string({
97
+ default: "development",
98
+ summary: "The environment to use."
99
+ }),
100
+ branch: _flag.branch
101
+ });
102
+ _define_property(AudienceOpen, "args", {
103
+ audienceKey: _core.Args.string({
104
+ required: true
105
+ })
106
+ });
@@ -0,0 +1,214 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return AudiencePull;
9
+ }
10
+ });
11
+ const _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
12
+ const _core = require("@oclif/core");
13
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
14
+ const _command = require("../../lib/helpers/command");
15
+ const _error = require("../../lib/helpers/error");
16
+ const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
17
+ const _projectconfig = require("../../lib/helpers/project-config");
18
+ const _ux = require("../../lib/helpers/ux");
19
+ const _audience = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/audience"));
20
+ const _runcontext = require("../../lib/run-context");
21
+ function _define_property(obj, key, value) {
22
+ if (key in obj) {
23
+ Object.defineProperty(obj, key, {
24
+ value: value,
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true
28
+ });
29
+ } else {
30
+ obj[key] = value;
31
+ }
32
+ return obj;
33
+ }
34
+ function _interop_require_default(obj) {
35
+ return obj && obj.__esModule ? obj : {
36
+ default: obj
37
+ };
38
+ }
39
+ function _getRequireWildcardCache(nodeInterop) {
40
+ if (typeof WeakMap !== "function") return null;
41
+ var cacheBabelInterop = new WeakMap();
42
+ var cacheNodeInterop = new WeakMap();
43
+ return (_getRequireWildcardCache = function(nodeInterop) {
44
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
45
+ })(nodeInterop);
46
+ }
47
+ function _interop_require_wildcard(obj, nodeInterop) {
48
+ if (!nodeInterop && obj && obj.__esModule) {
49
+ return obj;
50
+ }
51
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
52
+ return {
53
+ default: obj
54
+ };
55
+ }
56
+ var cache = _getRequireWildcardCache(nodeInterop);
57
+ if (cache && cache.has(obj)) {
58
+ return cache.get(obj);
59
+ }
60
+ var newObj = {
61
+ __proto__: null
62
+ };
63
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
64
+ for(var key in obj){
65
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
66
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
67
+ if (desc && (desc.get || desc.set)) {
68
+ Object.defineProperty(newObj, key, desc);
69
+ } else {
70
+ newObj[key] = obj[key];
71
+ }
72
+ }
73
+ }
74
+ newObj.default = obj;
75
+ if (cache) {
76
+ cache.set(obj, newObj);
77
+ }
78
+ return newObj;
79
+ }
80
+ class AudiencePull extends _basecommand.default {
81
+ async run() {
82
+ const { args, flags } = this.props;
83
+ if (flags.all && args.audienceKey) {
84
+ return this.error(`audienceKey arg \`${args.audienceKey}\` cannot also be provided when using --all`);
85
+ }
86
+ return flags.all ? this.pullAllAudiences() : this.pullOneAudience();
87
+ }
88
+ // Pull one audience
89
+ async pullOneAudience() {
90
+ const { flags } = this.props;
91
+ const dirContext = await this.getAudienceDirContext();
92
+ if (dirContext.exists) {
93
+ this.log(`‣ Found \`${dirContext.key}\` at ${dirContext.abspath}`);
94
+ } else {
95
+ const prompt = `Create a new audience directory \`${dirContext.key}\` at ${dirContext.abspath}?`;
96
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
97
+ if (!input) return;
98
+ }
99
+ _ux.spinner.start("‣ Loading");
100
+ try {
101
+ const audience = await this.apiV1.mgmtClient.audiences.retrieve(dirContext.key, {
102
+ environment: flags.environment,
103
+ branch: flags.branch,
104
+ annotate: true,
105
+ hide_uncommitted_changes: flags["hide-uncommitted-changes"]
106
+ });
107
+ _ux.spinner.stop();
108
+ // The SDK doesn't include annotation types, but the API returns them when annotate=true
109
+ await _audience.writeAudienceDirFromData(dirContext, audience, {
110
+ withSchema: true
111
+ });
112
+ const action = dirContext.exists ? "updated" : "created";
113
+ const scope = (0, _command.formatCommandScope)(flags);
114
+ this.log(`‣ Successfully ${action} \`${dirContext.key}\` at ${dirContext.abspath} using ${scope}`);
115
+ } catch (error) {
116
+ _ux.spinner.stop();
117
+ _core.ux.error(new _error.ApiError(error.message));
118
+ }
119
+ }
120
+ // Pull all audiences
121
+ async pullAllAudiences() {
122
+ const { flags } = this.props;
123
+ const audiencesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "audience", this.runContext.cwd);
124
+ const targetDirCtx = flags["audiences-dir"] || audiencesIndexDirCtx;
125
+ const prompt = targetDirCtx.exists ? `Pull latest audiences into ${targetDirCtx.abspath}?\n This will overwrite the contents of this directory.` : `Create a new audiences directory at ${targetDirCtx.abspath}?`;
126
+ const input = flags.force || await (0, _ux.promptToConfirm)(prompt);
127
+ if (!input) return;
128
+ _ux.spinner.start(`‣ Loading`);
129
+ try {
130
+ const audiences = await this.listAllAudiences();
131
+ // The SDK doesn't include annotation types, but the API returns them when annotate=true
132
+ await _audience.writeAudiencesIndexDir(targetDirCtx, audiences, {
133
+ withSchema: true
134
+ });
135
+ _ux.spinner.stop();
136
+ const action = targetDirCtx.exists ? "updated" : "created";
137
+ const scope = (0, _command.formatCommandScope)(flags);
138
+ this.log(`‣ Successfully ${action} the audiences directory at ${targetDirCtx.abspath} using ${scope}`);
139
+ } catch (error) {
140
+ _ux.spinner.stop();
141
+ _core.ux.error(new _error.ApiError(error.message));
142
+ }
143
+ }
144
+ async listAllAudiences() {
145
+ const { flags } = this.props;
146
+ const audiences = [];
147
+ for await (const audience of this.apiV1.mgmtClient.audiences.list({
148
+ environment: flags.environment,
149
+ branch: flags.branch,
150
+ annotate: true,
151
+ hide_uncommitted_changes: flags["hide-uncommitted-changes"]
152
+ })){
153
+ // The SDK doesn't include annotation types, but the API returns them when annotate=true
154
+ audiences.push(audience);
155
+ }
156
+ return audiences;
157
+ }
158
+ async getAudienceDirContext() {
159
+ const { audienceKey } = this.props.args;
160
+ const { resourceDir, cwd: runCwd } = this.runContext;
161
+ // Inside an existing resource dir, use it if valid for the target audience.
162
+ if (resourceDir) {
163
+ const target = {
164
+ commandId: _basecommand.default.id,
165
+ type: "audience",
166
+ key: audienceKey
167
+ };
168
+ return (0, _runcontext.ensureResourceDirForTarget)(resourceDir, target);
169
+ }
170
+ const audiencesIndexDirCtx = await (0, _projectconfig.resolveResourceDir)(this.projectConfig, "audience", runCwd);
171
+ // Not inside any existing audience directory, which means either create a
172
+ // new audience directory in the cwd, or update it if there is one already.
173
+ if (audienceKey) {
174
+ const dirPath = _nodepath.resolve(audiencesIndexDirCtx.abspath, audienceKey);
175
+ const exists = await _audience.isAudienceDir(dirPath);
176
+ return {
177
+ type: "audience",
178
+ key: audienceKey,
179
+ abspath: dirPath,
180
+ exists
181
+ };
182
+ }
183
+ // Not in any audience directory, nor an audience key arg was given so error.
184
+ return this.error("Missing 1 required arg:\naudienceKey");
185
+ }
186
+ }
187
+ _define_property(AudiencePull, "summary", "Pull one or more audiences from an environment into a local file system.");
188
+ _define_property(AudiencePull, "flags", {
189
+ environment: _core.Flags.string({
190
+ default: "development",
191
+ summary: "The environment to use."
192
+ }),
193
+ branch: _flag.branch,
194
+ all: _core.Flags.boolean({
195
+ summary: "Whether to pull all audiences from the specified environment."
196
+ }),
197
+ "audiences-dir": _flag.dirPath({
198
+ summary: "The target directory path to pull all audiences into.",
199
+ dependsOn: [
200
+ "all"
201
+ ]
202
+ }),
203
+ "hide-uncommitted-changes": _core.Flags.boolean({
204
+ summary: "Hide any uncommitted changes."
205
+ }),
206
+ force: _core.Flags.boolean({
207
+ summary: "Remove the confirmation prompt."
208
+ })
209
+ });
210
+ _define_property(AudiencePull, "args", {
211
+ audienceKey: _core.Args.string({
212
+ required: false
213
+ })
214
+ });
@@ -0,0 +1,167 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return AudiencePush;
9
+ }
10
+ });
11
+ const _core = require("@oclif/core");
12
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _command = require("../../lib/helpers/command");
14
+ const _const = require("../../lib/helpers/const");
15
+ const _error = require("../../lib/helpers/error");
16
+ const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
17
+ const _string = require("../../lib/helpers/string");
18
+ const _ux = require("../../lib/helpers/ux");
19
+ const _audience = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/audience"));
20
+ const _validate = /*#__PURE__*/ _interop_require_default(require("./validate"));
21
+ function _define_property(obj, key, value) {
22
+ if (key in obj) {
23
+ Object.defineProperty(obj, key, {
24
+ value: value,
25
+ enumerable: true,
26
+ configurable: true,
27
+ writable: true
28
+ });
29
+ } else {
30
+ obj[key] = value;
31
+ }
32
+ return obj;
33
+ }
34
+ function _interop_require_default(obj) {
35
+ return obj && obj.__esModule ? obj : {
36
+ default: obj
37
+ };
38
+ }
39
+ function _getRequireWildcardCache(nodeInterop) {
40
+ if (typeof WeakMap !== "function") return null;
41
+ var cacheBabelInterop = new WeakMap();
42
+ var cacheNodeInterop = new WeakMap();
43
+ return (_getRequireWildcardCache = function(nodeInterop) {
44
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
45
+ })(nodeInterop);
46
+ }
47
+ function _interop_require_wildcard(obj, nodeInterop) {
48
+ if (!nodeInterop && obj && obj.__esModule) {
49
+ return obj;
50
+ }
51
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
52
+ return {
53
+ default: obj
54
+ };
55
+ }
56
+ var cache = _getRequireWildcardCache(nodeInterop);
57
+ if (cache && cache.has(obj)) {
58
+ return cache.get(obj);
59
+ }
60
+ var newObj = {
61
+ __proto__: null
62
+ };
63
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
64
+ for(var key in obj){
65
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
66
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
67
+ if (desc && (desc.get || desc.set)) {
68
+ Object.defineProperty(newObj, key, desc);
69
+ } else {
70
+ newObj[key] = obj[key];
71
+ }
72
+ }
73
+ }
74
+ newObj.default = obj;
75
+ if (cache) {
76
+ cache.set(obj, newObj);
77
+ }
78
+ return newObj;
79
+ }
80
+ class AudiencePush extends _basecommand.default {
81
+ async run() {
82
+ const { flags } = this.props;
83
+ // 1. First read all audience directories found for the given command.
84
+ const target = await _audience.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
85
+ const [audiences, readErrors] = await _audience.readAllForCommandTarget(target);
86
+ if (readErrors.length > 0) {
87
+ this.error((0, _error.formatErrors)(readErrors, {
88
+ prependBy: "\n\n"
89
+ }));
90
+ }
91
+ if (audiences.length === 0) {
92
+ this.error(`No audience directories found in ${target.context.abspath}`);
93
+ }
94
+ // 2. Then validate them all ahead of pushing them.
95
+ _ux.spinner.start(`‣ Validating`);
96
+ const apiErrors = await _validate.default.validateAll(this.apiV1, this.props, audiences);
97
+ if (apiErrors.length > 0) {
98
+ this.error((0, _error.formatErrors)(apiErrors, {
99
+ prependBy: "\n\n"
100
+ }));
101
+ }
102
+ _ux.spinner.stop();
103
+ // 3. Finally push up each audience, abort on the first error.
104
+ _ux.spinner.start(`‣ Pushing`);
105
+ for (const audience of audiences){
106
+ try {
107
+ // eslint-disable-next-line no-await-in-loop
108
+ const resp = await this.apiV1.mgmtClient.audiences.upsert(audience.key, {
109
+ environment: flags.environment,
110
+ branch: flags.branch,
111
+ annotate: true,
112
+ commit: flags.commit,
113
+ commit_message: flags["commit-message"],
114
+ audience: audience.content
115
+ });
116
+ // Update the audience directory with the successfully pushed audience
117
+ // payload from the server.
118
+ // The SDK doesn't include annotation types, but the API returns them when annotate=true
119
+ // eslint-disable-next-line no-await-in-loop
120
+ await _audience.writeAudienceDirFromData(audience, resp.audience, {
121
+ withSchema: true
122
+ });
123
+ } catch (error) {
124
+ const sourceError = new _error.SourceError(error.message, _audience.audienceJsonPath(audience), "ApiError");
125
+ this.error((0, _error.formatError)(sourceError));
126
+ }
127
+ }
128
+ _ux.spinner.stop();
129
+ // 4. Display a success message.
130
+ const audienceKeys = audiences.map((a)=>a.key);
131
+ const actioned = flags.commit ? "pushed and committed" : "pushed";
132
+ const scope = (0, _command.formatCommandScope)(flags);
133
+ this.log(`‣ Successfully ${actioned} ${audiences.length} audience(s) to ${scope}:\n` + (0, _string.indentString)(audienceKeys.join("\n"), 4));
134
+ }
135
+ }
136
+ _define_property(AudiencePush, "summary", "Push one or more audiences from a local file system to Knock.");
137
+ _define_property(AudiencePush, "flags", {
138
+ environment: _core.Flags.string({
139
+ summary: "The environment to push the audience to. Defaults to development.",
140
+ default: _const.KnockEnv.Development
141
+ }),
142
+ branch: _flag.branch,
143
+ all: _core.Flags.boolean({
144
+ summary: "Whether to push all audiences from the target directory."
145
+ }),
146
+ "audiences-dir": _flag.dirPath({
147
+ summary: "The target directory path to find all audiences to push.",
148
+ dependsOn: [
149
+ "all"
150
+ ]
151
+ }),
152
+ commit: _core.Flags.boolean({
153
+ summary: "Push and commit the audience(s) at the same time"
154
+ }),
155
+ "commit-message": _core.Flags.string({
156
+ summary: "Use the given value as the commit message",
157
+ char: "m",
158
+ dependsOn: [
159
+ "commit"
160
+ ]
161
+ })
162
+ });
163
+ _define_property(AudiencePush, "args", {
164
+ audienceKey: _core.Args.string({
165
+ required: false
166
+ })
167
+ });
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "default", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return AudienceValidate;
9
+ }
10
+ });
11
+ const _core = require("@oclif/core");
12
+ const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _command = require("../../lib/helpers/command");
14
+ const _const = require("../../lib/helpers/const");
15
+ const _error = require("../../lib/helpers/error");
16
+ const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/helpers/flag"));
17
+ const _string = require("../../lib/helpers/string");
18
+ const _ux = require("../../lib/helpers/ux");
19
+ const _audience = /*#__PURE__*/ _interop_require_wildcard(require("../../lib/marshal/audience"));
20
+ function _define_property(obj, key, value) {
21
+ if (key in obj) {
22
+ Object.defineProperty(obj, key, {
23
+ value: value,
24
+ enumerable: true,
25
+ configurable: true,
26
+ writable: true
27
+ });
28
+ } else {
29
+ obj[key] = value;
30
+ }
31
+ return obj;
32
+ }
33
+ function _interop_require_default(obj) {
34
+ return obj && obj.__esModule ? obj : {
35
+ default: obj
36
+ };
37
+ }
38
+ function _getRequireWildcardCache(nodeInterop) {
39
+ if (typeof WeakMap !== "function") return null;
40
+ var cacheBabelInterop = new WeakMap();
41
+ var cacheNodeInterop = new WeakMap();
42
+ return (_getRequireWildcardCache = function(nodeInterop) {
43
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
44
+ })(nodeInterop);
45
+ }
46
+ function _interop_require_wildcard(obj, nodeInterop) {
47
+ if (!nodeInterop && obj && obj.__esModule) {
48
+ return obj;
49
+ }
50
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
51
+ return {
52
+ default: obj
53
+ };
54
+ }
55
+ var cache = _getRequireWildcardCache(nodeInterop);
56
+ if (cache && cache.has(obj)) {
57
+ return cache.get(obj);
58
+ }
59
+ var newObj = {
60
+ __proto__: null
61
+ };
62
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
63
+ for(var key in obj){
64
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
65
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
66
+ if (desc && (desc.get || desc.set)) {
67
+ Object.defineProperty(newObj, key, desc);
68
+ } else {
69
+ newObj[key] = obj[key];
70
+ }
71
+ }
72
+ }
73
+ newObj.default = obj;
74
+ if (cache) {
75
+ cache.set(obj, newObj);
76
+ }
77
+ return newObj;
78
+ }
79
+ class AudienceValidate extends _basecommand.default {
80
+ async run() {
81
+ // 1. Read all audience directories found for the given command.
82
+ const target = await _audience.ensureValidCommandTarget(this.props, this.runContext, this.projectConfig);
83
+ const [audiences, readErrors] = await _audience.readAllForCommandTarget(target);
84
+ if (readErrors.length > 0) {
85
+ this.error((0, _error.formatErrors)(readErrors, {
86
+ prependBy: "\n\n"
87
+ }));
88
+ }
89
+ if (audiences.length === 0) {
90
+ this.error(`No audience directories found in ${target.context.abspath}`);
91
+ }
92
+ // 2. Validate each audience data.
93
+ _ux.spinner.start(`‣ Validating`);
94
+ const apiErrors = await AudienceValidate.validateAll(this.apiV1, this.props, audiences);
95
+ if (apiErrors.length > 0) {
96
+ this.error((0, _error.formatErrors)(apiErrors, {
97
+ prependBy: "\n\n"
98
+ }));
99
+ }
100
+ _ux.spinner.stop();
101
+ // 3. Display a success message.
102
+ const audienceKeys = audiences.map((a)=>a.key);
103
+ const scope = (0, _command.formatCommandScope)({
104
+ ...this.props.flags
105
+ });
106
+ this.log(`‣ Successfully validated ${audiences.length} audience(s) using ${scope}:\n` + (0, _string.indentString)(audienceKeys.join("\n"), 4));
107
+ }
108
+ static async validateAll(api, props, audiences) {
109
+ const { flags } = props;
110
+ const errorPromises = audiences.map(async (audience)=>{
111
+ try {
112
+ await api.mgmtClient.audiences.validate(audience.key, {
113
+ environment: flags.environment,
114
+ branch: flags.branch,
115
+ audience: audience.content
116
+ });
117
+ return;
118
+ } catch (error) {
119
+ return new _error.SourceError(error.message, _audience.audienceJsonPath(audience), "ApiError");
120
+ }
121
+ });
122
+ const errors = (await Promise.all(errorPromises)).filter((e)=>Boolean(e));
123
+ return errors;
124
+ }
125
+ }
126
+ _define_property(AudienceValidate, "summary", "Validate one or more audiences from a local file system.");
127
+ _define_property(AudienceValidate, "flags", {
128
+ environment: _core.Flags.string({
129
+ summary: "The environment to validate the audience against. Defaults to development.",
130
+ default: _const.KnockEnv.Development
131
+ }),
132
+ branch: _flag.branch,
133
+ all: _core.Flags.boolean({
134
+ summary: "Whether to validate all audiences from the target directory."
135
+ }),
136
+ "audiences-dir": _flag.dirPath({
137
+ summary: "The target directory path to find all audiences to validate.",
138
+ dependsOn: [
139
+ "all"
140
+ ]
141
+ })
142
+ });
143
+ _define_property(AudienceValidate, "args", {
144
+ audienceKey: _core.Args.string({
145
+ required: false
146
+ })
147
+ });