Skip to content

Commit 8083b63

Browse files
committed
added reviewed changes
1 parent 1eee826 commit 8083b63

File tree

9 files changed

+67
-138
lines changed

9 files changed

+67
-138
lines changed

.talismanrc

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,20 @@
11
fileignoreconfig:
2-
- filename: snyk_output.log
3-
checksum: dfa9dc093345f006cc3fb107b8495fcbe79c524db51f44c08d959c656bedf2f7
4-
- filename: talisman_output.log
5-
checksum: 50a8928e551f9092dafcf50f531c926ac00e2846c564aafaaab70c1ecaa19490
2+
- filename: package-lock.json
3+
checksum: e51e2ec7698f3c6b2d89b368e00b2d52e49efb52361a0da3b8e13fd3bbc49ad8
4+
- filename: test/unit/utils/common-helper.test.ts
5+
checksum: 429885d64e75a276f72dd41c279c10c63f49d4e0e2106c36c465098568bcff29
6+
- filename: test/unit/utils/query-parser-simple.test.ts
7+
checksum: 729b55aee1b850864d137329aea0c1a2f451f1ceabb6f8c799b27ed39b0d860a
8+
- filename: test/unit/utils/content-type-helper.test.ts
9+
checksum: e7a5862e2a8de8d15d66c6c0c5078534c3bcca290f6b7d45a1e394bd0c71a1e8
10+
- filename: test/unit/utils/config-handler.test.ts
11+
checksum: a3d8a4e30a6ee8e05fe556dd614185588f2fe24e6f204f4a26bcb39adff21b1b
12+
- filename: test/unit/utils/referenced-asset-handler.test.ts
13+
checksum: f390a647df28f01c19d20720f8be7f6b25f03b47e9bdfa25ca610e56c15f8efa
14+
- filename: test/unit/query-executor.test.ts
15+
checksum: ce4e79d712e40e663804da3edc71f5a49504673976433952a636356e244e1d6b
16+
- filename: test/unit/utils/dependency-resolver.test.ts
17+
checksum: d4fe3507204ca8abbe8267c4de05473b58d88ffaf7e7a8fa4fd94a2b5827d0c6
18+
- filename: test/unit/module-exporter.test.ts
19+
checksum: 197314b2fb461004fe9f455e2e883a398853aa00f2a92054cb76b32cd1855bc7
620
version: '1.0'

src/commands/cm/stacks/export-query.ts

Lines changed: 2 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,5 @@
11
import { Command } from '@contentstack/cli-command';
2-
import {
3-
cliux,
4-
messageHandler,
5-
managementSDKClient,
6-
flags,
7-
ContentstackClient,
8-
FlagInput,
9-
pathValidator,
10-
sanitizePath,
11-
formatError,
12-
} from '@contentstack/cli-utilities';
2+
import { flags, FlagInput, sanitizePath, formatError } from '@contentstack/cli-utilities';
133
import { QueryExporter } from '../../../core/query-executor';
144
import { QueryExportConfig } from '../../../types';
155
import { log, setupQueryExportConfig } from '../../../utils';
@@ -82,12 +72,8 @@ export default class ExportQueryCommand extends Command {
8272
}
8373

8474
this.exportDir = sanitizePath(exportQueryConfig.exportDir);
85-
86-
// Initialize management API client
87-
const managementAPIClient: ContentstackClient = await managementSDKClient(exportQueryConfig);
88-
8975
// Initialize and run query export
90-
const queryExporter = new QueryExporter(managementAPIClient, exportQueryConfig);
76+
const queryExporter = new QueryExporter(exportQueryConfig);
9177
await queryExporter.execute();
9278

9379
log(exportQueryConfig, 'Query-based export completed successfully!', 'success');

src/config/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ const config: DefaultConfig = {
5252
// Performance settings
5353
fetchConcurrency: 5,
5454
writeConcurrency: 5,
55+
maxCTReferenceDepth: 20,
5556
// Optional settings
5657
};
5758

src/core/module-exporter.ts

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,15 @@
1-
import { ContentstackClient, formatError } from '@contentstack/cli-utilities';
1+
import { formatError } from '@contentstack/cli-utilities';
22
import ExportCommand from '@contentstack/cli-cm-export';
33
import { QueryExportConfig, Modules, ExportOptions } from '../types';
44
import { log } from '../utils/logger';
55
import config from '../config';
66
import * as path from 'path';
77

