Skip to content

Feat/query support #2001

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Jul 21, 2025
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
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
Expand Up @@ -6,7 +6,7 @@ fileignoreconfig:
- filename: packages/contentstack-import/test/integration/environments.test.js
checksum: e71f033dad8944ffeafdf22d0514bda1d20c43e8fea0d62c96e774f3414beb31
- filename: package-lock.json
checksum: 52bdeb0247e4b4e19510cd289f0baf1392000fbc64f06661291ffe08f440c89b
checksum: 48aade36a6bb3150851296921f0fc425cc92952d6651528d27576eb24bff422f
- filename: packages/contentstack-auth/test/unit/tokens-validation.test.ts
checksum: 676052e30d31a771ce68302d89b050d176bbef50f3abc7e9cdd4384f0e274e10
- filename: packages/contentstack-import/test/integration/auth-token.test.js
Expand Down Expand Up @@ -53,4 +53,6 @@ fileignoreconfig:
checksum: db5b7aedcd89d783760eb988a2369243c34edc9c12e93a41b2b08fb0da02afdc
- filename: packages/contentstack-export/src/export/modules/assets.ts
checksum: c7f19e6c4a212329d981cebce9a9a8393923dd7c85feb762ddcdca678f7a9349
- filename: packages/contentstack/README.md
checksum: d6da4ce77d52464737a4f22034f62fb93e47ec9200f8f788f06dbcedaae123b3
version: ''
6,406 changes: 3,116 additions & 3,290 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/contentstack-audit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $ npm install -g @contentstack/cli-audit
$ csdx COMMAND
running command...
$ csdx (--version|-v)
@contentstack/cli-audit/1.13.0 darwin-x64 node-v22.17.0
@contentstack/cli-audit/1.13.0 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-auth/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-auth
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-auth/1.4.1 darwin-x64 node-v22.17.0
@contentstack/cli-auth/1.4.1 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-bootstrap/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ $ npm install -g @contentstack/cli-cm-bootstrap
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-cm-bootstrap/1.14.1 darwin-x64 node-v22.17.0
@contentstack/cli-cm-bootstrap/1.14.1 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
1 change: 0 additions & 1 deletion packages/contentstack-bootstrap/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
"clean": "rm -rf ./lib ./node_modules tsconfig.build.tsbuildinfo",
"compile": "tsc -b tsconfig.json",
"postpack": "rm -f oclif.manifest.json",
"posttest": "eslint . --ext .ts --config .eslintrc",
"prepack": "pnpm compile && oclif manifest && oclif readme",
"version": "oclif readme && git add README.md",
"test": "npm run build && npm run test:e2e",
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-bootstrap/src/bootstrap/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,4 +131,4 @@ export default class Bootstrap {
cliux.error(messageHandler.parse('CLI_BOOTSTRAP_STACK_CREATION_FAILED', this.appConfig.stack));
}
}
}
}
2 changes: 1 addition & 1 deletion packages/contentstack-branches/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ $ npm install -g @contentstack/cli-cm-branches
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-cm-branches/1.4.3 darwin-x64 node-v22.17.0
@contentstack/cli-cm-branches/1.4.3 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-bulk-publish/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-cm-bulk-publish
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-cm-bulk-publish/1.8.2 darwin-x64 node-v22.17.0
@contentstack/cli-cm-bulk-publish/1.8.2 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-clone/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ $ npm install -g @contentstack/cli-cm-clone
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-cm-clone/1.14.3 darwin-arm64 node-v22.14.0
@contentstack/cli-cm-clone/1.14.3 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
70 changes: 32 additions & 38 deletions packages/contentstack-config/.eslintrc
Original file line number Diff line number Diff line change
@@ -1,40 +1,34 @@
{
"env": {
"node": true
},
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "tsconfig.json",
"sourceType": "module"
},
"extends": [
"plugin:@typescript-eslint/recommended"
],
"rules": {
"@typescript-eslint/no-unused-vars": [
"error",
{
"args": "none"
}
],
"@typescript-eslint/prefer-namespace-keyword": "error",
"@typescript-eslint/quotes": [
"error",
"single",
{
"avoidEscape": true,
"allowTemplateLiterals": true
}
],
"semi": "off",
"@typescript-eslint/type-annotation-spacing": "error",
"@typescript-eslint/no-redeclare": "off",
"eqeqeq": [
"error",
"smart"
],
"id-match": "error",
"no-eval": "error",
"no-var": "error"
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "plugin:mocha/recommended"],
"parser": "@typescript-eslint/parser",
"plugins": ["@typescript-eslint", "mocha"],
"rules": {
"unicorn/no-abusive-eslint-disable": "off",
"@typescript-eslint/no-use-before-define": "off",
"@typescript-eslint/ban-ts-ignore": "off",
"indent": "off",
"object-curly-spacing": "off",
"@typescript-eslint/no-unused-vars": ["error", { "argsIgnorePattern": "^_" }],
"mocha/no-async-describe": "off",
"mocha/no-identical-title": "off",
"mocha/no-mocha-arrows": "off",
"mocha/no-setup-in-describe": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-var-requires": "off",
"prefer-const": "error",
"no-fallthrough": "error",
"no-prototype-builtins": "off"
},
"env": {
"node": true,
"mocha": true
},
"overrides": [
{
"files": ["*.d.ts"],
"rules": {
"@typescript-eslint/no-explicit-any": "off"
}
}
}
]
}
2 changes: 1 addition & 1 deletion packages/contentstack-config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ $ npm install -g @contentstack/cli-config
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-config/1.13.0 darwin-x64 node-v22.17.0
@contentstack/cli-config/1.13.1 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down
3 changes: 1 addition & 2 deletions packages/contentstack-config/src/interfaces/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ export interface InquirePayload {
name: string;
message: string;
choices?: Array<any>;
// eslint-disable-next-line @typescript-eslint/ban-types
transformer?: Function;
transformer?: (value: any) => any;
}

