Skip to content
Closed
Show file tree
Hide file tree
Changes from all 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
6 changes: 4 additions & 2 deletions .talismanrc
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
fileignoreconfig:
- filename: pnpm-lock.yaml
checksum: 97a6a5b7d3ddb046ccd03d135c0421e674a4dbbc3f9466380481c5e3dac1ebd3
checksum: 39a9016fc7e0f41e8bc178bcd342a5c0574c7999a69c3bcec6713709b9557135
- filename: packages/contentstack-import/test/integration/auth-token-modules/environments.test.js
checksum: bc6f06b75d082aaf99e2f2f4b932b143765e2f14086967fb8973fe1b2ca6c03e
- filename: packages/contentstack-import/test/integration/environments.test.js
checksum: e71f033dad8944ffeafdf22d0514bda1d20c43e8fea0d62c96e774f3414beb31
- filename: package-lock.json
checksum: 8699ac1d7b2d3af92b6a95cbb9898ad5bb4e7eb17527824cd6ecdd14e6cfde5a
checksum: 89eb78e0882a4a4ffbf95c4f8b8655bb27c4293849eb0f57f3ad362317833606
- 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-migrate-rte/test/commands/json-migration.test.js
checksum: 09dbd275b308ebebc8173eb5c73faea1b98a9f04562bbb82dbc46330116aa325
version: ''
19,736 changes: 8,451 additions & 11,285 deletions package-lock.json

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion packages/contentstack-export-to-csv/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@contentstack/cli-cm-export-to-csv",
"description": "Export entities to csv",
"version": "1.8.2",
"version": "1.9.0",
"author": "Abhinav Gupta @abhinav-from-contentstack",
"bugs": "https://github.com/contentstack/cli/issues",
"dependencies": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const {
isAuthenticated,
cliux,
doesBranchExist,
isManagementTokenValid
isManagementTokenValid,
} = require('@contentstack/cli-utilities');
const util = require('../../util');
const config = require('../../util/config');
Expand All @@ -16,8 +16,9 @@ class ExportToCsvCommand extends Command {
action: flags.string({
required: false,
multiple: false,
options: ['entries', 'users', 'teams', 'taxonomies'],
description: 'Option to export data (entries, users, teams, taxonomies). <options: entries|users|teams|taxonomies>',
options: ['entries', 'users', 'teams', 'taxonomies', 'assets'],
description:
'Option to export data (entries, users, teams, taxonomies). <options: entries|users|teams|taxonomies|assets>',
}),
alias: flags.string({
char: 'a',
Expand Down Expand Up @@ -70,7 +71,7 @@ class ExportToCsvCommand extends Command {
description: '[optional] Provide a delimiter to separate individual data fields within the CSV file. For example: cm:export-to-csv --delimiter \'|\'',
default: ',',
}),
};
};

