@contentstack/cli-cm-seed 2.0.0-beta.10 → 2.0.0-beta.12

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/README.md CHANGED
@@ -10,22 +10,22 @@ To import content to your stack, you can choose from the following two sources:
10
10
  <!-- usagestop -->
11
11
  ## Commands
12
12
  <!-- commands -->
13
- * [`csdx cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [--yes <value>] [--alias <value>] [--locale <value>]`](#csdx-cmstacksseed---repo-value---org-value---stack-api-key-value---stack-name-value---yes-value---alias-value---locale-value)
13
+ * [`csdx cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [-y] [--alias <value>] [--locale <value>]`](#csdx-cmstacksseed---repo-value---org-value---stack-api-key-value---stack-name-value--y---alias-value---locale-value)
14
14
 
15
- ## `csdx cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [--yes <value>] [--alias <value>] [--locale <value>]`
15
+ ## `csdx cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [-y] [--alias <value>] [--locale <value>]`
16
16
 
17
17
  Create a stack from existing content types, entries, assets, etc
18
18
 
19
19
  ```
20
20
  USAGE
21
- $ csdx cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [--yes
22
- <value>] [--alias <value>] [--locale <value>]
21
+ $ csdx cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [-y]
22
+ [--alias <value>] [--locale <value>]
23
23
 
24
24
  FLAGS
25
25
  -a, --alias=<value> Alias of the management token
26
26
  -k, --stack-api-key=<value> Provide stack API key to seed content to
27
27
  -n, --stack-name=<value> Name of a new stack that needs to be created.
28
- -y, --yes=<value> [Optional] Skip the stack confirmation.
28
+ -y, --yes [Optional] Skip the stack confirmation.
29
29
  --org=<value> Provide Organization UID to create a new stack
30
30
  --repo=<value> GitHub organization name or GitHub user name/repository name.
31
31
 
@@ -23,7 +23,7 @@ class SeedCommand extends cli_command_1.Command {
23
23
  stackUid: seedFlags['stack-api-key'],
24
24
  stackName: seedFlags['stack-name'],
25
25
  fetchLimit: seedFlags['fetch-limit'],
26
- skipStackConfirmation: seedFlags['yes'],
26
+ skipStackConfirmation: seedFlags.yes,
27
27
  isAuthenticated: (0, cli_utilities_1.isAuthenticated)(),
28
28
  alias: managementTokenAlias,
29
29
  master_locale: seedFlags['locale'],
@@ -48,7 +48,6 @@ class SeedCommand extends cli_command_1.Command {
48
48
  }
49
49
  }
50
50
  }
51
- exports.default = SeedCommand;
52
51
  SeedCommand.description = 'Create a stack from existing content types, entries, assets, etc';
53
52
  SeedCommand.examples = [
54
53
  '$ csdx cm:stacks:seed',
@@ -57,7 +56,7 @@ SeedCommand.examples = [
57
56
  '$ csdx cm:stacks:seed --repo "account/repository" --stack-api-key "stack-api-key" //seed content into specific stack',
58
57
  '$ csdx cm:stacks:seed --repo "account/repository" --org "your-org-uid" --stack-name "stack-name" //create a new stack in given org uid',
59
58
  ];
60
- SeedCommand.usage = 'cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [--yes <value>] [--alias <value>] [--locale <value>]';
59
+ SeedCommand.usage = 'cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [-y] [--alias <value>] [--locale <value>]';
61
60
  SeedCommand.flags = {
62
61
  repo: cli_utilities_1.flags.string({
63
62
  description: 'GitHub organization name or GitHub user name/repository name.',
@@ -85,13 +84,12 @@ SeedCommand.flags = {
85
84
  exclusive: ['stack-api-key'],
86
85
  }),
87
86
  'fetch-limit': cli_utilities_1.flags.string({
88
- char: 'l',
89
87
  description: 'Limit for number of organizations or stacks to be fetched.',
90
88
  multiple: false,
91
89
  required: false,
92
90
  hidden: true,
93
91
  }),
94
- yes: cli_utilities_1.flags.string({
92
+ yes: cli_utilities_1.flags.boolean({
95
93
  char: 'y',
96
94
  required: false,
97
95
  description: '[Optional] Skip the stack confirmation.',
@@ -102,6 +100,8 @@ SeedCommand.flags = {
102
100
  }),
103
101
  locale: cli_utilities_1.flags.string({
104
102
  description: 'Master Locale of the stack',
103
+ default: 'en-us',
105
104
  hidden: true,
106
105
  }),
107
106
  };
107
+ exports.default = SeedCommand;
@@ -1,4 +1,3 @@
1
- /// <reference types="node" />
2
1
  import { Stream } from 'stream';
3
2
  export default class GitHubClient {
4
3
  username: string;
@@ -15,6 +14,7 @@ export default class GitHubClient {
15
14
  makeHeadApiCall(repo: string): Promise<any>;
16
15
  makeGetApiCall(repo: string): Promise<any>;
17
16
  checkIfRepoExists(repo: string): Promise<boolean>;
17
+ getMasterLocaleFromRepo(repo: string): Promise<string | null>;
18
18
  getLatestTarballUrl(repo: string): Promise<any>;
19
19
  streamRelease(url: string): Promise<Stream>;
20
20
  extract(destination: string, stream: Stream): Promise<void>;
@@ -100,6 +100,23 @@ class GitHubClient {
100
100
  }
101
101
  return false;
102
102
  }
103
+ async getMasterLocaleFromRepo(repo) {
104
+ var _a;
105
+ try {
106
+ const response = await this.httpClient.get(`https://raw.githubusercontent.com/${this.username}/${repo}/main/stack/locales/master-locale.json`);
107
+ if (response.data) {
108
+ const localeData = response.data;
109
+ const localeKey = Object.keys(localeData)[0];
110
+ if (localeKey && ((_a = localeData[localeKey]) === null || _a === void 0 ? void 0 : _a.code)) {
111
+ return localeData[localeKey].code;
112
+ }
113
+ }
114
+ }
115
+ catch (error) {
116
+ console.log('Could not fetch master locale from repository', error);
117
+ }
118
+ return null;
119
+ }
103
120
  async getLatestTarballUrl(repo) {
104
121
  try {
105
122
  const response = await this.httpClient.get(`${this.gitHubRepoUrl}/${repo}/releases/latest`);
@@ -1,17 +1,22 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.run = void 0;
3
+ exports.run = run;
4
+ const fs = require("fs");
4
5
  const process = require("process");
5
6
  const path = require("path");
6
7
  const cli_cm_import_1 = require("@contentstack/cli-cm-import");
7
8
  const cli_utilities_1 = require("@contentstack/cli-utilities");
8
9
  const STACK_FOLDER = 'stack';
9
10
  async function run(options) {
10
- const importPath = (0, cli_utilities_1.pathValidator)(path.resolve((0, cli_utilities_1.sanitizePath)(options.tmpPath), STACK_FOLDER));
11
+ const tmpPathResolved = path.resolve((0, cli_utilities_1.sanitizePath)(options.tmpPath));
12
+ const stackPath = path.join(tmpPathResolved, STACK_FOLDER);
13
+ // Support both structures: repo with stack/ folder (per docs) or content at root
14
+ const importPath = fs.existsSync(stackPath)
15
+ ? (0, cli_utilities_1.pathValidator)(stackPath)
16
+ : (0, cli_utilities_1.pathValidator)(tmpPathResolved);
11
17
  const args = options.alias
12
18
  ? ['-k', options.api_key, '-d', importPath, '--alias', options.alias]
13
19
  : ['-k', options.api_key, '-d', importPath];
14
20
  process.chdir(options.tmpPath);
15
21
  await cli_cm_import_1.default.run(args.concat('--skip-audit'));
16
22
  }
17
- exports.run = run;
@@ -10,7 +10,7 @@ export interface ContentModelSeederOptions {
10
10
  stackUid: string | undefined;
11
11
  stackName: string | undefined;
12
12
  fetchLimit: string | undefined;
13
- skipStackConfirmation: string | undefined;
13
+ skipStackConfirmation: boolean | undefined;
14
14
  isAuthenticated: boolean | false;
15
15
  managementToken?: string | undefined;
16
16
  alias?: string | undefined;
package/lib/seed/index.js CHANGED
@@ -127,48 +127,18 @@ class ContentModelSeeder {
127
127
  return newStack.api_key;
128
128
  }
129
129
  async shouldProceed(api_key) {
130
- let count;
131
130
  const stack_details = await this.csClient.getStack(api_key);
132
- if (this.options.master_locale != stack_details.master_locale) {
133
- cli_utilities_1.cliux.print(`Compass app requires the master locale to be set to English (en).`, {
134
- color: "yellow",
131
+ const repoMasterLocale = await this.ghClient.getMasterLocaleFromRepo(this.ghRepo);
132
+ const expectedLocale = repoMasterLocale || this.options.master_locale || exports.ENGLISH_LOCALE;
133
+ if (stack_details.master_locale !== expectedLocale) {
134
+ cli_utilities_1.cliux.print(`Repository '${this.ghRepo}' requires the master locale to be set to '${expectedLocale}', but your stack has '${stack_details.master_locale}'.`, {
135
+ color: 'yellow',
135
136
  bold: true,
136
137
  });
137
138
  return false;
138
139
  }
139
- const managementBody = {
140
- "name": "Checking roles for creating management token",
141
- "description": "This is a compass app management token.",
142
- "scope": [
143
- {
144
- "module": "content_type",
145
- "acl": {
146
- "read": true,
147
- "write": true
148
- }
149
- },
150
- {
151
- "module": "branch",
152
- "branches": [
153
- "main"
154
- ],
155
- "acl": {
156
- "read": true
157
- }
158
- }
159
- ],
160
- "expires_on": "3000-01-01",
161
- "is_email_notification_enabled": false
162
- };
163
- let managementTokenResult = await this.csClient.createManagementToken(api_key, this.managementToken, managementBody);
164
- if ((managementTokenResult === null || managementTokenResult === void 0 ? void 0 : managementTokenResult.response_code) == "161" || (managementTokenResult === null || managementTokenResult === void 0 ? void 0 : managementTokenResult.response_code) == "401") {
165
- cli_utilities_1.cliux.print(`Info: Failed to generate a management token.\nNote: Management token is not available in your plan. Please contact the admin for support.`, {
166
- color: 'red',
167
- });
168
- return false;
169
- }
170
- count = await this.csClient.getContentTypeCount(api_key, this.managementToken);
171
- if (count > 0 && this._options.skipStackConfirmation !== 'yes') {
140
+ const count = await this.csClient.getContentTypeCount(api_key, this.managementToken);
141
+ if (count > 0 && !this._options.skipStackConfirmation) {
172
142
  const proceed = await (0, interactive_1.inquireProceed)();
173
143
  if (!proceed) {
174
144
  return false;
@@ -1,7 +1,10 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.inquireStack = exports.inquireProceed = exports.inquireOrganization = exports.inquireRepo = void 0;
4
- const inquirer = require('inquirer');
3
+ exports.inquireRepo = inquireRepo;
4
+ exports.inquireOrganization = inquireOrganization;
5
+ exports.inquireProceed = inquireProceed;
6
+ exports.inquireStack = inquireStack;
7
+ const inquirer_1 = require("inquirer");
5
8
  async function inquireRepo(repos) {
6
9
  if (!repos || repos.length === 0)
7
10
  throw new Error('Precondition failed: No Repositories found.');
@@ -11,7 +14,7 @@ async function inquireRepo(repos) {
11
14
  const choices = repos.map((r) => {
12
15
  return { name: formatStackName(r.name), value: extractRepoName(r.html_url) };
13
16
  });
14
- const response = await inquirer.prompt([
17
+ const response = await inquirer_1.default.prompt([
15
18
  {
16
19
  type: 'list',
17
20
  name: 'choice',
@@ -21,7 +24,6 @@ async function inquireRepo(repos) {
21
24
  ]);
22
25
  return response;
23
26
  }
24
- exports.inquireRepo = inquireRepo;
25
27
  async function inquireOrganization(organizations) {
26
28
  if (!organizations || organizations.length === 0)
27
29
  throw new Error('Precondition failed: No Organizations found.');
@@ -31,7 +33,7 @@ async function inquireOrganization(organizations) {
31
33
  const choices = organizations.map((r) => {
32
34
  return { name: r.name, value: r.uid };
33
35
  });
34
- const response = await inquirer.prompt([
36
+ const response = await inquirer_1.default.prompt([
35
37
  {
36
38
  type: 'list',
37
39
  name: 'uid',
@@ -41,9 +43,8 @@ async function inquireOrganization(organizations) {
41
43
  ]);
42
44
  return organizations.find((r) => r.uid === response.uid);
43
45
  }
44
- exports.inquireOrganization = inquireOrganization;
45
46
  async function inquireProceed() {
46
- const createResponse = await inquirer.prompt([
47
+ const createResponse = await inquirer_1.default.prompt([
47
48
  {
48
49
  type: 'confirm',
49
50
  name: 'choice',
@@ -52,12 +53,11 @@ async function inquireProceed() {
52
53
  ]);
53
54
  return createResponse.choice;
54
55
  }
55
- exports.inquireProceed = inquireProceed;
56
56
  async function inquireStack(stacks, stackName) {
57
57
  const result = {};
58
58
  const hasStacks = stacks !== null && stacks.length > 0;
59
59
  if (hasStacks && !stackName) {
60
- const createResponse = await inquirer.prompt([
60
+ const createResponse = await inquirer_1.default.prompt([
61
61
  {
62
62
  type: 'list',
63
63
  name: 'choice',
@@ -83,7 +83,7 @@ async function inquireStack(stacks, stackName) {
83
83
  if (stackName)
84
84
  result.name = stackName.trim();
85
85
  else {
86
- const nameResponse = await inquirer.prompt([
86
+ const nameResponse = await inquirer_1.default.prompt([
87
87
  {
88
88
  type: 'input',
89
89
  name: 'name',
@@ -105,7 +105,7 @@ async function inquireStack(stacks, stackName) {
105
105
  return { name: `${s.name}`, value: s.uid };
106
106
  });
107
107
  choices.sort((a, b) => (a.name > b.name ? 1 : -1));
108
- const selectResponse = await inquirer.prompt([
108
+ const selectResponse = await inquirer_1.default.prompt([
109
109
  {
110
110
  type: 'list',
111
111
  name: 'uid',
@@ -120,7 +120,6 @@ async function inquireStack(stacks, stackName) {
120
120
  }
121
121
  return result;
122
122
  }
123
- exports.inquireStack = inquireStack;
124
123
  function formatStackName(name) {
125
124
  return name
126
125
  .replace('stack-', '')
@@ -57,7 +57,6 @@
57
57
  "type": "option"
58
58
  },
59
59
  "fetch-limit": {
60
- "char": "l",
61
60
  "description": "Limit for number of organizations or stacks to be fetched.",
62
61
  "hidden": true,
63
62
  "name": "fetch-limit",
@@ -71,9 +70,8 @@
71
70
  "description": "[Optional] Skip the stack confirmation.",
72
71
  "name": "yes",
73
72
  "required": false,
74
- "hasDynamicHelp": false,
75
- "multiple": false,
76
- "type": "option"
73
+ "allowNo": false,
74
+ "type": "boolean"
77
75
  },
78
76
  "alias": {
79
77
  "char": "a",
@@ -87,6 +85,7 @@
87
85
  "description": "Master Locale of the stack",
88
86
  "hidden": true,
89
87
  "name": "locale",
88
+ "default": "en-us",
90
89
  "hasDynamicHelp": false,
91
90
  "multiple": false,
92
91
  "type": "option"
@@ -99,7 +98,7 @@
99
98
  "pluginName": "@contentstack/cli-cm-seed",
100
99
  "pluginType": "core",
101
100
  "strict": true,
102
- "usage": "cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [--yes <value>] [--alias <value>] [--locale <value>]",
101
+ "usage": "cm:stacks:seed [--repo <value>] [--org <value>] [--stack-api-key <value>] [--stack-name <value>] [-y] [--alias <value>] [--locale <value>]",
103
102
  "isESM": false,
104
103
  "relativePath": [
105
104
  "lib",
@@ -110,5 +109,5 @@
110
109
  ]
111
110
  }
112
111
  },
113
- "version": "2.0.0-beta.10"
112
+ "version": "2.0.0-beta.12"
114
113
  }
package/package.json CHANGED
@@ -1,23 +1,23 @@
1
1
  {
2
2
  "name": "@contentstack/cli-cm-seed",
3
3
  "description": "create a Stack from existing content types, entries, assets, etc.",
4
- "version": "2.0.0-beta.10",
4
+ "version": "2.0.0-beta.12",
5
5
  "author": "Contentstack",
6
6
  "bugs": "https://github.com/contentstack/cli/issues",
7
7
  "dependencies": {
8
- "@contentstack/cli-cm-import": "~2.0.0-beta.11",
9
- "@contentstack/cli-command": "~2.0.0-beta.2",
10
- "@contentstack/cli-utilities": "~2.0.0-beta.2",
11
- "inquirer": "8.2.7",
8
+ "@contentstack/cli-cm-import": "~2.0.0-beta.13",
9
+ "@contentstack/cli-command": "~2.0.0-beta.4",
10
+ "@contentstack/cli-utilities": "~2.0.0-beta.4",
11
+ "inquirer": "12.11.1",
12
12
  "mkdirp": "^1.0.4",
13
- "tar": "^7.5.10",
13
+ "tar": "^7.5.11",
14
14
  "tmp": "^0.2.5"
15
15
  },
16
16
  "devDependencies": {
17
17
  "@types/inquirer": "^9.0.9",
18
18
  "@types/jest": "^26.0.24",
19
19
  "@types/mkdirp": "^1.0.2",
20
- "@types/node": "^14.18.63",
20
+ "@types/node": "^18.11.9",
21
21
  "@types/tar": "^6.1.13",
22
22
  "@types/tmp": "^0.2.6",
23
23
  "axios": "^1.13.5",
@@ -26,9 +26,10 @@
26
26
  "eslint-config-oclif-typescript": "^3.1.14",
27
27
  "jest": "^29.7.0",
28
28
  "oclif": "^4.17.46",
29
+ "@oclif/plugin-help": "^6.2.28",
29
30
  "ts-jest": "^29.4.6",
30
31
  "ts-node": "^8.10.2",
31
- "typescript": "^4.9.5"
32
+ "typescript": "^5.9.3"
32
33
  },
33
34
  "engines": {
34
35
  "node": ">=14.0.0"
@@ -49,6 +50,9 @@
49
50
  "oclif": {
50
51
  "commands": "./lib/commands",
51
52
  "bin": "csdx",
53
+ "devPlugins": [
54
+ "@oclif/plugin-help"
55
+ ],
52
56
  "repositoryPrefix": "<%- repo %>/blob/main/packages/contentstack-seed/<%- commandPath %>"
53
57
  },
54
58
  "csdxConfig": {
@@ -67,4 +71,4 @@
67
71
  "compile": "tsc -b tsconfig.json",
68
72
  "build": "pnpm compile && oclif manifest && oclif readme"
69
73
  }
70
- }
74
+ }