@knocklabs/cli 1.0.0 → 1.0.3

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.
Files changed (39) hide show
  1. package/README.md +283 -76
  2. package/dist/commands/audience/archive.js +120 -0
  3. package/dist/commands/audience/get.js +169 -0
  4. package/dist/commands/audience/list.js +159 -0
  5. package/dist/commands/audience/new.js +243 -0
  6. package/dist/commands/audience/open.js +106 -0
  7. package/dist/commands/audience/pull.js +214 -0
  8. package/dist/commands/audience/push.js +172 -0
  9. package/dist/commands/audience/validate.js +147 -0
  10. package/dist/commands/branch/create.js +40 -3
  11. package/dist/commands/branch/list.js +14 -9
  12. package/dist/commands/branch/switch.js +7 -2
  13. package/dist/commands/guide/push.js +2 -1
  14. package/dist/commands/layout/push.js +2 -1
  15. package/dist/commands/message-type/push.js +2 -1
  16. package/dist/commands/partial/push.js +2 -1
  17. package/dist/commands/pull.js +19 -12
  18. package/dist/commands/push.js +24 -13
  19. package/dist/commands/translation/push.js +2 -1
  20. package/dist/commands/workflow/push.js +2 -1
  21. package/dist/lib/api-v1.js +12 -6
  22. package/dist/lib/helpers/flag.js +6 -0
  23. package/dist/lib/helpers/git.js +22 -3
  24. package/dist/lib/helpers/project-config.js +1 -0
  25. package/dist/lib/marshal/audience/generator.js +38 -0
  26. package/dist/lib/marshal/audience/helpers.js +142 -0
  27. package/dist/lib/marshal/audience/index.js +23 -0
  28. package/dist/lib/marshal/audience/processor.isomorphic.js +25 -0
  29. package/dist/lib/marshal/audience/reader.js +149 -0
  30. package/dist/lib/marshal/audience/types.js +15 -0
  31. package/dist/lib/marshal/audience/writer.js +177 -0
  32. package/dist/lib/marshal/index.isomorphic.js +18 -14
  33. package/dist/lib/marshal/translation/helpers.js +2 -1
  34. package/dist/lib/marshal/translation/reader.js +1 -1
  35. package/dist/lib/resources.js +3 -0
  36. package/dist/lib/run-context/loader.js +9 -20
  37. package/dist/lib/urls.js +4 -0
  38. package/oclif.manifest.json +879 -188
  39. package/package.json +10 -10
@@ -8,9 +8,13 @@ Object.defineProperty(exports, "default", {
8
8
  return BranchCreate;
9
9
  }
10
10
  });
11
+ const _enquirer = require("enquirer");
11
12
  const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
12
13
  const _arg = require("../../lib/helpers/arg");
14
+ const _const = require("../../lib/helpers/const");
15
+ const _git = require("../../lib/helpers/git");
13
16
  const _request = require("../../lib/helpers/request");
