contensis-cli 1.1.2-beta.1 → 1.1.2-beta.10

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 (53) hide show
  1. package/dist/commands/copy.js +70 -0
  2. package/dist/commands/copy.js.map +7 -0
  3. package/dist/commands/create.js.map +2 -2
  4. package/dist/commands/dev.js +11 -4
  5. package/dist/commands/dev.js.map +2 -2
  6. package/dist/commands/get.js +1 -0
  7. package/dist/commands/get.js.map +2 -2
  8. package/dist/commands/globalOptions.js +24 -3
  9. package/dist/commands/globalOptions.js.map +2 -2
  10. package/dist/commands/import.js +1 -6
  11. package/dist/commands/import.js.map +2 -2
  12. package/dist/commands/index.js +7 -3
  13. package/dist/commands/index.js.map +2 -2
  14. package/dist/factories/RequestHandlerFactory.js +24 -13
  15. package/dist/factories/RequestHandlerFactory.js.map +2 -2
  16. package/dist/localisation/en-GB.js +3 -1
  17. package/dist/localisation/en-GB.js.map +2 -2
  18. package/dist/mappers/DevRequests-to-RequestHanderCliArgs.js +128 -88
  19. package/dist/mappers/DevRequests-to-RequestHanderCliArgs.js.map +3 -3
  20. package/dist/providers/GitHubCliModuleProvider.js +14 -4
  21. package/dist/providers/GitHubCliModuleProvider.js.map +2 -2
  22. package/dist/providers/file-provider.js +3 -0
  23. package/dist/providers/file-provider.js.map +2 -2
  24. package/dist/services/ContensisCliService.js +61 -0
  25. package/dist/services/ContensisCliService.js.map +2 -2
  26. package/dist/services/ContensisDevService.js +30 -5
  27. package/dist/services/ContensisDevService.js.map +3 -3
  28. package/dist/shell.js +1 -0
  29. package/dist/shell.js.map +2 -2
  30. package/dist/util/api-ids.js +110 -0
  31. package/dist/util/api-ids.js.map +7 -0
  32. package/dist/util/console.printer.js.map +2 -2
  33. package/dist/version.js +1 -1
  34. package/dist/version.js.map +1 -1
  35. package/package.json +2 -3
  36. package/src/commands/copy.ts +79 -0
  37. package/src/commands/create.ts +0 -1
  38. package/src/commands/dev.ts +14 -6
  39. package/src/commands/get.ts +12 -11
  40. package/src/commands/globalOptions.ts +25 -2
  41. package/src/commands/import.ts +4 -8
  42. package/src/commands/index.ts +7 -3
  43. package/src/factories/RequestHandlerFactory.ts +38 -17
  44. package/src/localisation/en-GB.ts +3 -2
  45. package/src/mappers/DevRequests-to-RequestHanderCliArgs.ts +147 -92
  46. package/src/providers/GitHubCliModuleProvider.ts +19 -6
  47. package/src/providers/file-provider.ts +4 -0
  48. package/src/services/ContensisCliService.ts +82 -0
  49. package/src/services/ContensisDevService.ts +37 -6
  50. package/src/shell.ts +2 -1
  51. package/src/util/api-ids.ts +111 -0
  52. package/src/util/console.printer.ts +2 -1
  53. package/src/version.ts +1 -1