88
export class ModuleExporter {
9-
private stackAPIClient: ReturnType<ContentstackClient['stack']>;
109
private exportQueryConfig: QueryExportConfig;
1110
private exportedModules: string[] = [];
1211

13-
constructor(stackAPIClient: ReturnType<ContentstackClient['stack']>, exportQueryConfig: QueryExportConfig) {
14-
this.stackAPIClient = stackAPIClient;
12+
constructor(exportQueryConfig: QueryExportConfig) {
1513
this.exportQueryConfig = exportQueryConfig;
1614
}
1715

src/core/query-executor.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { ContentstackClient, sanitizePath } from '@contentstack/cli-utilities';
1+
import { sanitizePath } from '@contentstack/cli-utilities';
22
import * as path from 'path';
33
import { QueryExportConfig, Modules } from '../types';
44
import { QueryParser } from '../utils/query-parser';
@@ -10,18 +10,16 @@ import { ContentTypeDependenciesHandler } from '../utils';
1010
import { AssetReferenceHandler } from '../utils';
1111

1212
export class QueryExporter {
13-
private stackAPIClient: ReturnType<ContentstackClient['stack']>;
1413
private exportQueryConfig: QueryExportConfig;
1514
private queryParser: QueryParser;
1615
private moduleExporter: ModuleExporter;
1716

18-
constructor(managementAPIClient: ContentstackClient, exportQueryConfig: QueryExportConfig) {
17+
constructor(exportQueryConfig: QueryExportConfig) {
1918
this.exportQueryConfig = exportQueryConfig;
2019

2120
// Initialize components
2221
this.queryParser = new QueryParser(this.exportQueryConfig);
2322
this.moduleExporter = new ModuleExporter(this.stackAPIClient, exportQueryConfig);
24-
// this.assetUtils = new AssetUtils(this.exportQueryConfig);
2523
}
2624

2725
async execute(): Promise<void> {
@@ -89,8 +87,11 @@ export class QueryExporter {
8987

9088
log(this.exportQueryConfig, `Starting with ${currentBatch.length} initial content types`, 'info');
9189

90+
// track reference depth
91+
let iterationCount = 0;
9292
// Step 3: Process batches until no new references are found
93-
while (currentBatch.length > 0) {
93+
while (currentBatch.length > 0 && iterationCount < this.exportQueryConfig.maxCTReferenceDepth) {
94+
iterationCount++;
9495
currentBatch.forEach((ct: any) => exportedContentTypeUIDs.add(ct.uid));
9596
// Extract referenced content types from current batch
9697
const referencedUIDs = await referencedHandler.extractReferencedContentTypes(currentBatch);

src/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ export interface DefaultConfig {
171171
assets: string;
172172
};
173173
externalConfigPath?: string;
174+
maxCTReferenceDepth: number;
174175
}
175176

176177
export interface QueryExportConfig extends DefaultConfig {

src/utils/query-parser.ts

Lines changed: 0 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -61,75 +61,5 @@ export class QueryParser {
6161
throw new CLIError(`Module "${module}" is not queryable. Supported modules: ${queryableModules.join(', ')}`);
6262
}
6363
}
64-
65-
// // Validate query structure for each module
66-
// for (const [moduleName, moduleQuery] of Object.entries(query.modules)) {
67-
// this.validateModuleQuery(moduleName, moduleQuery);
68-
// }
69-
70-
// // Validate query depth
71-
// this.validateQueryDepth(query, 0);
7264
}
73-
74-
// private validateModuleQuery(moduleName: string, moduleQuery: any): void {
75-
// if (!moduleQuery || typeof moduleQuery !== 'object') {
76-
// throw new CLIError(`Query for module "${moduleName}" must be an object`);
77-
// }
78-
79-
// const moduleConfig = this.config.modules.definitions[moduleName as any];
80-
// if (moduleConfig?.queryConfig) {
81-
// this.validateQueryOperators(moduleQuery, moduleConfig.queryConfig.supportedOperators);
82-
// this.validateQueryFields(moduleQuery, moduleConfig.queryConfig.supportedFields, moduleName);
83-
// }
84-
// }
85-
86-
// private validateQueryOperators(queryObj: any, supportedOperators: string[]): void {
87-
// for (const [key, value] of Object.entries(queryObj)) {
88-
// if (key.startsWith('$')) {
89-
// if (!supportedOperators.includes(key)) {
90-
// throw new CLIError(`Invalid query operator: ${key}. Supported operators: ${supportedOperators.join(', ')}`);
91-
// }
92-
// }
93-
94-
// if (typeof value === 'object' && value !== null) {
95-
// this.validateQueryOperators(value, supportedOperators);
96-
// }
97-
// }
98-
// }
99-
100-
// private validateQueryFields(queryObj: any, supportedFields: string[], moduleName: string): void {
101-
// for (const [key, value] of Object.entries(queryObj)) {
102-
// if (!key.startsWith('$') && !supportedFields.includes(key)) {
103-
// throw new CLIError(
104-
// `Invalid query field "${key}" for module "${moduleName}". Supported fields: ${supportedFields.join(', ')}`,
105-
// );
106-
// }
107-
108-
// if (typeof value === 'object' && value !== null && !key.startsWith('$')) {
109-
// // Field-level operators are allowed
110-
// this.validateQueryOperators(value, this.config.queryConfig.defaultOperators);
111-
// }
112-
// }
113-
// }
114-
115-
// private validateQueryDepth(obj: any, depth: number): void {
116-
// if (depth > this.config.queryConfig.validation.maxQueryDepth) {
117-
// throw new CLIError(
118-
// `Query depth exceeds maximum allowed depth of ${this.config.queryConfig.validation.maxQueryDepth}`,
119-
// );
120-
// }
121-
122-
// if (typeof obj === 'object' && obj !== null) {
123-
// for (const value of Object.values(obj)) {
124-
// if (typeof value === 'object') {
125-
// this.validateQueryDepth(value, depth + 1);
126-
// }
127-
// if (Array.isArray(value) && value.length > this.config.queryConfig.validation.maxArraySize) {
128-
// throw new CLIError(
129-
// `Array size exceeds maximum allowed size of ${this.config.queryConfig.validation.maxArraySize}`,
130-
// );
131-
// }
132-
// }
133-
// }
134-
// }
13565
}

test/config.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,6 @@
33
"UNIT_EXECUTION_ORDER": [],
44
"INTEGRATION_EXECUTION_ORDER": [],
55
"ENABLE_PREREQUISITES": true,
6-
"REGIONS": ["NA", "EU", "AZURE-NA", "AZURE-EU"],
6+
"REGIONS": ["AWS-NA", "AWS-EU", "AZURE-NA", "AZURE-EU"],
77
"apiKey": "***REMOVED***"
8-
}
8+
}

test/run.test.js

Lines changed: 35 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,40 @@
1-
const { join } = require("path");
2-
const filter = require("lodash/filter");
3-
const forEach = require("lodash/forEach");
4-
const isEmpty = require("lodash/isEmpty");
5-
const isArray = require("lodash/isArray");
6-
const includes = require("lodash/includes");
7-
const { existsSync, readdirSync } = require("fs");
1+
const { join } = require('path');
2+
const filter = require('lodash/filter');
3+
const forEach = require('lodash/forEach');
4+
const isEmpty = require('lodash/isEmpty');
5+
const isArray = require('lodash/isArray');
6+
const includes = require('lodash/includes');
7+
const { existsSync, readdirSync } = require('fs');
88

9-
const { initEnvData, getLoginCredentials } = require('./integration/utils/helper')
10-
const { INTEGRATION_EXECUTION_ORDER, IS_TS, ENABLE_PREREQUISITES } = require("./config.json");
9+
const { initEnvData, getLoginCredentials } = require('./integration/utils/helper');
10+
const { INTEGRATION_EXECUTION_ORDER, IS_TS, ENABLE_PREREQUISITES } = require('./config.json');
1111

1212
// NOTE init env variables
13-
require('dotenv-expand').expand(require('dotenv').config())
13+
require('dotenv-expand').expand(require('dotenv').config());
1414
// require('dotenv').config({ path: resolve(process.cwd(), '.env.test') })
1515

1616
const { INTEGRATION_TEST } = process.env;
1717

18-
initEnvData() // NOTE Prepare env data
18+
initEnvData(); // NOTE Prepare env data
1919

2020
const args = process.argv.slice(2);
21-
const testFileExtension = IS_TS ? '.ts' : '.js'
21+
const testFileExtension = IS_TS ? '.ts' : '.js';
2222

2323
/**
2424
* @method getFileName
2525
* @param {string} file
2626
* @returns {string}
2727
*/
2828
const getFileName = (file) => {
29-
if (includes(file, ".test") && includes(file, testFileExtension)) return file;
30-
else if (includes(file, ".test")) return `${file}${testFileExtension}`;
31-
else if (!includes(file, ".test")) return `${file}.test${testFileExtension}`;
29+
if (includes(file, '.test') && includes(file, testFileExtension)) return file;
30+
else if (includes(file, '.test')) return `${file}${testFileExtension}`;
31+
else if (!includes(file, '.test')) return `${file}.test${testFileExtension}`;
3232
else return `${file}.test${testFileExtension}`;
3333
};
3434

3535
/**
3636
* @method includeInitFileIfExist
37-
* @param {String} basePath
37+
* @param {String} basePath
3838
*/
3939
const includeInitFileIfExist = (basePath, region) => {
4040
const filePath = join(__dirname, basePath, `init.test${testFileExtension}`);
@@ -43,14 +43,14 @@ const includeInitFileIfExist = (basePath, region) => {
4343
if (existsSync(filePath)) {
4444
require(filePath)(region);
4545
}
46-
} catch (err) {
47-
debugger
46+
} catch (err) {
47+
console.error(err.message);
4848
}
49-
}
49+
};
5050

5151
/**
5252
* @method includeCleanUpFileIfExist
53-
* @param {String} basePath
53+
* @param {String} basePath
5454
*/
5555
const includeCleanUpFileIfExist = async (basePath, region) => {
5656
const filePath = join(__dirname, basePath, `clean-up.test${testFileExtension}`);
@@ -59,25 +59,26 @@ const includeCleanUpFileIfExist = async (basePath, region) => {
5959
if (existsSync(filePath)) {
6060
require(filePath)(region);
6161
}
62-
} catch (err) { }
63-
}
62+
} catch (err) {}
63+
};
6464

