@contentstack/cli-cm-clone 2.0.0-beta.4 → 2.0.0-beta.6

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/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  MIT License
2
2
 
3
- Copyright (c) 2024 Contentstack
3
+ Copyright (c) 2026 Contentstack
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
package/README.md CHANGED
@@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone
16
16
  $ csdx COMMAND
17
17
  running command...
18
18
  $ csdx (--version)
19
- @contentstack/cli-cm-clone/2.0.0-beta.4 darwin-arm64 node-v24.12.0
19
+ @contentstack/cli-cm-clone/2.0.0-beta.6 darwin-arm64 node-v24.12.0
20
20
  $ csdx --help [COMMAND]
21
21
  USAGE
22
22
  $ csdx COMMAND
@@ -38,6 +38,62 @@ USAGE
38
38
 
39
39
  <!-- commands -->
40
40
  * [`csdx cm:stacks:clone [--source-branch <value>] [--target-branch <value>] [--source-management-token-alias <value>] [--destination-management-token-alias <value>] [-n <value>] [--type a|b] [--source-stack-api-key <value>] [--destination-stack-api-key <value>] [--import-webhook-status disable|current]`](#csdx-cmstacksclone---source-branch-value---target-branch-value---source-management-token-alias-value---destination-management-token-alias-value--n-value---type-ab---source-stack-api-key-value---destination-stack-api-key-value---import-webhook-status-disablecurrent)
41
+ * [`csdx cm:stacks:clone [--source-branch <value>] [--target-branch <value>] [--source-management-token-alias <value>] [--destination-management-token-alias <value>] [-n <value>] [--type a|b] [--source-stack-api-key <value>] [--destination-stack-api-key <value>] [--import-webhook-status disable|current]`](#csdx-cmstacksclone---source-branch-value---target-branch-value---source-management-token-alias-value---destination-management-token-alias-value--n-value---type-ab---source-stack-api-key-value---destination-stack-api-key-value---import-webhook-status-disablecurrent)
42
+
43
+ ## `csdx cm:stacks:clone [--source-branch <value>] [--target-branch <value>] [--source-management-token-alias <value>] [--destination-management-token-alias <value>] [-n <value>] [--type a|b] [--source-stack-api-key <value>] [--destination-stack-api-key <value>] [--import-webhook-status disable|current]`
44
+
45
+ Clone data (structure/content or both) of a stack into another stack
46
+
47
+ ```
48
+ USAGE
49
+ $ csdx cm:stack-clone cm:stacks:clone [--source-branch <value>] [--target-branch <value>]
50
+ [--source-management-token-alias <value>] [--destination-management-token-alias <value>] [-n <value>] [--type a|b]
51
+ [--source-stack-api-key <value>] [--destination-stack-api-key <value>] [--import-webhook-status disable|current]
52
+
53
+ FLAGS
54
+ -c, --config=<value> Path for the external configuration
55
+ -n, --stack-name=<value> Provide a name for the new stack to store the cloned content.
56
+ -y, --yes Force override all Marketplace prompts.
57
+ --destination-management-token-alias=<value> Destination management token alias.
58
+ --destination-stack-api-key=<value> Destination stack API key
59
+ --import-webhook-status=<option> [default: disable] [default: disable] (optional) The status of the
60
+ import webhook. <options: disable|current>
61
+ <options: disable|current>
62
+ --skip-audit (optional) Skips the audit fix that occurs during an import
63
+ operation.
64
+ --source-branch=<value> Branch of the source stack.
65
+ --source-branch-alias=<value> Alias of Branch of the source stack.
66
+ --source-management-token-alias=<value> Source management token alias.
67
+ --source-stack-api-key=<value> Source stack API key
68
+ --target-branch=<value> Branch of the target stack.
69
+ --target-branch-alias=<value> Alias of Branch of the target stack.
70
+ --type=<option> Type of data to clone. You can select option a or b.
71
+ a) Structure (all modules except entries & assets).
72
+ b) Structure with content (all modules including entries & assets).
73
+
74
+ <options: a|b>
75
+
76
+ DESCRIPTION
77
+ Clone data (structure/content or both) of a stack into another stack
78
+ Use this plugin to automate the process of cloning a stack in few steps.
79
+
80
+
81
+ ALIASES
82
+ $ csdx cm:stack-clone
83
+
84
+ EXAMPLES
85
+ $ csdx cm:stacks:clone
86
+
87
+ $ csdx cm:stacks:clone --source-branch <source-branch-name> --target-branch <target-branch-name> --yes
88
+
89
+ $ csdx cm:stacks:clone --source-stack-api-key <apiKey> --destination-stack-api-key <apiKey>
90
+
91
+ $ csdx cm:stacks:clone --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias>
92
+
93
+ $ csdx cm:stacks:clone --source-branch --target-branch --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias>
94
+
95
+ $ csdx cm:stacks:clone --source-branch --target-branch --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias> --type <value a or b>
96
+ ```
41
97
 
42
98
  ## `csdx cm:stacks:clone [--source-branch <value>] [--target-branch <value>] [--source-management-token-alias <value>] [--destination-management-token-alias <value>] [-n <value>] [--type a|b] [--source-stack-api-key <value>] [--destination-stack-api-key <value>] [--import-webhook-status disable|current]`
43
99
 
@@ -77,6 +133,9 @@ DESCRIPTION
77
133
  Use this plugin to automate the process of cloning a stack in few steps.
78
134
 
79
135
 
136
+ ALIASES
137
+ $ csdx cm:stack-clone
138
+
80
139
  EXAMPLES
81
140
  $ csdx cm:stacks:clone
82
141
 
@@ -91,5 +150,5 @@ EXAMPLES
91
150
  $ csdx cm:stacks:clone --source-branch --target-branch --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias> --type <value a or b>
92
151
  ```
93
152
 
94
- _See code: [src/commands/cm/stacks/clone.js](https://github.com/contentstack/cli/blob/main/packages/contentstack-clone/src/commands/cm/stacks/clone.js)_
153
+ _See code: [src/commands/cm/stacks/clone.ts](https://github.com/contentstack/cli/blob/main/packages/contentstack-clone/src/commands/cm/stacks/clone.ts)_
95
154
  <!-- commandsstop -->
package/bin/run.cmd ADDED
@@ -0,0 +1,3 @@
1
+ @echo off
2
+
3
+ node "%~dp0\run" %*
package/bin/run.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+
3
+ // eslint-disable-next-line unicorn/prefer-top-level-await
4
+ (async () => {
5
+ const oclif = await import('@oclif/core');
6
+ await oclif.execute({ development: false, dir: __dirname });
7
+ })();
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-clone",
3
3
  "description": "Contentstack stack clone plugin",
4
- "version": "2.0.0-beta.4",
4
+ "version": "2.0.0-beta.6",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/rohitmishra209/cli-cm-clone/issues",
7
7
  "dependencies": {
8
8
  "@colors/colors": "^1.6.0",
9
- "@contentstack/cli-cm-export": "~2.0.0-beta.4",
10
- "@contentstack/cli-cm-import": "~2.0.0-beta.3",
11
- "@contentstack/cli-command": "~1.7.0",
12
- "@contentstack/cli-utilities": "~1.15.0",
9
+ "@contentstack/cli-cm-export": "~2.0.0-beta.5",
10
+ "@contentstack/cli-cm-import": "~2.0.0-beta.5",
11
+ "@contentstack/cli-command": "~1.7.2",
12
+ "@contentstack/cli-utilities": "~1.17.0",
13
13
  "@oclif/core": "^4.3.0",
14
14
  "@oclif/plugin-help": "^6.2.28",
15
15
  "chalk": "^4.1.2",
@@ -22,21 +22,29 @@
22
22
  },
23
23
  "devDependencies": {
24
24
  "@oclif/test": "^4.1.13",
25
+ "@types/chai": "^4.3.0",
26
+ "@types/mocha": "^10.0.0",
27
+ "@types/node": "^14.18.63",
28
+ "@types/sinon": "^10.0.0",
29
+ "@typescript-eslint/eslint-plugin": "^5.62.0",
25
30
  "chai": "^4.5.0",
26
31
  "eslint": "^8.57.1",
27
32
  "eslint-config-oclif": "^6.0.62",
28
33
  "mocha": "^10.8.2",
29
34
  "nyc": "^15.1.0",
30
35
  "oclif": "^4.17.46",
31
- "sinon": "^19.0.5"
36
+ "sinon": "^21.0.1",
37
+ "ts-node": "^10.9.2",
38
+ "typescript": "^4.9.5"
32
39
  },
33
40
  "engines": {
34
41
  "node": ">=14.0.0"
35
42
  },
36
43
  "files": [
44
+ "/bin",
45
+ "/lib",
37
46
  "/npm-shrinkwrap.json",
38
- "/oclif.manifest.json",
39
- "/src"
47
+ "/oclif.manifest.json"
40
48
  ],
41
49
  "homepage": "https://github.com/rohitmishra209/cli-cm-clone",
42
50
  "keywords": [
@@ -45,23 +53,29 @@
45
53
  "plugin"
46
54
  ],
47
55
  "license": "MIT",
56
+ "main": "./lib/commands/cm/stacks/clone.js",
48
57
  "oclif": {
49
- "commands": "./src/commands",
58
+ "commands": "./lib/commands",
50
59
  "bin": "csdx",
51
60
  "repositoryPrefix": "<%- repo %>/blob/main/packages/contentstack-clone/<%- commandPath %>"
52
61
  },
53
62
  "repository": "https://github.com/contentstack/cli",
54
63
  "scripts": {
64
+ "build": "npm run clean && npm run compile",
65
+ "clean": "rm -rf ./lib ./node_modules tsconfig.build.tsbuildinfo",
66
+ "compile": "tsc -b tsconfig.json",
55
67
  "postpack": "rm -f oclif.manifest.json",
56
- "prepack": "oclif manifest && oclif readme",
57
- "test": "nyc --reporter=html mocha --forbid-only \"test/**/*.test.js\"",
58
- "posttest": "eslint .",
59
- "version": "oclif readme && git add README.md",
60
- "clean": "rm -rf ./node_modules tsconfig.build.tsbuildinfo"
68
+ "prepack": "pnpm compile && oclif manifest && oclif readme",
69
+ "test:report": "tsc -p test && nyc --reporter=lcov --extension .ts mocha --forbid-only \"test/**/*.test.ts\" 2>&1 | grep -v 'ERR_INVALID_ARG_TYPE' ; npx nyc report --reporter=text-summary --reporter=text || true",
70
+ "pretest": "tsc -p test",
71
+ "test:unit": "nyc --extension .ts mocha --forbid-only \"test/**/*.test.ts\" 2>&1 | grep -v 'ERR_INVALID_ARG_TYPE' ; npx nyc report --reporter=text-summary --reporter=text || true",
72
+ "lint": "eslint src/**/*.ts",
73
+ "format": "eslint src/**/*.ts --fix",
74
+ "test:unit:report": "nyc --reporter=text --reporter=text-summary --extension .ts mocha --forbid-only \"test/**/*.test.ts\""
61
75
  },
62
76
  "csdxConfig": {
63
77
  "shortCommandName": {
64
78
  "cm:stacks:clone": "CLN"
65
79
  }
66
80
  }
67
- }
81
+ }
@@ -1,350 +0,0 @@
1
- const { Command } = require('@contentstack/cli-command');
2
- const { configHandler, flags, isAuthenticated, managementSDKClient, log, handleAndLogError } = require('@contentstack/cli-utilities');
3
- const { CloneHandler } = require('../../../lib/util/clone-handler');
4
- const path = require('path');
5
- const { rimraf } = require('rimraf');
6
- const merge = require('merge');
7
- let pathdir = path.join(__dirname.split('src')[0], 'contents');
8
- const { readdirSync, readFileSync } = require('fs');
9
- let config = {};
10
-
11
- class StackCloneCommand extends Command {
12
- /**
13
- * Determine authentication method based on user preference
14
- */
15
- determineAuthenticationMethod(sourceManagementTokenAlias, destinationManagementTokenAlias) {
16
- // Track authentication method
17
- let authenticationMethod = 'unknown';
18
-
19
- // Determine authentication method based on user preference
20
- if (sourceManagementTokenAlias || destinationManagementTokenAlias) {
21
- authenticationMethod = 'Management Token';
22
- } else if (isAuthenticated()) {
23
- // Check if user is authenticated via OAuth
24
- const isOAuthUser = configHandler.get('authorisationType') === 'OAUTH' || false;
25
- if (isOAuthUser) {
26
- authenticationMethod = 'OAuth';
27
- } else {
28
- authenticationMethod = 'Basic Auth';
29
- }
30
- } else {
31
- authenticationMethod = 'Basic Auth';
32
- }
33
-
34
- return authenticationMethod;
35
- }
36
-
37
- /**
38
- * Create clone context object for logging
39
- */
40
- createCloneContext(authenticationMethod) {
41
- return {
42
- command: this.context?.info?.command || 'cm:stacks:clone',
43
- module: 'clone',
44
- email: configHandler.get('email') || '',
45
- sessionId: this.context?.sessionId || '',
46
- authenticationMethod: authenticationMethod || 'Basic Auth',
47
- };
48
- }
49
-
50
- async run() {
51
- try {
52
- let self = this;
53
- const { flags: cloneCommandFlags } = await self.parse(StackCloneCommand);
54
- const {
55
- yes,
56
- type: cloneType,
57
- 'stack-name': stackName,
58
- 'source-branch': sourceStackBranch,
59
- 'source-branch-alias': sourceStackBranchAlias,
60
- 'target-branch': targetStackBranch,
61
- 'target-branch-alias': targetStackBranchAlias,
62
- 'source-stack-api-key': sourceStackApiKey,
63
- 'destination-stack-api-key': destinationStackApiKey,
64
- 'source-management-token-alias': sourceManagementTokenAlias,
65
- 'destination-management-token-alias': destinationManagementTokenAlias,
66
- 'import-webhook-status': importWebhookStatus,
67
- config: externalConfigPath,
68
- } = cloneCommandFlags;
69
-
70
- const handleClone = async () => {
71
- const listOfTokens = configHandler.get('tokens');
72
- const authenticationMethod = this.determineAuthenticationMethod(
73
- sourceManagementTokenAlias,
74
- destinationManagementTokenAlias,
75
- );
76
- const cloneContext = this.createCloneContext(authenticationMethod);
77
- log.debug('Starting clone operation setup', cloneContext);
78
-
79
- if (externalConfigPath) {
80
- log.debug(`Loading external configuration from: ${externalConfigPath}`, cloneContext);
81
- let externalConfig = readFileSync(externalConfigPath, 'utf-8');
82
- externalConfig = JSON.parse(externalConfig);
83
- config = merge.recursive(config, externalConfig);
84
- }
85
- config.forceStopMarketplaceAppsPrompt = yes;
86
- config.skipAudit = cloneCommandFlags['skip-audit'];
87
- log.debug('Clone configuration prepared', {
88
- ...cloneContext,
89
- cloneType: config.cloneType,
90
- skipAudit: config.skipAudit,
91
- forceStopMarketplaceAppsPrompt: config.forceStopMarketplaceAppsPrompt
92
- });
93
-
94
- if (cloneType) {
95
- config.cloneType = cloneType;
96
- }
97
- if (stackName) {
98
- config.stackName = stackName;
99
- }
100
- if (sourceStackBranch) {
101
- config.sourceStackBranch = sourceStackBranch;
102
- }
103
- if (sourceStackBranchAlias) {
104
- config.sourceStackBranchAlias = sourceStackBranchAlias;
105
- }
106
- if (targetStackBranch) {
107
- config.targetStackBranch = targetStackBranch;
108
- }
109
- if (targetStackBranchAlias) {
110
- config.targetStackBranchAlias = targetStackBranchAlias;
111
- }
112
- if (sourceStackApiKey) {
113
- config.source_stack = sourceStackApiKey;
114
- }
115
- if (destinationStackApiKey) {
116
- config.target_stack = destinationStackApiKey;
117
- }
118
- if (sourceManagementTokenAlias && listOfTokens[sourceManagementTokenAlias]) {
119
- config.source_alias = sourceManagementTokenAlias;
120
- config.source_stack = listOfTokens[sourceManagementTokenAlias].apiKey;
121
- log.debug(`Using source token alias: ${sourceManagementTokenAlias}`, cloneContext);
122
- } else if (sourceManagementTokenAlias) {
123
- log.warn(`Provided source token alias (${sourceManagementTokenAlias}) not found in your config.!`, cloneContext);
124
- }
125
- if (destinationManagementTokenAlias && listOfTokens[destinationManagementTokenAlias]) {
126
- config.destination_alias = destinationManagementTokenAlias;
127
- config.target_stack = listOfTokens[destinationManagementTokenAlias].apiKey;
128
- log.debug(`Using destination token alias: ${destinationManagementTokenAlias}`, cloneContext);
129
- } else if (destinationManagementTokenAlias) {
130
- log.warn(
131
- `Provided destination token alias (${destinationManagementTokenAlias}) not found in your config.!`,
132
- cloneContext,
133
- );
134
- }
135
- if (importWebhookStatus) {
136
- config.importWebhookStatus = importWebhookStatus;
137
- }
138
-
139
- const managementAPIClient = await managementSDKClient(config);
140
- log.debug('Management API client initialized successfully', cloneContext);
141
-
142
- log.debug(`Content directory path: ${pathdir}`, cloneContext);
143
- await this.removeContentDirIfNotEmptyBeforeClone(pathdir, cloneContext); // NOTE remove if folder not empty before clone
144
- this.registerCleanupOnInterrupt(pathdir, cloneContext);
145
-
146
- config.auth_token = configHandler.get('authtoken');
147
- config.host = this.cmaHost;
148
- config.cdn = this.cdaHost;
149
- config.pathDir = pathdir;
150
- config.cloneContext = cloneContext;
151
- log.debug('Clone configuration finalized', cloneContext);
152
- const cloneHandler = new CloneHandler(config);
153
- cloneHandler.setClient(managementAPIClient);
154
- log.debug('Starting clone operation', cloneContext);
155
- cloneHandler.execute().catch((error) => {
156
- handleAndLogError(error, cloneContext);
157
- });
158
- };
159
-
160
- if (sourceManagementTokenAlias && destinationManagementTokenAlias) {
161
- if (sourceStackBranch || targetStackBranch) {
162
- if (isAuthenticated()) {
163
- handleClone();
164
- } else {
165
- log.error('Log in to execute this command,csdx auth:login', cloneContext);
166
- this.exit(1);
167
- }
168
- } else {
169
- handleClone();
170
- }
171
- } else if (isAuthenticated()) {
172
- handleClone();
173
- } else {
174
- log.error('Please login to execute this command, csdx auth:login', cloneContext);
175
- this.exit(1);
176
- }
177
- } catch (error) {
178
- if (error) {
179
- await this.cleanUp(pathdir, null, cloneContext);
180
- log.error('Stack clone command failed', { ...cloneContext, error: error?.message || error });
181
- }
182
- }
183
- }
184
-
185
-
186
-
187
- async removeContentDirIfNotEmptyBeforeClone(dir, cloneContext) {
188
- try {
189
- log.debug('Checking if content directory is empty', { ...cloneContext, dir });
190
- const dirNotEmpty = readdirSync(dir).length;
191
-
192
- if (dirNotEmpty) {
193
- log.debug('Content directory is not empty, cleaning up', { ...cloneContext, dir });
194
- await this.cleanUp(dir, null, cloneContext);
195
- }
196
- } catch (error) {
197
- const omit = ['ENOENT']; // NOTE add emittable error codes in the array
198
-
199
- if (!omit.includes(error.code)) {
200
- log.error('Error checking content directory', { ...cloneContext, error: error?.message, code: error.code });
201
- }
202
- }
203
- }
204
-
205
- async cleanUp(pathDir, message, cloneContext) {
206
- try {
207
- log.debug('Starting cleanup', { ...cloneContext, pathDir });
208
- await rimraf(pathDir);
209
- if (message) {
210
- log.info(message, cloneContext);
211
- }
212
- log.debug('Cleanup completed', { ...cloneContext, pathDir });
213
- } catch (err) {
214
- if (err) {
215
- log.debug('Cleaning up', cloneContext);
216
- const skipCodeArr = ['ENOENT', 'EBUSY', 'EPERM', 'EMFILE', 'ENOTEMPTY'];
217
-
218
- if (skipCodeArr.includes(err.code)) {
219
- log.debug('Cleanup error code is in skip list, exiting', { ...cloneContext, code: err?.code });
220
- process.exit();
221
- }
222
- }
223
- }
224
- }
225
-
226
- registerCleanupOnInterrupt(pathDir, cloneContext) {
227
- const interrupt = ['SIGINT', 'SIGQUIT', 'SIGTERM'];
228
- const exceptions = ['unhandledRejection', 'uncaughtException'];
229
-
230
- const cleanUp = async (exitOrError) => {
231
- if (exitOrError) {
232
- log.debug('Cleaning up on interrupt', cloneContext);
233
- await this.cleanUp(pathDir, null, cloneContext);
234
- log.info('Cleanup done', cloneContext);
235
-
236
- if (exitOrError instanceof Promise) {
237
- exitOrError.catch((error) => {
238
- log.error('Error during cleanup', { ...cloneContext, error: (error && error?.message) || '' });
239
- });
240
- } else if (exitOrError.message) {
241
- log.error('Cleanup error', { ...cloneContext, error: exitOrError?.message });
242
- } else if (exitOrError.errorMessage) {
243
- log.error('Cleanup error', { ...cloneContext, error: exitOrError?.errorMessage });
244
- }
245
-
246
- if (exitOrError === true) process.exit();
247
- }
248
- };
249
-
250
- exceptions.forEach((event) => process.on(event, cleanUp));
251
- interrupt.forEach((signal) => process.on(signal, () => cleanUp(true)));
252
- }
253
- }
254
-
255
- StackCloneCommand.description = `Clone data (structure/content or both) of a stack into another stack
256
- Use this plugin to automate the process of cloning a stack in few steps.
257
- `;
258
-
259
- StackCloneCommand.examples = [
260
- 'csdx cm:stacks:clone',
261
- 'csdx cm:stacks:clone --source-branch <source-branch-name> --target-branch <target-branch-name> --yes',
262
- 'csdx cm:stacks:clone --source-stack-api-key <apiKey> --destination-stack-api-key <apiKey>',
263
- 'csdx cm:stacks:clone --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias>',
264
- 'csdx cm:stacks:clone --source-branch --target-branch --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias>',
265
- 'csdx cm:stacks:clone --source-branch --target-branch --source-management-token-alias <management token alias> --destination-management-token-alias <management token alias> --type <value a or b>',
266
- ];
267
-
268
- StackCloneCommand.aliases = [];
269
-
270
- StackCloneCommand.flags = {
271
- 'source-branch': flags.string({
272
- required: false,
273
- multiple: false,
274
- description: 'Branch of the source stack.',
275
- exclusive: ['source-branch-alias'],
276
- }),
277
- 'source-branch-alias': flags.string({
278
- required: false,
279
- multiple: false,
280
- description: 'Alias of Branch of the source stack.',
281
- exclusive: ['source-branch'],
282
- }),
283
- 'target-branch': flags.string({
284
- required: false,
285
- multiple: false,
286
- description: 'Branch of the target stack.',
287
- exclusive: ['target-branch-alias'],
288
- }),
289
- 'target-branch-alias': flags.string({
290
- required: false,
291
- multiple: false,
292
- description: 'Alias of Branch of the target stack.',
293
- exclusive: ['target-branch'],
294
- }),
295
- 'source-management-token-alias': flags.string({
296
- required: false,
297
- multiple: false,
298
- description: 'Source management token alias.',
299
- }),
300
- 'destination-management-token-alias': flags.string({
301
- required: false,
302
- multiple: false,
303
- description: 'Destination management token alias.',
304
- }),
305
- 'stack-name': flags.string({
306
- char: 'n',
307
- required: false,
308
- multiple: false,
309
- description: 'Provide a name for the new stack to store the cloned content.',
310
- }),
311
- type: flags.string({
312
- required: false,
313
- multiple: false,
314
- options: ['a', 'b'],
315
- description: ` Type of data to clone. You can select option a or b.
316
- a) Structure (all modules except entries & assets).
317
- b) Structure with content (all modules including entries & assets).
318
- `,
319
- }),
320
- 'source-stack-api-key': flags.string({
321
- description: 'Source stack API key',
322
- }),
323
- 'destination-stack-api-key': flags.string({
324
- description: 'Destination stack API key',
325
- }),
326
- 'import-webhook-status': flags.string({
327
- description: '[default: disable] (optional) The status of the import webhook. <options: disable|current>',
328
- options: ['disable', 'current'],
329
- required: false,
330
- default: 'disable',
331
- }),
332
- yes: flags.boolean({
333
- char: 'y',
334
- required: false,
335
- description: 'Force override all Marketplace prompts.',
336
- }),
337
- 'skip-audit': flags.boolean({
338
- description: ' (optional) Skips the audit fix that occurs during an import operation.',
339
- }),
340
- config: flags.string({
341
- char: 'c',
342
- required: false,
343
- description: 'Path for the external configuration',
344
- }),
345
- };
346
-
347
- StackCloneCommand.usage =
348
- 'cm:stacks:clone [--source-branch <value>] [--target-branch <value>] [--source-management-token-alias <value>] [--destination-management-token-alias <value>] [-n <value>] [--type a|b] [--source-stack-api-key <value>] [--destination-stack-api-key <value>] [--import-webhook-status disable|current]';
349
-
350
- module.exports = StackCloneCommand;
@@ -1,67 +0,0 @@
1
- const CloneCommand = function (execute, undo, params, parentContext) {
2
- this.execute = execute.bind(parentContext);
3
- this.undo = undo && undo.bind(parentContext);
4
- this.params = params;
5
- };
6
-
7
- const HandleOrgCommand = function (params, parentContext) {
8
- return new CloneCommand(parentContext.handleOrgSelection, null, params, parentContext);
9
- };
10
-
11
- const HandleStackCommand = function (params, parentContext) {
12
- return new CloneCommand(parentContext.handleStackSelection, parentContext.execute, params, parentContext);
13
- };
14
-
15
- const HandleBranchCommand = function (params, parentContext, backStepHandler) {
16
- return new CloneCommand(parentContext.handleBranchSelection, backStepHandler, params, parentContext);
17
- };
18
-
19
- const HandleDestinationStackCommand = function (params, parentContext) {
20
- return new CloneCommand(parentContext.handleStackSelection, parentContext.executeDestination, params, parentContext);
21
- };
22
-
23
- const HandleExportCommand = function (params, parentContext) {
24
- return new CloneCommand(parentContext.cmdExport, null, params, parentContext);
25
- };
26
-
27
- const SetBranchCommand = function (params, parentContext) {
28
- return new CloneCommand(parentContext.setBranch, null, params, parentContext);
29
- };
30
-
31
- const CreateNewStackCommand = function (params, parentContext) {
32
- return new CloneCommand(parentContext.createNewStack, parentContext.executeDestination, params, parentContext);
33
- };
34
-
35
- const CloneTypeSelectionCommand = function (params, parentContext) {
36
- return new CloneCommand(parentContext.cloneTypeSelection, null, params, parentContext);
37
- };
38
-
39
- const Clone = function () {
40
- const commands = [];
41
-
42
- return {
43
- execute: async function (command) {
44
- commands.push(command);
45
- const result = await command.execute(command.params);
46
- return result;
47
- },
48
- undo: async function () {
49
- if (commands.length) {
50
- const command = commands.pop();
51
- command.undo && await command.undo(command.params);
52
- }
53
- },
54
- };
55
- };
56
-
57
- module.exports = {
58
- HandleOrgCommand,
59
- HandleStackCommand,
60
- HandleBranchCommand,
61
- HandleDestinationStackCommand,
62
- HandleExportCommand,
63
- SetBranchCommand,
64
- CreateNewStackCommand,
65
- CloneTypeSelectionCommand,
66
- Clone,
67
- };
@@ -1,49 +0,0 @@
1
- 'use strict';
2
-
3
- const { EventEmitter } = require('events');
4
-
5
- class CustomAbortSignal {
6
- constructor() {
7
- this.eventEmitter = new EventEmitter();
8
- this.onabort = null;
9
- this.aborted = false;
10
- }
11
- toString() {
12
- return '[object CustomAbortSignal]';
13
- }
14
- get [Symbol.toStringTag]() {
15
- return 'CustomAbortSignal';
16
- }
17
- removeEventListener(name, handler) {
18
- this.eventEmitter.removeListener(name, handler);
19
- }
20
- addEventListener(name, handler) {
21
- this.eventEmitter.on(name, handler);
22
- }
23
- dispatchEvent(type) {
24
- const event = { type, target: this };
25
- const handlerName = `on${type}`;
26
-
27
- if (typeof this[handlerName] === 'function') this[handlerName](event);
28
- }
29
- }
30
-
31
- class CustomAbortController {
32
- constructor() {
33
- this.signal = new CustomAbortSignal();
34
- }
35
- abort() {
36
- if (this.signal.aborted) return;
37
-
38
- this.signal.aborted = true;
39
- this.signal.dispatchEvent('abort');
40
- }
41
- toString() {
42
- return '[object CustomAbortController]';
43
- }
44
- get [Symbol.toStringTag]() {
45
- return 'CustomAbortController';
46
- }
47
- }
48
-
49
- module.exports = { CustomAbortController, CustomAbortSignal };