Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
41b7363
added org plan check
Jun 30, 2026
6db9d0d
fixed org plan check
Jul 1, 2026
f1c2f3c
changed to use package.json
Jul 1, 2026
42312b7
merged latest changes
Jul 8, 2026
b71137b
Fix: Reconcile completed progress bar counts with processed items
harshitha-cstk Jul 20, 2026
bb54659
test: make progress reconciliation tests independent of cli-progress …
harshitha-cstk Jul 20, 2026
7b3efc5
Merge pull request #2649 from contentstack/v2-beta
naman-contentstack Jul 20, 2026
4bd08dd
Merge branch 'v2-dev' into fix/dx-7521-progress-complete-count
harshitha-cstk Jul 21, 2026
6940f82
feat(utilities): add readGlobalFieldSchemas utility function
cs-raj Jul 22, 2026
cd6cca9
docs: mark launch as opt-in plugin in root README (DX-9744)
harshitha-cstk Jul 23, 2026
ee6fd07
lock file update
cs-raj Jul 23, 2026
a577aa9
Merge pull request #2651 from contentstack/fix/dx-9744-readme-cleanup
harshitha-cstk Jul 23, 2026
e9eda83
build: remove @contentstack/cli-launch from bundled CLI (DX-9742)
harshitha-cstk Jul 23, 2026
5f58ed7
fix(utilities): add globalfields.json to readGlobalFieldSchemas ignor…
cs-raj Jul 23, 2026
6f695a1
Merge pull request #2652 from contentstack/fix/remove-cli-launch-from…
harshitha-cstk Jul 23, 2026
f42e59b
test(utilities): add readGlobalFieldSchemas unit tests and assert rea…
cs-raj Jul 23, 2026
adfc7b7
docs: document launch opt-in requirement in 2.x migration guide (DX-9…
harshitha-cstk Jul 23, 2026
c944a03
Merge pull request #2654 from contentstack/fix/dx-9748-update-migrati…
harshitha-cstk Jul 23, 2026
3c9fbc0
remove launch from oclif topic from package
harshitha-cstk Jul 23, 2026
fee5e5c
org plan check and endpoints auto update in cli config
Jul 23, 2026
51d0866
feat: warn and suggest install for opt-in launch commands
harshitha-cstk Jul 24, 2026
d19dd25
Merge pull request #2650 from contentstack/enhc/DX-9464
cs-raj Jul 24, 2026
e86f92b
Merge pull request #2656 from contentstack/fix/add-warning-for-launch
harshitha-cstk Jul 24, 2026
0a0f817
Merge branch 'v2-dev' into enh/dx-9742-demote-launch-plugin
harshitha-cstk Jul 24, 2026
de615d3
update pnpm lock file
harshitha-cstk Jul 24, 2026
b7476d0
Merge branch 'v2-dev' into fix/dx-7521-progress-complete-count
harshitha-cstk Jul 24, 2026
82db02f
Merge pull request #2647 from contentstack/fix/dx-7521-progress-compl…
harshitha-cstk Jul 24, 2026
2d47f39
Merge branch 'v2-dev' into enh/dx-9742-demote-launch-plugin
harshitha-cstk Jul 24, 2026
b0432fb
merged latest code
Jul 24, 2026
90db17e
Merge pull request #2655 from contentstack/enh/dx-9742-demote-launch-…
harshitha-cstk Jul 24, 2026
3a06fd4
fix: version bump
harshitha-cstk Jul 24, 2026
8742f16
Merge pull request #2660 from contentstack/fix/version-bump
harshitha-cstk Jul 24, 2026
2ca4341
bumped versions and merged updates
Jul 27, 2026
7ea473a
Merge pull request #2627 from contentstack/feat/org-plan-check
shafeeqd959 Jul 27, 2026
9fca4a6
corrected version bump
Jul 27, 2026
45662a6
Merge pull request #2663 from contentstack/feat/org-plan-check
shafeeqd959 Jul 27, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .talismanrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
fileignoreconfig:
- filename: pnpm-lock.yaml
checksum: 64ca5ee7000d70e76ba367e3cacc2158e5cd33e41c7844fb6af79837a9469bb6
checksum: 117b66122d3f3043f48724ff9755ec2d4a9dff3c156ceedef753df3014cafee6
- filename: packages/contentstack/src/hooks/init/opt-in-plugin-guide.ts
checksum: 2b079a93988e2439a03c401f75695fcdbfeb138a75c84707e4bc892536680e9f
version: '1.0'
44 changes: 44 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,45 @@ csdx cm:entries:publish --content-types blog --environments prod --locales en-us
csdx cm:stacks:bulk-entries --operation publish --content-types blog --environments prod --locales en-us -k blt123
```

### 7. 🚀 Launch Plugin Now Opt-In

**What Changed:**
- The `launch` plugin (`@contentstack/cli-launch`) is no longer bundled with the CLI
- All `launch:*` commands now require installing the plugin explicitly before use
- Brings `launch` in line with the opt-in, modular plugin model used elsewhere in 2.x

> ⚠️ **This is a change relative to the 2.x beta — not only relative to 1.x.** `@contentstack/cli-launch` was bundled throughout the 1.x releases **and** the entire 2.x beta period, so `launch:*` worked out of the box for beta users too. Starting with 2.x GA it becomes opt-in, so beta users who rely on `launch:*` are also affected when they upgrade.

**Before (1.x.x and 2.x.x-beta):**
- `launch:*` commands were bundled with the CLI and available by default after installation

**After (2.x.x GA):**
- `launch:*` commands are provided by a separate, opt-in plugin that must be installed explicitly
- Running any `launch:*` command without the plugin installed fails with a `command not found` error where it previously worked out of the box

**Affected commands:** `launch`, `launch:deployments`, `launch:environments`, `launch:functions`, `launch:logs`, `launch:open`, `launch:rollback`

**Installation Methods:**


**Option 1: Using CLI Plugin Manager**
```bash
csdx plugins:install @contentstack/cli-launch
```

**Option 2: Using npm**
```bash
npm install -g @contentstack/cli-launch
```

**Usage:**
After installation, launch commands will be available through the CLI:
```bash
csdx launch --help
```

**Migration Action:** If you use any `launch:*` command, install the `@contentstack/cli-launch` plugin before (or immediately after) upgrading to 2.x GA to avoid `command not found` errors. This applies to 2.x beta users as well, since `launch` was bundled during the beta.

## Troubleshooting

### Common Issues
Expand All @@ -209,6 +248,11 @@ csdx cm:stacks:bulk-entries --operation publish --content-types blog --environme
- The 2.x.x-beta version should be faster due to TypeScript modules
- If you are experiencing issues, switch to console log mode for debugging

**5. `launch:*` command not found:**
- In 2.x GA, `launch` is an opt-in plugin and is no longer bundled (it was bundled in 1.x and during the 2.x beta)
- Install it with `csdx plugins:install @contentstack/cli-launch`, then re-run your `launch:*` command
- Verify it is installed with `csdx plugins`

### Getting Help

**Documentation:**
Expand Down
6 changes: 3 additions & 3 deletions packages/contentstack-auth/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-auth",
"description": "Contentstack CLI plugin for authentication activities",
"version": "2.0.0-beta.16",
"version": "2.0.0-beta.17",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"scripts": {
Expand All @@ -15,8 +15,8 @@
"lint": "eslint src/**/*.ts"
},
"dependencies": {
"@contentstack/cli-command": "~2.0.0-beta.10",
"@contentstack/cli-utilities": "~2.0.0-beta.11",
"@contentstack/cli-command": "~2.0.0-beta.11",
"@contentstack/cli-utilities": "~2.0.0-beta.12",
"@oclif/core": "^4.11.4",
"otplib": "^12.0.1"
},
Expand Down
6 changes: 3 additions & 3 deletions packages/contentstack-command/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-command",
"description": "Contentstack CLI plugin for configuration",
"version": "2.0.0-beta.10",
"version": "2.0.0-beta.11",
"author": "Contentstack",
"main": "lib/index.js",
"types": "lib/index.d.ts",
Expand All @@ -14,7 +14,7 @@
"lint": "eslint src/**/*.ts"
},
"dependencies": {
"@contentstack/cli-utilities": "~2.0.0-beta.11",
"@contentstack/cli-utilities": "~2.0.0-beta.12",
"contentstack": "^3.27.0",
"@oclif/core": "^4.11.4"
},
Expand Down Expand Up @@ -66,4 +66,4 @@
"url": "git+https://github.com/contentstack/cli.git",
"directory": "packages/contentstack-command"
}
}
}
2 changes: 1 addition & 1 deletion packages/contentstack-command/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ abstract class ContentstackCommand extends Command {

get context() {
// @ts-ignore
return this.config.context || {};
return this.config.context || this.config.options?.context || {};
}

get email() {
Expand Down
8 changes: 4 additions & 4 deletions packages/contentstack-config/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-config",
"description": "Contentstack CLI plugin for configuration",
"version": "2.0.0-beta.14",
"version": "2.0.0-beta.15",
"author": "Contentstack",
"scripts": {
"build": "pnpm compile && oclif manifest && oclif readme",
Expand All @@ -14,8 +14,8 @@
"lint": "eslint src/**/*.ts"
},
"dependencies": {
"@contentstack/cli-command": "~2.0.0-beta.10",
"@contentstack/cli-utilities": "~2.0.0-beta.11",
"@contentstack/cli-command": "~2.0.0-beta.11",
"@contentstack/cli-utilities": "~2.0.0-beta.12",
"@contentstack/utils": "~1.9.1",
"@oclif/core": "^4.11.4"
},
Expand Down Expand Up @@ -95,4 +95,4 @@
"url": "git+https://github.com/contentstack/cli.git",
"directory": "packages/contentstack-config"
}
}
}
19 changes: 19 additions & 0 deletions packages/contentstack-config/src/commands/config/set/region.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
'cs-assets': _flags.string({
description: 'Custom host to set for Contentstack Assets API',
}),
'auth-api': _flags.string({
description: 'Custom host to set for Auth API',
}),
};
static examples = [
'$ csdx config:set:region',
Expand Down Expand Up @@ -82,6 +85,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
let launchHubUrl = regionSetFlags['launch'];
let composableStudioUrl = regionSetFlags['studio'];
let csAssetsUrl = regionSetFlags['cs-assets'];
let authUrl = regionSetFlags['auth-api'];
let selectedRegion = args.region;
if (!(cda && cma && uiHost && name) && !selectedRegion) {
selectedRegion = await interactive.askRegions();
Expand Down Expand Up @@ -115,6 +119,9 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
if (!csAssetsUrl) {
csAssetsUrl = this.transformUrl(cma, 'am-api');
}
if (!authUrl) {
authUrl = this.transformUrl(cma, 'auth-api');
}
let customRegion: Region = {
cda,
cma,
Expand All @@ -125,6 +132,17 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
launchHubUrl,
composableStudioUrl,
csAssetsUrl,
endpoints: {
contentManagement: cma,
contentDelivery: cda,
application: uiHost,
developerHub: developerHubUrl,
launch: launchHubUrl,
personalizeManagement: personalizeUrl,
composableStudio: composableStudioUrl,
assetManagement: csAssetsUrl,
auth: authUrl,
},
};
customRegion = regionHandler.setCustomRegion(customRegion);
await authHandler.setConfigData('logout'); //Todo: Handle this logout flow well through logout command call
Expand All @@ -137,6 +155,7 @@ export default class RegionSetCommand extends BaseCommand<typeof RegionSetComman
cliux.success(`Launch URL: ${customRegion.launchHubUrl}`);
cliux.success(`Studio URL: ${customRegion.composableStudioUrl}`);
cliux.success(`Contentstack Assets URL: ${customRegion.csAssetsUrl}`);
cliux.success(`Auth API URL: ${customRegion.endpoints?.auth}`);
} catch (error) {
handleAndLogError(error, { ...this.contextDetails, module: 'config-set-region' });
}
Expand Down
1 change: 1 addition & 0 deletions packages/contentstack-config/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export interface Region {
launchHubUrl: string;
composableStudioUrl: string;
csAssetsUrl?: string;
endpoints?: Record<string, string>;
}

export interface Limit {
Expand Down
55 changes: 20 additions & 35 deletions packages/contentstack-config/src/utils/region-handler.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { configHandler } from '@contentstack/cli-utilities';
import { getContentstackEndpoint } from '@contentstack/utils';
import { configHandler, resolveCanonicalEndpoints, buildRegionFromEndpoints } from '@contentstack/cli-utilities';
import { Region, RegionsMap } from '../interfaces';

function validURL(str) {
Expand All @@ -23,28 +22,10 @@ function validURL(str) {
* @returns {object} Region object with all necessary URLs
*/
function getRegionObject(regionKey: string): Region {
try {
// getContentstackEndpoint handles all aliases defined in regions.json
const endpoints = getContentstackEndpoint(regionKey) as any;

if (typeof endpoints === 'string') {
throw new Error('Invalid endpoint response');
}

return {
name: regionKey,
cma: endpoints.contentManagement,
cda: endpoints.contentDelivery,
uiHost: endpoints.application,
developerHubUrl: endpoints.developerHub,
launchHubUrl: endpoints.launch,
personalizeUrl: endpoints.personalizeManagement,
composableStudioUrl: endpoints.composableStudio,
csAssetsUrl: endpoints.assetManagement,
};
} catch {
return null;
}
// resolveCanonicalEndpoints handles all aliases defined in regions.json
const endpoints = resolveCanonicalEndpoints(regionKey);
if (!endpoints) return null;
return buildRegionFromEndpoints(regionKey, endpoints) as Region;
}

/**
Expand Down Expand Up @@ -147,19 +128,23 @@ class UserConfig {
* @returns { object } JSON object with only valid keys for region
*/
sanitizeRegionObject(regionObject) {
const sanitizedRegion = {
cma: regionObject.cma,
cda: regionObject.cda,
uiHost: regionObject.uiHost,
name: regionObject.name,
developerHubUrl: regionObject['developerHubUrl'],
personalizeUrl: regionObject['personalizeUrl'],
launchHubUrl: regionObject['launchHubUrl'],
composableStudioUrl: regionObject['composableStudioUrl'],
csAssetsUrl: regionObject['csAssetsUrl'],
// endpoints is the single source of truth — every friendly field (cma, cda, ...,
// auth, csAssetsUrl) is derived from it below via buildRegionFromEndpoints, same
// as named regions. Falls back to synthesizing endpoints from the individual raw
// fields when the caller didn't supply one directly.
const endpoints = regionObject['endpoints'] ?? {
contentManagement: regionObject.cma,
contentDelivery: regionObject.cda,
application: regionObject.uiHost,
developerHub: regionObject['developerHubUrl'],
launch: regionObject['launchHubUrl'],
personalizeManagement: regionObject['personalizeUrl'],
composableStudio: regionObject['composableStudioUrl'],
assetManagement: regionObject['csAssetsUrl'],
auth: regionObject['authUrl'],
};

return sanitizedRegion;
return buildRegionFromEndpoints(regionObject.name, endpoints);
}
}

Expand Down
82 changes: 81 additions & 1 deletion packages/contentstack-config/test/unit/commands/region.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,87 @@ describe('Region command', function () {
csAssetsUrl: 'https://custom-asset-management.com',
};
const result = UserConfig.setCustomRegion(customRegion);
expect(result).to.deep.equal(customRegion);
expect(result.cma).to.equal(customRegion.cma);
expect(result.cda).to.equal(customRegion.cda);
expect(result.uiHost).to.equal(customRegion.uiHost);
expect(result.name).to.equal(customRegion.name);
expect(result.developerHubUrl).to.equal(customRegion.developerHubUrl);
expect(result.personalizeUrl).to.equal(customRegion.personalizeUrl);
expect(result.launchHubUrl).to.equal(customRegion.launchHubUrl);
expect(result.composableStudioUrl).to.equal(customRegion.composableStudioUrl);
});

it('should include a matching endpoints object for a custom region without an auth host', function () {
const customRegion = {
cma: 'https://custom-cma.com',
cda: 'https://custom-cda.com',
uiHost: 'https://custom-ui.com',
name: 'Custom Region',
developerHubUrl: 'https://custom-developer-hub.com',
personalizeUrl: 'https://custom-personalize.com',
launchHubUrl: 'https://custom-launch.com',
composableStudioUrl: 'https://custom-composable-studio.com',
};
const result = UserConfig.setCustomRegion(customRegion);
expect(result.endpoints).to.deep.equal({
contentManagement: customRegion.cma,
contentDelivery: customRegion.cda,
application: customRegion.uiHost,
developerHub: customRegion.developerHubUrl,
launch: customRegion.launchHubUrl,
personalizeManagement: customRegion.personalizeUrl,
composableStudio: customRegion.composableStudioUrl,
assetManagement: undefined,
auth: undefined,
});
});

it('should preserve an explicitly supplied endpoints object for a custom region', function () {
const endpoints = {
contentManagement: 'https://custom-cma.com',
contentDelivery: 'https://custom-cda.com',
application: 'https://custom-ui.com',
auth: 'https://custom-auth.com',
};
const customRegion = {
cma: 'https://custom-cma.com',
cda: 'https://custom-cda.com',
uiHost: 'https://custom-ui.com',
name: 'Custom Region',
endpoints,
};
const result = UserConfig.setCustomRegion(customRegion);
expect(result.cma).to.equal(endpoints.contentManagement);
expect(result.cda).to.equal(endpoints.contentDelivery);
expect(result.uiHost).to.equal(endpoints.application);
expect(result.endpoints).to.deep.equal(endpoints);
});

it('should not fall back to a stale legacy authUrl input once endpoints.auth is supplied', function () {
// endpoints is the single source of truth: a stale/mismatched top-level
// authUrl on the raw input is never used — only endpoints.auth matters.
const customRegion = {
cma: 'https://custom-cma.com',
cda: 'https://custom-cda.com',
uiHost: 'https://custom-ui.com',
name: 'Custom Region',
authUrl: 'https://stale-auth.com',
endpoints: {
contentManagement: 'https://custom-cma.com',
contentDelivery: 'https://custom-cda.com',
application: 'https://custom-ui.com',
auth: 'https://correct-auth.com',
},
};
const result = UserConfig.setCustomRegion(customRegion);
expect(result.endpoints.auth).to.equal('https://correct-auth.com');
});

it('should include the full endpoints passthrough (incl. auth) for named regions', function () {
const result = UserConfig.setRegion('NA');
expect(result.endpoints).to.be.an('object');
expect(result.endpoints.auth).to.equal('https://auth-api.contentstack.com');
expect(result.endpoints.contentManagement).to.equal(result.cma);
});

it('should sanitize region object to only include valid properties', function () {
Expand Down
Loading
Loading