6565
/**
6666
* @method includeTestFiles
6767
* @param {Array<string>} files
6868
* @param {string} basePath
6969
*/
70-
const includeTestFiles = async (files, basePath = "integration") => {
70+
const includeTestFiles = async (files, basePath = 'integration') => {
7171
let regions = getLoginCredentials();
7272
for (let region of Object.keys(regions)) {
7373
if (ENABLE_PREREQUISITES) {
74-
includeInitFileIfExist(basePath, regions[region]) // NOTE Run all the pre configurations
74+
includeInitFileIfExist(basePath, regions[region]); // NOTE Run all the pre configurations
7575
}
7676

77-
files = filter(files, (name) => (
78-
!includes(`init.test${testFileExtension}`, name) &&
79-
!includes(`clean-up.test${testFileExtension}`, name)
80-
)) // NOTE remove init, clean-up files
77+
files = filter(
78+
files,
79+
(name) =>
80+
!includes(name, `init.test${testFileExtension}`) && !includes(name, `clean-up.test${testFileExtension}`),
81+
); // NOTE remove init, clean-up files
8182

8283
forEach(files, (file) => {
8384
const filename = getFileName(file);
@@ -89,11 +90,11 @@ const includeTestFiles = async (files, basePath = "integration") => {
8990
console.error(`File not found - ${filename}`);
9091
}
9192
} catch (err) {
92-
console.err(err.message)
93+
console.error(err.message);
9394
}
9495
});
9596

96-
await includeCleanUpFileIfExist(basePath, regions[region]) // NOTE run all cleanup code/commands
97+
await includeCleanUpFileIfExist(basePath, regions[region]); // NOTE run all cleanup code/commands
9798
}
9899
};
99100