17
+ const _string = require("../../lib/helpers/string");
14
18
  function _define_property(obj, key, value) {
15
19
  if (key in obj) {
16
20
  Object.defineProperty(obj, key, {
@@ -32,12 +36,45 @@ function _interop_require_default(obj) {
32
36
  class BranchCreate extends _basecommand.default {
33
37
  async run() {
34
38
  const { args, flags } = this.props;
35
- const resp = await this.request(args.slug);
39
+ // If slug is provided, use it directly
40
+ let slug = args.slug;
41
+ // Otherwise, prompt for it with Git branch as default
42
+ if (!slug) {
43
+ slug = await this.promptForBranchSlug();
44
+ }
45
+ if (!slug) {
46
+ return this.error("Invalid slug provided");
47
+ }
48
+ const resp = await this.request(slug);
36
49
  if (flags.json) return resp;
37
50
  this.render(resp);
38
51
  }
52
+ async promptForBranchSlug() {
53
+ const gitBranch = (0, _git.getCurrentGitBranch)();
54
+ const initial = gitBranch ? (0, _string.slugify)(gitBranch) : undefined;
55
+ try {
56
+ const response = await (0, _enquirer.prompt)({
57
+ type: "input",
58
+ name: "slug",
59
+ message: "Branch slug",
60
+ initial,
61
+ validate: (value)=>{
62
+ const slugified = (0, _string.slugify)(value);
63
+ if (!slugified) {
64
+ return "Invalid slug provided";
65
+ }
66
+ return true;
67
+ }
68
+ });
69
+ return (0, _string.slugify)(response.slug);
70
+ } catch {
71
+ return undefined;
72
+ }
73
+ }
39
74
  async request(slug) {
40
- return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.post(`/v1/branches/${slug}`));
75
+ return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.branches.create(slug, {
76
+ environment: _const.KnockEnv.Development
77
+ }));
41
78
  }
42
79
  async render(data) {
43
80
  this.log(`‣ Successfully created branch \`${data.slug}\``);
@@ -48,7 +85,7 @@ _define_property(BranchCreate, "summary", "Creates a new branch off of the devel
48
85
  _define_property(BranchCreate, "enableJsonFlag", true);
49
86
  _define_property(BranchCreate, "args", {
50
87
  slug: _arg.CustomArgs.slug({
51
- required: true,
88
+ required: false,
52
89
  description: "The slug for the new branch"
53
90
  })
54
91
  });
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "default", {
10
10
  });
11
11
  const _core = require("@oclif/core");
12
12
  const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
13
+ const _const = require("../../lib/helpers/const");
13
14
  const _date = require("../../lib/helpers/date");
14
15
  const _page = require("../../lib/helpers/page");
15
16
  const _request = require("../../lib/helpers/request");
@@ -43,28 +44,32 @@ class BranchList extends _basecommand.default {
43
44
  ...this.props.flags,
44
45
  ...pageParams
45
46
  });
46
- return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.get("/v1/branches", {
47
- query: queryParams
47
+ return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.branches.list({
48
+ environment: _const.KnockEnv.Development,
49
+ ...queryParams
48
50
  }));
49
51
  }
50
52
  async render(data) {
51
53
  const { entries } = data;
52
54
  this.log(`‣ Showing ${entries.length} branches off of the development environment\n`);
53
- _core.ux.table(entries, {
55
+ const formattedBranches = entries.map((entry)=>({
56
+ slug: entry.slug,
57
+ created_at: (0, _date.formatDate)(entry.created_at),
58
+ updated_at: (0, _date.formatDate)(entry.updated_at),
59
+ last_commit_at: entry.last_commit_at ? (0, _date.formatDate)(entry.last_commit_at) : "Never"
60
+ }));
61
+ _core.ux.table(formattedBranches, {
54
62
  slug: {
55
63
  header: "Slug"
56
64
  },
57
65
  created_at: {
58
- header: "Created at",
59
- get: (entry)=>(0, _date.formatDate)(entry.created_at)
66
+ header: "Created at"
60
67
  },
61
68
  updated_at: {
62
- header: "Updated at",
63
- get: (entry)=>(0, _date.formatDate)(entry.updated_at)
69
+ header: "Updated at"
64
70
  },
65
71
  last_commit_at: {
66
- header: "Last commit at",
67
- get: (entry)=>entry.last_commit_at ? (0, _date.formatDate)(entry.last_commit_at) : "Never"
72
+ header: "Last commit at"
68
73
  }
69
74
  });
70
75
  return this.prompt(data);
@@ -15,6 +15,7 @@ const _fsextra = /*#__PURE__*/ _interop_require_wildcard(require("fs-extra"));
15
15
  const _basecommand = /*#__PURE__*/ _interop_require_default(require("../../lib/base-command"));
16
16
  const _arg = require("../../lib/helpers/arg");
17
17
  const _branch = require("../../lib/helpers/branch");
18
+ const _const = require("../../lib/helpers/const");
18
19
  const _error = require("../../lib/helpers/error");
19
20
  const _git = require("../../lib/helpers/git");
20
21
  const _request = require("../../lib/helpers/request");
@@ -132,12 +133,16 @@ class BranchSwitch extends _basecommand.default {
132
133
  }
133
134
  }
134
135
  async fetchBranch(slug) {
135
- return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.get(`/v1/branches/${slug}`), {
136
+ return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.branches.retrieve(slug, {
137
+ environment: _const.KnockEnv.Development
138
+ }), {
136
139
  action: "‣ Fetching branch"
137
140
  });
138
141
  }
139
142
  async createBranch(slug) {
140
- return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.post(`/v1/branches/${slug}`), {
143
+ return (0, _request.withSpinnerV2)(()=>this.apiV1.mgmtClient.branches.create(slug, {
144
+ environment: _const.KnockEnv.Development
145
+ }), {
141
146
  action: "‣ Creating branch"
142
147
  });
143
148
  }
@@ -162,7 +162,8 @@ _define_property(GuidePush, "flags", {
162
162
  dependsOn: [
163
163
  "commit"
164
164
  ]
165
- })
165
+ }),
166
+ force: _flag.force
166
167
  });
167
168
  _define_property(GuidePush, "args", {
168
169
  guideKey: _core.Args.string({
@@ -168,7 +168,8 @@ _define_property(EmailLayoutPush, "flags", {
168
168
  dependsOn: [
169
169
  "commit"
170
170
  ]
171
- })
171
+ }),
172
+ force: _flag.force
172
173
  });
173
174
  _define_property(EmailLayoutPush, "args", {
174
175
  emailLayoutKey: _core.Args.string({
@@ -165,7 +165,8 @@ _define_property(MessageTypePush, "flags", {
165
165
  dependsOn: [
166
166
  "commit"
167
167
  ]
168
- })
168
+ }),
169
+ force: _flag.force
169
170
  });
170
171
  _define_property(MessageTypePush, "args", {
171
172
  messageTypeKey: _core.Args.string({
@@ -165,7 +165,8 @@ _define_property(PartialPush, "flags", {
165
165
  dependsOn: [
166
166
  "commit"
167
167
  ]
168
- })
168
+ }),
169
+ force: _flag.force
169
170
  });
170
171
  _define_property(PartialPush, "args", {
171
172
  partialKey: _core.Args.string({
@@ -15,12 +15,13 @@ const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../lib/helpers/fl
15
15
  const _projectconfig = require("../lib/helpers/project-config");
16
16
  const _ux = require("../lib/helpers/ux");
17
17
  const _resources = require("../lib/resources");
18
- const _pull = /*#__PURE__*/ _interop_require_default(require("./guide/pull"));
19
- const _pull1 = /*#__PURE__*/ _interop_require_default(require("./layout/pull"));
20
- const _pull2 = /*#__PURE__*/ _interop_require_default(require("./message-type/pull"));
21
- const _pull3 = /*#__PURE__*/ _interop_require_default(require("./partial/pull"));
22
- const _pull4 = /*#__PURE__*/ _interop_require_default(require("./translation/pull"));
23
- const _pull5 = /*#__PURE__*/ _interop_require_default(require("./workflow/pull"));
18
+ const _pull = /*#__PURE__*/ _interop_require_default(require("./audience/pull"));
19
+ const _pull1 = /*#__PURE__*/ _interop_require_default(require("./guide/pull"));
20
+ const _pull2 = /*#__PURE__*/ _interop_require_default(require("./layout/pull"));
21
+ const _pull3 = /*#__PURE__*/ _interop_require_default(require("./message-type/pull"));
22
+ const _pull4 = /*#__PURE__*/ _interop_require_default(require("./partial/pull"));
23
+ const _pull5 = /*#__PURE__*/ _interop_require_default(require("./translation/pull"));
24
+ const _pull6 = /*#__PURE__*/ _interop_require_default(require("./workflow/pull"));
24
25
  function _define_property(obj, key, value) {
25
26
  if (key in obj) {
26
27
  Object.defineProperty(obj, key, {
@@ -140,39 +141,45 @@ _define_property(Pull, "flags", {
140
141
  const runResourcePullCommand = async (resourceType, targetDirCtx, args)=>{
141
142
  const subdirPath = _nodepath.resolve(targetDirCtx.abspath, _resources.RESOURCE_SUBDIRS[resourceType]);
142
143
  switch(resourceType){
144
+ case "audience":
145
+ return _pull.default.run([
146
+ ...args,
147
+ "--audiences-dir",
148
+ subdirPath
149
+ ]);
143
150
  case "email_layout":
144
- return _pull1.default.run([
151
+ return _pull2.default.run([
145
152
  ...args,
146
153
  "--layouts-dir",
147
154
  subdirPath
148
155
  ]);
149
156
  case "partial":
150
- return _pull3.default.run([
157
+ return _pull4.default.run([
151
158
  ...args,
152
159
  "--partials-dir",
153
160
  subdirPath
154
161
  ]);
155
162
  // TODO(KNO-9451): Include translation in the knock pull
156
163
  case "translation":
157
- return _pull4.default.run([
164
+ return _pull5.default.run([
158
165
  ...args,
159
166
  "--translations-dir",
160
167
  subdirPath
161
168
  ]);
162
169
  case "workflow":
163
- return _pull5.default.run([
170
+ return _pull6.default.run([
164
171
  ...args,
165
172
  "--workflows-dir",
166
173
  subdirPath
167
174
  ]);
168
175
  case "message_type":
169
- return _pull2.default.run([
176
+ return _pull3.default.run([
170
177
  ...args,
171
178
  "--message-types-dir",
172
179
  subdirPath
173
180
  ]);
174
181
  case "guide":
175
- return _pull.default.run([
182
+ return _pull1.default.run([
176
183
  ...args,
177
184
  "--guides-dir",
178
185
  subdirPath
@@ -16,12 +16,13 @@ const _const = require("../lib/helpers/const");
16
16
  const _flag = /*#__PURE__*/ _interop_require_wildcard(require("../lib/helpers/flag"));
17
17
  const _projectconfig = require("../lib/helpers/project-config");
18
18
  const _resources = require("../lib/resources");
19
- const _push = /*#__PURE__*/ _interop_require_default(require("./guide/push"));
20
- const _push1 = /*#__PURE__*/ _interop_require_default(require("./layout/push"));
21
- const _push2 = /*#__PURE__*/ _interop_require_default(require("./message-type/push"));
22
- const _push3 = /*#__PURE__*/ _interop_require_default(require("./partial/push"));
23
- const _push4 = /*#__PURE__*/ _interop_require_default(require("./translation/push"));
24
- const _push5 = /*#__PURE__*/ _interop_require_default(require("./workflow/push"));
19
+ const _push = /*#__PURE__*/ _interop_require_default(require("./audience/push"));
20
+ const _push1 = /*#__PURE__*/ _interop_require_default(require("./guide/push"));
21
+ const _push2 = /*#__PURE__*/ _interop_require_default(require("./layout/push"));
22
+ const _push3 = /*#__PURE__*/ _interop_require_default(require("./message-type/push"));
23
+ const _push4 = /*#__PURE__*/ _interop_require_default(require("./partial/push"));
24
+ const _push5 = /*#__PURE__*/ _interop_require_default(require("./translation/push"));
25
+ const _push6 = /*#__PURE__*/ _interop_require_default(require("./workflow/push"));
25
26
  function _define_property(obj, key, value) {
26
27
  if (key in obj) {
27
28
  Object.defineProperty(obj, key, {
@@ -111,6 +112,9 @@ class Push extends _basecommand.default {
111
112
  ...flags["commit-message"] ? [
112
113
  "--commit-message",
113
114
  flags["commit-message"]
115
+ ] : [],
116
+ ...flags.force ? [
117
+ "--force"
114
118
  ] : []
115
119
  ];
116
120
  // Note: Because we're pushing the different resource types sequentially,
@@ -146,7 +150,8 @@ _define_property(Push, "flags", {
146
150
  dependsOn: [
147
151
  "commit"
148
152
  ]
149
- })
153
+ }),
154
+ force: _flag.force
150
155
  });
151
156
  const runResourcePushCommand = async (resourceType, targetDirCtx, args)=>{
152
157
  const subdirPath = _nodepath.resolve(targetDirCtx.abspath, _resources.RESOURCE_SUBDIRS[resourceType]);
@@ -155,38 +160,44 @@ const runResourcePushCommand = async (resourceType, targetDirCtx, args)=>{
155
160
  return;
156
161
  }
157
162
  switch(resourceType){
163
+ case "audience":
164
+ return _push.default.run([
165
+ ...args,
166
+ "--audiences-dir",
167
+ subdirPath
168
+ ]);
158
169
  case "email_layout":
159
- return _push1.default.run([
170
+ return _push2.default.run([
160
171
  ...args,
161
172
  "--layouts-dir",
162
173
  subdirPath
163
174
  ]);
164
175
  case "partial":
165
- return _push3.default.run([
176
+ return _push4.default.run([
166
177
  ...args,
167
178
  "--partials-dir",
168
179
  subdirPath
169
180
  ]);
170
181
  case "translation":
171
- return _push4.default.run([
182
+ return _push5.default.run([
172
183
  ...args,
173
184
  "--translations-dir",
174
185
  subdirPath
175
186
  ]);
176
187
  case "workflow":
177
- return _push5.default.run([
188
+ return _push6.default.run([
178
189
  ...args,
179
190
  "--workflows-dir",
180
191
  subdirPath
181
192
  ]);
182
193
  case "message_type":
183
- return _push2.default.run([
194
+ return _push3.default.run([
184
195
  ...args,
185
196
  "--message-types-dir",
186
197
  subdirPath
187
198
  ]);
188
199
  case "guide":
189
- return _push.default.run([
200
+ return _push1.default.run([
190
201
  ...args,
191
202
  "--guides-dir",
192
203
  subdirPath
@@ -153,7 +153,8 @@ _define_property(TranslationPush, "flags", {
153
153
  dependsOn: [
154
154
  "commit"
155
155
  ]
156
- })
156
+ }),
157
+ force: _flag.force
157
158
  });
158
159
  _define_property(TranslationPush, "args", {
159
160
  translationRef: _core.Args.string({
@@ -162,7 +162,8 @@ _define_property(WorkflowPush, "flags", {
162
162
  dependsOn: [
163
163
  "commit"
164
164
  ]
165
- })
165
+ }),
166
+ force: _flag.force
166
167
  });
167
168
  _define_property(WorkflowPush, "args", {
168
169
  workflowKey: _core.Args.string({
@@ -73,7 +73,8 @@ class ApiV1 {
73
73
  branch: flags.branch,
74
74
  annotate: flags.annotate,
75
75
  commit: flags.commit,
76
- commit_message: flags["commit-message"]
76
+ commit_message: flags["commit-message"],
77
+ force: flags.force
77
78
  });
78
79
  const data = {
79
80
  workflow
@@ -187,7 +188,8 @@ class ApiV1 {
187
188
  branch: flags.branch,
188
189
  commit: flags.commit,
189
190
  commit_message: flags["commit-message"],
190
- namespace: translation.namespace
191
+ namespace: translation.namespace,
192
+ force: flags.force
191
193
  });
192
194
  return this.put(`/translations/${translation.locale_code}`, {
193
195
  translation
@@ -238,7 +240,8 @@ class ApiV1 {
238
240
  branch: flags.branch,
239
241
  annotate: flags.annotate,
240
242
  commit: flags.commit,
241
- commit_message: flags["commit-message"]
243
+ commit_message: flags["commit-message"],
244
+ force: flags.force
242
245
  });
243
246
  const data = {
244
247
  email_layout: layout
@@ -289,7 +292,8 @@ class ApiV1 {
289
292
  branch: flags.branch,
290
293
  annotate: flags.annotate,
291
294
  commit: flags.commit,
292
- commit_message: flags["commit-message"]
295
+ commit_message: flags["commit-message"],
296
+ force: flags.force
293
297
  });
294
298
  const data = {
295
299
  partial
@@ -347,7 +351,8 @@ class ApiV1 {
347
351
  branch: flags.branch,
348
352
  annotate: flags.annotate,
349
353
  commit: flags.commit,
350
- commit_message: flags["commit-message"]
354
+ commit_message: flags["commit-message"],
355
+ force: flags.force
351
356
  });
352
357
  const data = {
353
358
  message_type: messageType
@@ -411,7 +416,8 @@ class ApiV1 {
411
416
  branch: flags.branch,
412
417
  annotate: flags.annotate,
413
418
  commit: flags.commit,
414
- commit_message: flags["commit-message"]
419
+ commit_message: flags["commit-message"],
420
+ force: flags.force
415
421
  });
416
422
  const data = {
417
423
  guide
@@ -21,6 +21,9 @@ _export(exports, {
21
21
  get filePath () {
22
22
  return filePath;
23
23
  },
24
+ get force () {
25
+ return force;
26
+ },
24
27
  get jsonStr () {
25
28
  return jsonStr;
26
29
  },
@@ -152,3 +155,6 @@ const branch = slug({
152
155
  // Using lodash's once avoids unnecessarily reading the branch file multiple times.
153
156
  default: (0, _lodash.once)(_branch.readSlugFromBranchFile)
154
157
  });
158
+ const force = _core.Flags.boolean({
159
+ summary: "Force pushes the resource or resources to Knock, overwriting whatever is currently stored. " + "If you're using this on a non-development environment, you should also ensure you `commit` the changes."
160
+ });
@@ -2,9 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", {
3
3
  value: true
4
4
  });
5
- Object.defineProperty(exports, "isFileIgnoredByGit", {
6
- enumerable: true,
7
- get: function() {
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get getCurrentGitBranch () {
13
+ return getCurrentGitBranch;
14
+ },
15
+ get isFileIgnoredByGit () {
8
16
  return isFileIgnoredByGit;
9
17
  }
10
18
  });
@@ -23,3 +31,14 @@ const isFileIgnoredByGit = async (currDir, filePath)=>{
23
31
  return false;
24
32
  }
25
33
  };
34
+ const getCurrentGitBranch = ()=>{
35
+ try {
36
+ const branch = (0, _nodechild_process.execSync)("git rev-parse --abbrev-ref HEAD", {
37
+ stdio: "pipe",
38
+ encoding: "utf-8"
39
+ }).trim();
40
+ return branch;
41
+ } catch {
42
+ return undefined;
43
+ }
44
+ };
@@ -130,6 +130,7 @@ const findAndReadProjectConfig = async ()=>{
130
130
  return readProjectConfig(configPath);
131
131
  };
132
132
  const ResourceDirectoriesByType = {
133
+ audience: "audiences",
133
134
  workflow: "workflows",
134
135
  guide: "guides",
135
136
  partial: "partials",
@@ -0,0 +1,38 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get generateAudienceDir () {
13
+ return generateAudienceDir;
14
+ },
15
+ get scaffoldAudienceDirBundle () {
16
+ return scaffoldAudienceDirBundle;
17
+ }
18
+ });
19
+ const _processorisomorphic = require("./processor.isomorphic");
20
+ const _writer = require("./writer");
21
+ /*
22
+ * Scaffolds a new audience directory bundle with default content.
23
+ */ const scaffoldAudienceDirBundle = (attrs)=>{
24
+ const audienceJson = {
25
+ name: attrs.name,
26
+ type: attrs.type
27
+ };
28
+ if (attrs.description) {
29
+ audienceJson.description = attrs.description;
30
+ }
31
+ return {
32
+ [_processorisomorphic.AUDIENCE_JSON]: audienceJson
33
+ };
34
+ };
35
+ const generateAudienceDir = async (audienceDirCtx, attrs)=>{
36
+ const bundle = scaffoldAudienceDirBundle(attrs);
37
+ return (0, _writer.writeAudienceDirFromBundle)(audienceDirCtx, bundle);
38
+ };