async run() {
try {
Expand All @@ -88,7 +89,7 @@ class ExportToCsvCommand extends Command {
branch: branchUid,
"team-uid": teamUid,
'taxonomy-uid': taxonomyUID,
delimiter
delimiter,
},
} = await this.parse(ExportToCsvCommand);

Expand Down Expand Up @@ -222,15 +223,15 @@ class ExportToCsvCommand extends Command {
}
case config.exportTeams:
case 'teams': {
try{
try {
let organization;
if (org) {
organization = { uid: org, name: orgName || org };
} else {
organization = await util.chooseOrganization(managementAPIClient, action); // prompt for organization
}
await util.exportTeams(managementAPIClient,organization,teamUid, delimiter);

await util.exportTeams(managementAPIClient, organization, teamUid, delimiter);
} catch (error) {
if (error.message || error.errorMessage) {
cliux.error(util.formatError(error));
Expand All @@ -254,6 +255,60 @@ class ExportToCsvCommand extends Command {
await this.createTaxonomyAndTermCsvFile(stackAPIClient, stackName, stack, taxonomyUID, delimiter);
break;
}
case config.exportAssets:
case 'assets': {
let stack;
let stackAPIClient;
if (managementTokenAlias) {
const { stackDetails, apiClient } = await this.getAliasDetails(managementTokenAlias, stackName);
managementAPIClient = apiClient;
stack = stackDetails;
} else {
stack = await this.getStackDetails(managementAPIClient, stackAPIKey, org);
}

stackAPIClient = this.getStackClient(managementAPIClient, stack);

const [assetsCount, assetsFolderCount] = await Promise.all([
util.getAssetsCount(stackAPIClient),
util.getAssetsCount(stackAPIClient, true),
]);

console.log(`Total assets found: ${assetsCount}`);
console.log(`Total asset folders found: ${assetsFolderCount}`);

if (assetsCount > 0) {
const assets = await util.getAssetsAndFolders(stackAPIClient, assetsCount);
const filteredAssets = assets.map((asset) => {
const { uid, title, _version, parent_uid, filename, file_size } = asset;
return {
uid,
title,
parent_uid,
_version,
filename,
file_size,
};
});
util.write(this, filteredAssets, 'Assets.csv', 'Assets', delimiter);
}

if (assetsFolderCount > 0) {
const assetsFolders = await util.getAssetsAndFolders(stackAPIClient, assetsCount, true);

const filterAssetFolders = assetsFolders.map((assetFolder) => {
const { uid, name, _version, parent_uid } = assetFolder;
return {
uid,
name,
_version,
parent_uid,
};
});

util.write(this, filterAssetFolders, 'AssetsFolder.csv', 'Assets Folders', delimiter);
}
}
}
} catch (error) {
if (error.message || error.errorMessage) {
Expand Down Expand Up @@ -438,7 +493,7 @@ class ExportToCsvCommand extends Command {
const fileName = `${stackName ?? stack.name}_taxonomies.csv`;
const { taxonomiesData, headers } = await util.createImportableCSV(payload, taxonomies);
if (taxonomiesData?.length) {
util.write(this, taxonomiesData, fileName, 'taxonomies',delimiter, headers);
util.write(this, taxonomiesData, fileName, 'taxonomies', delimiter, headers);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions packages/contentstack-export-to-csv/src/util/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ module.exports = {
exportUsers: "Export organization users' data to a .CSV file",
exportTeams: "Export organization teams' data to a .CSV file",
exportTaxonomies: 'Export taxonomies to a .CSV file',
exportAssets: 'Export assets to a .CSV file',
adminError: "Unable to export data. Make sure you're an admin or owner of this organization",
organizationNameRegex: /\'/,
CLI_EXPORT_CSV_LOGIN_FAILED: "You need to login to execute this command. See: auth:login --help",
Expand Down
47 changes: 46 additions & 1 deletion packages/contentstack-export-to-csv/src/util/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,49 @@ function sanitizeData(flatData) {
return flatData;
}

function getAssetsCount(stack, isDir = false) {
const queryParam = {
limit: 1,
asc: 'created_at',
include_count: false,
skip: 10 ** 100,
};

if (isDir) queryParam.query = { is_dir: true };

return stack
.asset()
.query(queryParam)
.count()
.then(({ assets }) => assets)
.catch((error) => {
console.log('Error fetching assets count:', error);
});
}

async function getAssetsAndFolders(stack, total, isDir = false) {
let skip = 0;
let limit = 100;
const assets = [];
while (skip <= total) {
const queryParam = {
limit,
query: { is_dir: isDir },
skip,
asc: 'created_at',
include_count: true,
};

try {
const { items } = await stack.asset().query(queryParam).find();
assets.push(...items);
skip = skip + limit;
} catch (error) {
console.error('Error fetching assets:', error);
}
}
return assets;
}
function cleanEntries(entries, language, environments, contentTypeUid) {
const filteredEntries = entries.filter((entry) => {
return entry['locale'] === language;
Expand Down Expand Up @@ -472,7 +515,7 @@ function startupQuestions() {
type: 'list',
name: 'action',
message: 'Choose Action',
choices: [config.exportEntries, config.exportUsers, config.exportTeams, config.exportTaxonomies, 'Exit'],
choices: [config.exportEntries, config.exportUsers, config.exportTeams, config.exportTaxonomies, config.exportAssets, 'Exit'],
},
];
inquirer
Expand Down Expand Up @@ -1253,4 +1296,6 @@ module.exports = {
getTaxonomy,
getStacks,
createImportableCSV,
getAssetsAndFolders,
getAssetsCount
};
Original file line number Diff line number Diff line change
Expand Up @@ -396,5 +396,53 @@
}
]
},
"taxonomyCSVData": "`taxonomy1,taxonomy1,,,,,,,\n,,,term1,term1,,,,\n,,,,,term1_2,term1_2,,\n,,,term2,term2,,,,\n,,,,,term2_2,term2_2,,\n,,,,,,,term2_2_1,term2_2_1\n,,,,,term2_1,term2_1,,`"
"taxonomyCSVData": "`taxonomy1,taxonomy1,,,,,,,\n,,,term1,term1,,,,\n,,,,,term1_2,term1_2,,\n,,,term2,term2,,,,\n,,,,,term2_2,term2_2,,\n,,,,,,,term2_2_1,term2_2_1\n,,,,,term2_1,term2_1,,`",
"assets": [
{
"uid": "asset_uid_1",
"title": "Test Asset 1",
"_version": 1,
"parent_uid": null,
"filename": "test-image-1.jpg",
"file_size": 1024000,
"created_by": "user1",
"updated_by": "user1",
"created_at": "2023-08-08T13:52:46.592Z",
"updated_at": "2023-08-08T13:52:46.592Z"
},
{
"uid": "asset_uid_2",
"title": "Test Asset 2",
"_version": 1,
"parent_uid": "folder_uid_1",
"filename": "test-image-2.png",
"file_size": 2048000,
"created_by": "user2",
"updated_by": "user2",
"created_at": "2023-08-08T13:52:46.592Z",
"updated_at": "2023-08-08T13:52:46.592Z"
}
],
"assetFolders": [
{
"uid": "folder_uid_1",
"name": "Test Folder 1",
"_version": 1,
"parent_uid": null,
"created_by": "user1",
"updated_by": "user1",
"created_at": "2023-08-08T13:52:46.592Z",
"updated_at": "2023-08-08T13:52:46.592Z"
},
{
"uid": "folder_uid_2",
"name": "Test Folder 2",
"_version": 1,
"parent_uid": "folder_uid_1",
"created_by": "user2",
"updated_by": "user2",
"created_at": "2023-08-08T13:52:46.592Z",
"updated_at": "2023-08-08T13:52:46.592Z"
}
]
}
Loading
Loading