export interface Region {
Expand Down
6 changes: 3 additions & 3 deletions packages/contentstack-export/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ $ npm install -g @contentstack/cli-cm-export
$ csdx COMMAND
running command...
$ csdx (--version)
@contentstack/cli-cm-export/1.17.0 darwin-x64 node-v22.17.0
@contentstack/cli-cm-export/1.18.0 darwin-arm64 node-v22.13.1
$ csdx --help [COMMAND]
USAGE
$ csdx COMMAND
Expand Down Expand Up @@ -83,7 +83,7 @@ FLAGS
-m, --module=<value> [optional] Specific module name. If not specified, the export command will export all
the modules to the stack. The available modules are assets, content-types, entries,
environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks,
workflows, custom-roles, and taxonomies.
workflows, custom-roles, personalize projects, and taxonomies.
-t, --content-types=<value>... [optional] The UID of the content type(s) whose content you want to export. In case
of multiple content types, specify the IDs separated by spaces.
-y, --yes [optional] Force override all Marketplace prompts.
Expand Down Expand Up @@ -132,7 +132,7 @@ FLAGS
-m, --module=<value> [optional] Specific module name. If not specified, the export command will export all
the modules to the stack. The available modules are assets, content-types, entries,
environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks,
workflows, custom-roles, and taxonomies.
workflows, custom-roles, personalize projects, and taxonomies.
-t, --content-types=<value>... [optional] The UID of the content type(s) whose content you want to export. In case
of multiple content types, specify the IDs separated by spaces.
-y, --yes [optional] Force override all Marketplace prompts.
Expand Down
2 changes: 1 addition & 1 deletion packages/contentstack-export/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-cm-export",
"description": "Contentstack CLI plugin to export content from stack",
"version": "1.17.0",
"version": "1.18.0",
"author": "Contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"dependencies": {
Expand Down
15 changes: 11 additions & 4 deletions packages/contentstack-export/src/commands/cm/stacks/export.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,19 +72,22 @@ export default class ExportCommand extends Command {
}),
module: flags.string({
char: 'm',
description: '[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, and taxonomies.',
description:
'[optional] Specific module name. If not specified, the export command will export all the modules to the stack. The available modules are assets, content-types, entries, environments, extensions, marketplace-apps, global-fields, labels, locales, webhooks, workflows, custom-roles, personalize projects, and taxonomies.',
parse: printFlagDeprecation(['-m'], ['--module']),
}),
'content-types': flags.string({
char: 't',
description: '[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.',
description:
'[optional] The UID of the content type(s) whose content you want to export. In case of multiple content types, specify the IDs separated by spaces.',
multiple: true,
parse: printFlagDeprecation(['-t'], ['--content-types']),
}),
branch: flags.string({
char: 'B',
// default: 'main',
description: '[optional] The name of the branch where you want to export your content. If you don\'t mention the branch name, then by default the content will be exported from all the branches of your stack.',
description:
"[optional] The name of the branch where you want to export your content. If you don't mention the branch name, then by default the content will be exported from all the branches of your stack.",
parse: printFlagDeprecation(['-B'], ['--branch']),
}),
'secured-assets': flags.boolean({
Expand All @@ -95,6 +98,10 @@ export default class ExportCommand extends Command {
required: false,
description: '[optional] Force override all Marketplace prompts.',
}),
query: flags.string({
description: '[optional] Query object (inline JSON or file path) to filter module exports.',
hidden: true,
}),
};