@@ -0,0 +1,79 @@
1
+ import { Command } from 'commander';
2
+ import { CopyField } from 'migratortron';
3
+ import { cliCommand } from '~/services/ContensisCliService';
4
+ import {
5
+ commit,
6
+ concurrency,
7
+ delivery,
8
+ entryId,
9
+ ignoreErrors,
10
+ mapContensisOpts,
11
+ outputEntries,
12
+ zenql,
13
+ } from './globalOptions';
14
+
15
+ export const makeCopyCommand = () => {
16
+ const copy = new Command()
17
+ .command('copy')
18
+ .description('copy command')
19
+ .addHelpText('after', `\n`)
20
+ .showHelpAfterError(true)
21
+ .exitOverride();
22
+
23
+ copy
24
+ .command('field')
25
+ .description('copy the contents of one content type field to another')
26
+ .argument(
27
+ '<contentTypeId>',
28
+ 'the api id of the content type containing the fields to copy'
29
+ )
30
+ .argument('<fieldId>', 'the id of the field to copy from')
31
+ .argument('<destinationId>', 'the id of the field to copy to')
32
+ .option(
33
+ '-t --template <template>',
34
+ 'apply a liquidjs template (surrounded by double quotes) to modify the copied field content'
35
+ )
36
+ .addOption(commit)
37
+ .addOption(concurrency)
38
+ .addOption(ignoreErrors)
39
+ .addOption(outputEntries)
40
+ .addOption(delivery)
41
+ .addOption(entryId)
42
+ .addOption(zenql)
43
+ .usage('<contentTypeId> <fieldId> <destinationId> (all arguments required)')
44
+ .addHelpText(
45
+ 'after',
46
+ `
47
+ Example call:
48
+ > copy field blog authorName contributors\n
49
+ > copy field blog description kicker --template "<h2>{{ source_value }}</h2>"\n`
50
+ )
51
+ .action(
52
+ async (
53
+ contentTypeId: string,
54
+ fieldId: string,
55
+ destinationId: string,
56
+ opts: any
57
+ ) => {
58
+ const { template, ...restOpts } = opts;
59
+ const copyField: CopyField = {
60
+ contentTypeId,
61
+ fieldId,
62
+ destinationId,
63
+ template: opts.template,
64
+ };
65
+
66
+ return await cliCommand(
67
+ ['copy', 'project', contentTypeId, fieldId, destinationId],
68
+ opts,
69
+ mapContensisOpts({ copyField, ...restOpts })
70
+ ).CopyEntryField({
71
+ commit: opts.commit,
72
+ fromFile: opts.fromFile,
73
+ logOutput: opts.outputEntries,
74
+ });
75
+ }
76
+ );
77
+
78
+ return copy;
79
+ };
@@ -2,7 +2,6 @@ import { Command } from 'commander';
2
2
  import { Project } from 'contensis-core-api';
3
3
  import { cliCommand } from '~/services/ContensisCliService';
4
4
  import { shell } from '~/shell';
5
- import { isUuid } from '~/util';
6
5
 
7
6
  export const makeCreateCommand = () => {
8
7
  const create = new Command()
@@ -49,20 +49,28 @@ Example call:
49
49
  dev
50
50
  .command('requests')
51
51
  .description('launch request handler for local development')
52
- .argument('[block-ids...]', 'ids of any blocks to develop locally')
52
+ .argument(
53
+ '[block-id...]',
54
+ 'id of block to develop locally and the local uri to pass requests for this block onto'
55
+ )
53
56
  .option('--args <args...>', 'override or add additional args')
54
- .usage('[block-ids...]')
57
+ .option(
58
+ '--release <release>',
59
+ 'launch a specific release version of the request handler'
60
+ )
61
+ .usage('[block-id] [local-uri]')
55
62
  .addHelpText(
56
63
  'after',
57
64
  `
58
65
  Example call:
59
- > dev requests test-block-one\n`
66
+ > dev requests test-block-one
67
+ > dev requests my-website http://localhost:8080\n`
60
68
  )
61
- .action(async (blockIds: string[] = [], opts) => {
69
+ .action(async (blockId: string[] = [], opts) => {
62
70
  await devCommand(
63
- ['dev', 'requests', blockIds.join(' ')],
71
+ ['dev', 'requests', blockId.join(' ')],
64
72
  opts
65
- ).ExecRequestHandler(blockIds, opts?.args);
73
+ ).ExecRequestHandler(blockId, opts?.args, opts.release);
66
74
  });
67
75
 
68
76
  return dev;
@@ -215,24 +215,24 @@ Example call:
215
215
  });
216
216
 
217
217
  sharedGetEntryOptions(
218
- program
219
- .command('entries')
220
- .description('get entries')
221
- .argument(
222
- '[search phrase]',
223
- 'get entries with the search phrase, use quotes for multiple words'
224
- )
218
+ program
219
+ .command('entries')
220
+ .description('get entries')
221
+ .argument(
222
+ '[search phrase]',
223
+ 'get entries with the search phrase, use quotes for multiple words'
224
+ )
225
225
  .addOption(contentTypes)
226
- .option(
226
+ .option(
227
227
  '-d --dependents',
228
- 'find and return any dependencies of all found entries'
229
- )
228
+ 'find and return any dependencies of all found entries'
229
+ )
230
230
  )