@@ -102,18 +103,15 @@ const includeTestFiles = async (files, basePath = "integration") => {
102103
* @param {Array<string> | undefined | null | unknown} executionOrder
103104
* @param {boolean} isIntegrationTest
104105
*/
105-
const run = (
106-
executionOrder,
107-
isIntegrationTest = true
108-
) => {
109-
const testFolder = isIntegrationTest ? "integration" : "unit";
106+
const run = (executionOrder, isIntegrationTest = true) => {
107+
const testFolder = isIntegrationTest ? 'integration' : 'unit';
110108

111109
if (isArray(executionOrder) && !isEmpty(executionOrder)) {
112110
includeTestFiles(executionOrder, testFolder);
113111
} else {
114112
const basePath = join(__dirname, testFolder);
115113
const allIntegrationTestFiles = filter(readdirSync(basePath), (file) =>
116-
includes(file, `.test${testFileExtension}`)
114+
includes(file, `.test${testFileExtension}`),
117115
);
118116

119117
includeTestFiles(allIntegrationTestFiles);
@@ -122,7 +120,7 @@ const run = (
122120

123121
if (INTEGRATION_TEST === 'true') {
124122
run(INTEGRATION_EXECUTION_ORDER);
125-
} else if (includes(args, "--unit-test")) {
123+
} else if (includes(args, '--unit-test')) {
126124
// NOTE unit test case will be handled here
127125
// run(UNIT_EXECUTION_ORDER, false);
128126
}

0 commit comments

Comments
 (0)