static aliases: string[] = ['cm:export'];
Expand All @@ -107,7 +114,7 @@ export default class ExportCommand extends Command {
// Note setting host to create cma client
exportConfig.host = this.cmaHost;
exportConfig.region = this.region;
if(this.developerHubUrl) exportConfig.developerHubBaseUrl = this.developerHubUrl;
if (this.developerHubUrl) exportConfig.developerHubBaseUrl = this.developerHubUrl;
if (this.personalizeUrl) exportConfig.modules.personalize.baseURL[exportConfig.region.name] = this.personalizeUrl;
exportDir = sanitizePath(exportConfig.cliLogsPath || exportConfig.data || exportConfig.exportDir);
const managementAPIClient: ContentstackClient = await managementSDKClient(exportConfig);
Expand Down
21 changes: 14 additions & 7 deletions packages/contentstack-export/src/export/module-exporter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,23 @@ class ModuleExporter {

async exportSingleModule(moduleName: Modules): Promise<void> {
// Note stack is always exported
let exportModules: Modules[] = ['stack'];
const {
modules: { [moduleName]: { dependencies = [] } = {} },
} = this.exportConfig;

if (dependencies.length > 0) {
exportModules = exportModules.concat(dependencies);
let exportModules: Modules[] = [];
if (!this.exportConfig.skipStackSettings) {
exportModules.push('stack');
}

exportModules.push(moduleName);

if (!this.exportConfig.skipDependencies) {
const {
modules: { [moduleName]: { dependencies = [] } = {} },
} = this.exportConfig;

if (dependencies.length > 0) {
exportModules = exportModules.concat(dependencies);
}
}

for (const moduleName of exportModules) {
await this.exportByModuleByName(moduleName);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ export default class ExportAssets extends BaseClass {
include_publish_details: true,
except: { BASE: this.assetConfig.invalidKeys },
};
this.applyQueryFilters(queryParam, 'assets');

if (this.assetConfig.includeVersionedAssets) {
const customHandler = (array: Array<any>) => {
Expand Down
14 changes: 14 additions & 0 deletions packages/contentstack-export/src/export/modules/base-class.ts
Original file line number Diff line number Diff line change
Expand Up @@ -187,4 +187,18 @@ export default abstract class BaseClass {
return Promise.resolve();
}
}

protected applyQueryFilters(requestObject: any, moduleName: string): any {
if (this.exportConfig.query?.modules?.[moduleName]) {
const moduleQuery = this.exportConfig.query.modules[moduleName];
// Merge the query parameters with existing requestObject
if (moduleQuery) {
if (!requestObject.query) {
requestObject.query = moduleQuery;
}
Object.assign(requestObject.query, moduleQuery);
}
}
return requestObject;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default class ContentTypesExport extends BaseClass {
skip?: number;
limit?: number;
include_global_field_schema: boolean;
uid?: Record<string, string[]>
uid?: Record<string, string[]>;
};
private contentTypesConfig: {
dirName?: string;
Expand All @@ -38,11 +38,14 @@ export default class ContentTypesExport extends BaseClass {
include_global_field_schema: true,
};

// If content type id is provided then use it as part of query
if (Array.isArray(this.exportConfig.contentTypes) && this.exportConfig.contentTypes.length > 0) {
// If content type id is provided then use it as part of query
if (Array.isArray(this.exportConfig.contentTypes) && this.exportConfig.contentTypes.length > 0) {
this.qs.uid = { $in: this.exportConfig.contentTypes };
}

}

// Add after existing qs setup and before contentTypesDirPath
this.applyQueryFilters(this.qs, 'content-types');

this.contentTypesDirPath = path.resolve(
sanitizePath(exportConfig.data),
sanitizePath(exportConfig.branchName || ''),
Expand Down Expand Up @@ -99,7 +102,10 @@ export default class ContentTypesExport extends BaseClass {
async writeContentTypes(contentTypes: Record<string, unknown>[]) {
function write(contentType: Record<string, unknown>) {
return fsUtil.writeFile(
path.join(sanitizePath(this.contentTypesDirPath), sanitizePath(`${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`)),
path.join(
sanitizePath(this.contentTypesDirPath),
sanitizePath(`${contentType.uid === 'schema' ? 'schema|1' : contentType.uid}.json`),
),
contentType,
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default class ExportExtensions extends BaseClass {
this.extensions = {};
this.extensionConfig = exportConfig.modules.extensions;
this.qs = { include_count: true };
this.applyQueryFilters(this.qs, 'extensions');
}

async start(): Promise<void> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,14 +35,15 @@ export default class GlobalFieldsExport extends BaseClass {
asc: 'updated_at',
include_count: true,
limit: this.globalFieldsConfig.limit,
include_global_field_schema: true
include_global_field_schema: true,
};
this.globalFieldsDirPath = path.resolve(
sanitizePath(exportConfig.data),
sanitizePath(exportConfig.branchName || ''),
sanitizePath(this.globalFieldsConfig.dirName),
);
this.globalFields = [];
this.applyQueryFilters(this.qs, 'global-fields');
}

async start() {
Expand All @@ -62,7 +63,7 @@ export default class GlobalFieldsExport extends BaseClass {
if (skip) {
this.qs.skip = skip;
}
let globalFieldsFetchResponse = await this.stackAPIClient.globalField({api_version: '3.2'}).query(this.qs).find();
let globalFieldsFetchResponse = await this.stackAPIClient.globalField({ api_version: '3.2' }).query(this.qs).find();
if (Array.isArray(globalFieldsFetchResponse.items) && globalFieldsFetchResponse.items.length > 0) {
this.sanitizeAttribs(globalFieldsFetchResponse.items);
skip += this.globalFieldsConfig.limit || 100;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export default class ExportTaxonomies extends BaseClass {
this.taxonomies = {};
this.taxonomiesConfig = exportConfig.modules.taxonomies;
this.qs = { include_count: true, limit: this.taxonomiesConfig.limit || 100, skip: 0 };
this.applyQueryFilters(this.qs, 'taxonomies');
}

async start(): Promise<void> {
Expand Down
Loading
Loading