231
231
  .addOption(
232
232
  new Option(
233
233
  '--data-format <dataFormat>',
234
234
  'find and return entries of a specific data format'
235
- )
235
+ )
236
236
  .choices(['entry', 'asset', 'webpage'])
237
237
  .default('entry')
238
238
  )
@@ -298,6 +298,7 @@ Example call:
298
298
  Example call:
299
299
  > get block contensis-website
300
300
  > get block contensis-website develop latest
301
+ > get block contensis-website feature-branch 3
301
302
  `
302
303
  )
303
304
  .action(async (blockId: string, branch: string, version: string, opts) => {
@@ -1,9 +1,10 @@
1
1
  import { Command, Option } from 'commander';
2
+ import { MigrateRequest } from 'migratortron';
2
3
  import { url } from '~/util';
3
4
 
4
5
  // Map various input options into a request to be processed
5
6
  // by Migratortron / Contensis import library
6
- export const mapContensisOpts = (opts: any = {}) => ({
7
+ export const mapContensisOpts = (opts: any = {}): MigrateRequest => ({
7
8
  source:
8
9
  opts.sourceAlias || opts.sourceProjectId
9
10
  ? {
@@ -14,6 +15,8 @@ export const mapContensisOpts = (opts: any = {}) => ({
14
15
  }
15
16
  : undefined,
16
17
  models: opts.modelIds,
18
+ copyField: opts.copyField,
19
+ // convert various cli options into MigrateRequest.query format
17
20
  query:
18
21
  opts.id ||
19
22
  opts.entryIds ||
@@ -23,7 +26,8 @@ export const mapContensisOpts = (opts: any = {}) => ({
23
26
  opts.paths ||
24
27
  opts.assetType ||
25
28
  opts.contentType ||
26
- opts.dataFormat
29
+ opts.dataFormat ||
30
+ opts.deliveryApi
27
31
  ? {
28
32
  assetTypes: opts.assetType,
29
33
  contentTypeIds: opts.contentType,
@@ -33,11 +37,13 @@ export const mapContensisOpts = (opts: any = {}) => ({
33
37
  includePaths: opts.paths,
34
38
  orderBy: opts.orderBy,
35
39
  searchTerm: opts.phrase,
40
+ useDelivery: opts.deliveryApi,
36
41
  }
37
42
  : undefined,
38
43
  zenQL: opts.zenql,
39
44
  transformGuids: !opts.preserveGuids,
40
45
  ignoreErrors: opts.ignoreErrors,
46
+ concurrency: opts.concurrency ? Number(opts.concurrency) : undefined,
41
47
  });
42
48
 
43
49
  /* Output options */
@@ -81,6 +87,11 @@ const sharedSecret = new Option(
81
87
  );
82
88
 
83
89
  /* Entry get options */
90
+ export const delivery = new Option(
91
+ '-delivery --delivery-api',
92
+ 'use delivery api to get the entries'
93
+ );
94
+
84
95
  export const zenql = new Option(
85
96
  '-q --zenql <zenql>',
86
97
  'get entries with a supplied ZenQL statement'
@@ -121,6 +132,18 @@ export const ignoreErrors = new Option(
121
132
  'commit the import ignoring any reported errors'
122
133
  ).default(false);
123
134
 
135
+ export const outputEntries = new Option(
136
+ '-oe --output-entries <outputEntries>',
137
+ 'which details of the entries included in the import to output'
138
+ )
139
+ .choices(['errors', 'changes', 'all'])
140
+ .default('errors');
141
+
142
+ export const concurrency = new Option(
143
+ '-conc --concurrency <concurrency>',
144
+ 'the number of entries to load in parallel'
145
+ ).default(2);
146
+
124
147
  export const addConnectOptions = (program: Command) =>
125
148
  program.addOption(alias.hideHelp()).addOption(project.hideHelp());
126
149
 
@@ -2,9 +2,11 @@ import { Command, Option } from 'commander';
2
2
  import { cliCommand } from '~/services/ContensisCliService';
3
3
  import {
4
4
  commit,
5
+ concurrency,
5
6
  getEntryOptions,
6
7
  ignoreErrors,
7
8
  mapContensisOpts,
9
+ outputEntries,
8
10
  } from './globalOptions';
9
11
 
10
12
  export const makeImportCommand = () => {
@@ -113,14 +115,8 @@ Example call:
113
115
  '-preserve --preserve-guids',
114
116
  'include this flag when you are importing entries that you have previously exported and wish to update'
115
117
  )
116
- .addOption(
117
- new Option(
118
- '-oe --output-entries <outputEntries>',
119
- 'which details of the entries included in the import to output'
120
- )
121
- .choices(['errors', 'changes', 'all'])
122
- .default('errors')
123
- )
118
+ .addOption(concurrency)
119
+ .addOption(outputEntries)
124
120
  .addOption(ignoreErrors)
125
121
  .addHelpText(
126
122
  'after',
@@ -2,6 +2,7 @@ import { Command } from 'commander';
2
2
  import { Logger } from '~/util/logger';
3
3
  import { LIB_VERSION } from '~/version';
4
4
  import { makeConnectCommand } from './connect';
5
+ import { makeCopyCommand } from './copy';
5
6
  import { makeCreateCommand } from './create';
6
7
  import { makeDevCommand } from './dev';
7
8
  import { makeDiffCommand } from './diff';
@@ -49,6 +50,9 @@ const commands = () => {
49
50
  program.addCommand(
50
51
  addGlobalOptions(makeCreateCommand()).copyInheritedSettings(program)
51
52
  );
53
+ program.addCommand(
54
+ addGlobalOptions(makeCopyCommand()).copyInheritedSettings(program)
55
+ );
52
56
  program.addCommand(
53
57
  addConnectOptions(
54
58
  addAuthenticationOptions(makeDevCommand())
@@ -58,9 +62,9 @@ const commands = () => {
58
62
  addGlobalOptions(makeExecuteCommand()).copyInheritedSettings(program)
59
63
  );
60
64
  program.addCommand(
61
- addGlobalOptions(
62
- addImportOptions(makeDiffCommand())
63
- ).copyInheritedSettings(program)
65
+ addGlobalOptions(addImportOptions(makeDiffCommand())).copyInheritedSettings(
66
+ program
67
+ )
64
68
  );
65
69
  program.addCommand(
66
70
  addGlobalOptions(makeGetCommand()).copyInheritedSettings(program)
@@ -6,7 +6,7 @@ import { LogMessages } from '~/localisation/en-GB';
6
6
  import GitHubCliModuleProvider from '~/providers/GitHubCliModuleProvider';
7
7
 
8
8
  import ManifestProvider from '~/providers/ManifestProvider';
9
- import { appRootDir, joinPath } from '~/providers/file-provider';
9
+ import { appRootDir, checkDir, joinPath } from '~/providers/file-provider';
10
10
  import { isDebug } from '~/util/debug';
11
11
  import { Logger } from '~/util/logger';
12
12
 
@@ -21,6 +21,7 @@ export class RequestHandlerFactory {
21
21
  cmd = 'Zengenti.Contensis.RequestHandler.LocalDevelopment';
22
22
 
23
23
  prerelease;
24
+ version; // pass in a specific release version to run
24
25
 
25
26
  get exePath() {
26
27
  return path.join(this.basePath, `${this.name}-${this.moduleInfo.version}`);
@@ -35,29 +36,31 @@ export class RequestHandlerFactory {
35
36
  );
36
37
  }
37
38
 
38
- constructor(prerelease = false) {
39
+ constructor(version?: string, prerelease = false) {
39
40
  this.prerelease = prerelease;
41
+ this.version = version;
40
42
  }
41
43
 
42
44
  // Use the factory to create a request handler instance
43
45
  // handling the download and updating of the external binary
44
46
  async Create() {
45
- const { moduleInfo } = this;
46
- const firstUse = !moduleInfo?.version || moduleInfo?.version === '*';
47
+ const { moduleInfo, version } = this;
48
+ const downloadImmediately =
49
+ !moduleInfo?.version || moduleInfo?.version === '*' || this.version;
47
50
 
48
- if (firstUse) {
51
+ if (downloadImmediately) {
49
52
  // Create cli-manifest.json
50
53
  this.manifest.writeModule(this.name, this.moduleInfo);
51
54
 
52
55
  // Download for first time use (await)
53
- await this.CheckUpdate({ verbose: true });
56
+ await this.CheckUpdate({ verbose: true, version });
54
57
  }
55
58
 
56
59
  // Apply any downloaded/pending update so we launch that version
57
60
  await this.ApplyUpdate();
58
61
 
59
62
  // Fire an async update check and continue working in the background (do not await)
60
- if (!firstUse) this.CheckUpdate();
63
+ if (!downloadImmediately) this.CheckUpdate();
61
64
 
62
65
  // Return a RequestHandler ready to invoke
63
66
  return this.CreateInvoke(this);
@@ -121,11 +124,17 @@ export class RequestHandlerFactory {
121
124
  };
122
125
  }
123
126
 
124
- async CheckUpdate({ verbose = false }: { verbose?: boolean } = {}) {
125
- const { debug, log, manifest, messages, moduleInfo } = this;
127
+ async CheckUpdate({
128
+ verbose = false,
129
+ version,
130
+ }: { verbose?: boolean; version?: string } = {}) {
131
+ const { cmd, debug, log, manifest, messages, moduleInfo } = this;
132
+
126
133
  const github = new GitHubCliModuleProvider(moduleInfo.github);
134
+
127
135
  // Find latest version
128
- const release = await github.FindLatestRelease();
136
+ const release = await github.FindLatestRelease(version);
137
+
129
138
  if (verbose || debug)
130
139
  if (release)
131
140
  log.info(
@@ -137,10 +146,14 @@ export class RequestHandlerFactory {
137
146
  else
138
147
  log.warning(messages.devrequests.install.notFound(moduleInfo.github));
139
148
 
149
+ const downloadSpecificRelease =
150
+ version && !checkDir('c') && release?.tag_name;
151
+
140
152
  // Should we download an update?
141
153
  if (
142
- release?.tag_name &&
143
- ![moduleInfo.version, moduleInfo.install].includes(release.tag_name)
154
+ (release?.tag_name &&
155
+ ![moduleInfo.version, moduleInfo.install].includes(release.tag_name)) ||
156
+ downloadSpecificRelease
144
157
  ) {
145
158
  // Download platform-specific release asset
146
159
  const downloadPath = path.join(
@@ -160,6 +173,7 @@ export class RequestHandlerFactory {
160
173
  }
161
174
  try {
162
175
  await github.DownloadRelease(release, {
176
+ cmd,
163
177
  path: downloadPath,
164
178
  // Map NodeJS os platform to release asset name
165
179
  platforms: [
@@ -186,10 +200,16 @@ export class RequestHandlerFactory {
186
200
  ),
187
201
  });
188
202
 
189
- // Update module info with downloaded release
190
- this.moduleInfo.install = release.tag_name;
191
- // Write module info update to manifest so it installs on next invoke
192
- manifest.writeModule(this.name, this.moduleInfo);
203
+ if (!version) {
204
+ // Update module info with downloaded release
205
+ this.moduleInfo.install = release.tag_name;
206
+ // Write module info update to manifest so it installs on next invoke
207
+ manifest.writeModule(this.name, this.moduleInfo);
208
+ } else {
209
+ // Set module version in memory so the request handler
210
+ // will be invoked with this version this time only
211
+ this.moduleInfo.version = release.tag_name;
212
+ }
193
213
  }
194
214
  }
195
215
  }
@@ -222,4 +242,5 @@ export class RequestHandlerFactory {
222
242
  }
223
243
  }
224
244
 
225
- export const createRequestHandler = () => new RequestHandlerFactory().Create();
245
+ export const createRequestHandler = (version?: string) =>
246
+ new RequestHandlerFactory(version).Create();
@@ -607,8 +607,7 @@ export const LogMessages = {
607
607
  install: {
608
608
  notFound: (repo: string) =>
609
609
  `Could not find a release in ${repo} repo - please check github`,
610
- download: (repo: string, version: string) =>
611
- `Found release ${repo} ${version}`,
610
+ download: (repo: string, version: string) => `Found release ${version}`,
612
611
  downloading: (repo: string, version: string) =>
613
612
  `Downloading ${repo} ${version}`,
614
613
  downloadFail: (repo: string, version: string) =>
@@ -621,6 +620,8 @@ export const LogMessages = {
621
620
  )}?`,
622
621
  },
623
622
  launch: () => `Launching request handler for local development`,
623
+ overrideBlock: () => `Which block will you be running?`,
624
+ overrideUri: () => `How to access your development site`,
624
625
  spawn: () =>
625
626
  `If you see a firewall popup requesting network access, it is safe to approve`,
626
627
  exited: (code: number | null) =>