@contentstack/cli-utilities 1.4.5 → 1.5.1
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/lib/fs-utility/core.d.ts +140 -0
- package/lib/fs-utility/core.js +374 -0
- package/lib/fs-utility/helper.d.ts +3 -0
- package/lib/fs-utility/helper.js +33 -0
- package/lib/fs-utility/index.d.ts +4 -0
- package/lib/fs-utility/index.js +11 -0
- package/lib/fs-utility/types.d.ts +69 -0
- package/lib/fs-utility/types.js +2 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.js +1 -0
- package/lib/interfaces/index.d.ts +1 -1
- package/package.json +5 -4
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { Chunk, PageInfo, WriteFileOptions, FsConstructorOptions, ChunkFilesGetterType } from './types';
|
|
3
|
+
export default class FsUtility {
|
|
4
|
+
private prefixKey;
|
|
5
|
+
private basePath;
|
|
6
|
+
private fileExt;
|
|
7
|
+
private moduleName;
|
|
8
|
+
private currentFileName;
|
|
9
|
+
private keepMetadata;
|
|
10
|
+
private indexFileName;
|
|
11
|
+
private chunkFileSize;
|
|
12
|
+
private omitKeys;
|
|
13
|
+
private defaultInitContent;
|
|
14
|
+
private metaPickKeys;
|
|
15
|
+
private currentFileRelativePath;
|
|
16
|
+
private writableStream;
|
|
17
|
+
private metaData;
|
|
18
|
+
private readIndexer;
|
|
19
|
+
private writeIndexer;
|
|
20
|
+
private metaHandler;
|
|
21
|
+
pageInfo: PageInfo;
|
|
22
|
+
constructor(options?: FsConstructorOptions);
|
|
23
|
+
get isNewFsStructure(): boolean;
|
|
24
|
+
get isIndexFileExist(): boolean;
|
|
25
|
+
get currentPageDetails(): PageInfo;
|
|
26
|
+
get indexFileContent(): Record<string, any>;
|
|
27
|
+
/**
|
|
28
|
+
* @method readChunkFiles
|
|
29
|
+
* @returns Object
|
|
30
|
+
*/
|
|
31
|
+
get readChunkFiles(): {
|
|
32
|
+
next: () => ChunkFilesGetterType;
|
|
33
|
+
previous: () => ChunkFilesGetterType;
|
|
34
|
+
get: (index: number) => ChunkFilesGetterType;
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* @method readFile
|
|
38
|
+
* @param filePath string
|
|
39
|
+
* @param parse boolean | undefined
|
|
40
|
+
* @returns string | undefined
|
|
41
|
+
*/
|
|
42
|
+
readFile(filePath: string, parse?: boolean | undefined): string | Record<string, unknown> | Record<string, unknown>[] | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* @method writeFile
|
|
45
|
+
* @param filePath string
|
|
46
|
+
* @param data Object | undefined
|
|
47
|
+
* @return void
|
|
48
|
+
*/
|
|
49
|
+
writeFile(filePath: string, data: Chunk, mapKeyVal?: boolean): void;
|
|
50
|
+
/**
|
|
51
|
+
* @method makeDirectory
|
|
52
|
+
* @param path string
|
|
53
|
+
* @return Promise<string | undefined>
|
|
54
|
+
*/
|
|
55
|
+
makeDirectory(path: string): Promise<string | undefined>;
|
|
56
|
+
/**
|
|
57
|
+
* @method readdir
|
|
58
|
+
* @param dirPath string | Buffer | URL
|
|
59
|
+
* @returns [string]
|
|
60
|
+
*/
|
|
61
|
+
readdir(dirPath: string | Buffer | URL): string[] | [];
|
|
62
|
+
/**
|
|
63
|
+
* @method createFolderIfNotExist
|
|
64
|
+
* @param path string
|
|
65
|
+
* @return {void}
|
|
66
|
+
*/
|
|
67
|
+
createFolderIfNotExist(path: string): void;
|
|
68
|
+
/**
|
|
69
|
+
* @method writeIntoFile
|
|
70
|
+
* @param {String|Object|Array} chunk Record<string, string>[]
|
|
71
|
+
* @param {WriteFileOptions} options WriteFileOptions
|
|
72
|
+
* @return void
|
|
73
|
+
*/
|
|
74
|
+
writeIntoFile(chunk: Record<string, string>[], options?: WriteFileOptions): void;
|
|
75
|
+
/**
|
|
76
|
+
* @method createNewFile
|
|
77
|
+
* @return {void}
|
|
78
|
+
* @description creating new chunk file
|
|
79
|
+
*/
|
|
80
|
+
protected createNewFile(): void;
|
|
81
|
+
/**
|
|
82
|
+
* @method writeIntoExistingFile
|
|
83
|
+
* @param chunk Record<string, string>[] | object | Array<any> | string;
|
|
84
|
+
* @param options WriteFileOptions
|
|
85
|
+
* @returns void
|
|
86
|
+
*/
|
|
87
|
+
protected writeIntoExistingFile(chunk: Chunk, options?: WriteFileOptions): void;
|
|
88
|
+
/**
|
|
89
|
+
* @method handleKeyValMapAndMetaData
|
|
90
|
+
* @param chunk Chunk
|
|
91
|
+
* @param keyName string
|
|
92
|
+
* @returns Chunk
|
|
93
|
+
*/
|
|
94
|
+
handleKeyValMapAndMetaData(chunk: Chunk, keyName?: string | string[] | undefined): Chunk;
|
|
95
|
+
/**
|
|
96
|
+
* @method completeFile
|
|
97
|
+
* @param closeIndexer boolean
|
|
98
|
+
* @return {void}
|
|
99
|
+
* @description writing chunks into existing file
|
|
100
|
+
*/
|
|
101
|
+
completeFile(closeIndexer?: boolean): void;
|
|
102
|
+
/**
|
|
103
|
+
* @method closeFile
|
|
104
|
+
* @param closeIndexer boolean
|
|
105
|
+
* @return {void}
|
|
106
|
+
* @description closing current write stream
|
|
107
|
+
*/
|
|
108
|
+
protected closeFile(closeIndexer?: boolean): void;
|
|
109
|
+
saveMeta(meta: Chunk): void;
|
|
110
|
+
getPlainMeta(basePath?: string): Record<string, unknown>;
|
|
111
|
+
/**
|
|
112
|
+
* @method getFileByIndex
|
|
113
|
+
* @param _self FsUtility
|
|
114
|
+
* @param index number
|
|
115
|
+
* @returns Promise<string>
|
|
116
|
+
*/
|
|
117
|
+
protected getFileByIndex(index?: number): Promise<Record<string, unknown> | Record<string, unknown>[]>;
|
|
118
|
+
/**
|
|
119
|
+
* @method next
|
|
120
|
+
* @returns Promise<string>
|
|
121
|
+
*/
|
|
122
|
+
protected next(): Promise<Record<string, unknown> | Record<string, unknown>[]>;
|
|
123
|
+
/**
|
|
124
|
+
* @method previous
|
|
125
|
+
* @param _self FsUtility
|
|
126
|
+
* @returns Promise<string>
|
|
127
|
+
*/
|
|
128
|
+
protected previous(): Promise<Record<string, unknown> | Record<string, unknown>[] | Error>;
|
|
129
|
+
/**
|
|
130
|
+
* @method updatePageInfo
|
|
131
|
+
* @param _self FsUtility
|
|
132
|
+
* @param isNext boolean
|
|
133
|
+
* @param index number
|
|
134
|
+
* @returns void
|
|
135
|
+
*/
|
|
136
|
+
updatePageInfo(isNext?: boolean | null, index?: number | null): void;
|
|
137
|
+
removeFile(path: string): void;
|
|
138
|
+
}
|
|
139
|
+
export declare function getDirectories(source: string): string[] | [];
|
|
140
|
+
export declare function getFileList(dirName: string, onlyName?: boolean): Promise<string[] | []>;
|
|
@@ -0,0 +1,374 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFileList = exports.getDirectories = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const mkdirp_1 = tslib_1.__importDefault(require("mkdirp"));
|
|
6
|
+
const keys_1 = tslib_1.__importDefault(require("lodash/keys"));
|
|
7
|
+
const uuid_1 = require("uuid");
|
|
8
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
9
|
+
const node_path_1 = require("node:path");
|
|
10
|
+
const node_fs_1 = require("node:fs");
|
|
11
|
+
const helper_1 = require("./helper");
|
|
12
|
+
class FsUtility {
|
|
13
|
+
constructor(options = {}) {
|
|
14
|
+
var _a;
|
|
15
|
+
this.prefixKey = '';
|
|
16
|
+
this.currentFileName = '';
|
|
17
|
+
this.keepMetadata = false;
|
|
18
|
+
this.metaData = {};
|
|
19
|
+
this.readIndexer = {};
|
|
20
|
+
this.writeIndexer = {};
|
|
21
|
+
this.pageInfo = {
|
|
22
|
+
after: 0,
|
|
23
|
+
before: 0,
|
|
24
|
+
hasNextPage: false,
|
|
25
|
+
hasPreviousPage: false,
|
|
26
|
+
pageInfoUpdated: false,
|
|
27
|
+
};
|
|
28
|
+
const { fileExt, omitKeys, basePath, moduleName, metaHandler, keepMetadata, metaPickKeys, chunkFileSize, indexFileName, defaultInitContent, createDirIfNotExist = true, } = options;
|
|
29
|
+
this.metaHandler = metaHandler;
|
|
30
|
+
this.basePath = basePath || '';
|
|
31
|
+
this.omitKeys = omitKeys || [];
|
|
32
|
+
this.fileExt = fileExt || 'json';
|
|
33
|
+
this.metaPickKeys = metaPickKeys || [];
|
|
34
|
+
this.moduleName = moduleName || 'chunk';
|
|
35
|
+
this.chunkFileSize = chunkFileSize || 10;
|
|
36
|
+
this.keepMetadata = keepMetadata || ((_a = keepMetadata === undefined) !== null && _a !== void 0 ? _a : true);
|
|
37
|
+
this.indexFileName = indexFileName || 'index.json';
|
|
38
|
+
this.pageInfo.hasNextPage = (0, keys_1.default)(this.indexFileContent).length > 0;
|
|
39
|
+
this.defaultInitContent = defaultInitContent || (this.fileExt === 'json' ? '{' : '');
|
|
40
|
+
if (createDirIfNotExist) {
|
|
41
|
+
this.createFolderIfNotExist(this.basePath);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
get isNewFsStructure() {
|
|
45
|
+
return (0, node_fs_1.existsSync)(`${this.basePath}/metadata.json`) && (0, node_fs_1.existsSync)(`${this.basePath}/files`);
|
|
46
|
+
}
|
|
47
|
+
get isIndexFileExist() {
|
|
48
|
+
return (0, node_fs_1.existsSync)(`${this.basePath}/${this.indexFileName}`);
|
|
49
|
+
}
|
|
50
|
+
get currentPageDetails() {
|
|
51
|
+
return this.pageInfo;
|
|
52
|
+
}
|
|
53
|
+
get indexFileContent() {
|
|
54
|
+
let indexData = {};
|
|
55
|
+
const indexPath = `${this.basePath}/${this.indexFileName}`;
|
|
56
|
+
if ((0, node_fs_1.existsSync)(indexPath)) {
|
|
57
|
+
indexData = JSON.parse((0, node_fs_1.readFileSync)(indexPath, 'utf-8'));
|
|
58
|
+
}
|
|
59
|
+
return indexData;
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* @method readChunkFiles
|
|
63
|
+
* @returns Object
|
|
64
|
+
*/
|
|
65
|
+
get readChunkFiles() {
|
|
66
|
+
return {
|
|
67
|
+
next: this.next.bind(this),
|
|
68
|
+
previous: this.previous.bind(this),
|
|
69
|
+
get: this.getFileByIndex.bind(this),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
// STUB old utility methods
|
|
73
|
+
/**
|
|
74
|
+
* @method readFile
|
|
75
|
+
* @param filePath string
|
|
76
|
+
* @param parse boolean | undefined
|
|
77
|
+
* @returns string | undefined
|
|
78
|
+
*/
|
|
79
|
+
readFile(filePath, parse = undefined) {
|
|
80
|
+
let data;
|
|
81
|
+
filePath = (0, node_path_1.resolve)(filePath);
|
|
82
|
+
parse = typeof parse === 'undefined' ? true : parse;
|
|
83
|
+
if ((0, node_fs_1.existsSync)(filePath)) {
|
|
84
|
+
data = parse ? JSON.parse((0, node_fs_1.readFileSync)(filePath, 'utf-8')) : data;
|
|
85
|
+
}
|
|
86
|
+
return data;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* @method writeFile
|
|
90
|
+
* @param filePath string
|
|
91
|
+
* @param data Object | undefined
|
|
92
|
+
* @return void
|
|
93
|
+
*/
|
|
94
|
+
writeFile(filePath, data, mapKeyVal = false) {
|
|
95
|
+
if (mapKeyVal) {
|
|
96
|
+
data = (0, helper_1.mapKeyAndVal)(data, 'uid', this.omitKeys); // NOTE Map values as Key/value pair object
|
|
97
|
+
}
|
|
98
|
+
data = typeof data === 'object' ? JSON.stringify(data) : data || '{}';
|
|
99
|
+
(0, node_fs_1.writeFileSync)(filePath, data);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* @method makeDirectory
|
|
103
|
+
* @param path string
|
|
104
|
+
* @return Promise<string | undefined>
|
|
105
|
+
*/
|
|
106
|
+
makeDirectory(path) {
|
|
107
|
+
return (0, mkdirp_1.default)(path);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* @method readdir
|
|
111
|
+
* @param dirPath string | Buffer | URL
|
|
112
|
+
* @returns [string]
|
|
113
|
+
*/
|
|
114
|
+
readdir(dirPath) {
|
|
115
|
+
return (0, node_fs_1.existsSync)(dirPath) ? (0, node_fs_1.readdirSync)(dirPath) : [];
|
|
116
|
+
}
|
|
117
|
+
// STUB End of old utility
|
|
118
|
+
/**
|
|
119
|
+
* @method createFolderIfNotExist
|
|
120
|
+
* @param path string
|
|
121
|
+
* @return {void}
|
|
122
|
+
*/
|
|
123
|
+
createFolderIfNotExist(path) {
|
|
124
|
+
if (path && !(0, node_fs_1.existsSync)(path)) {
|
|
125
|
+
(0, node_fs_1.mkdirSync)(path, { recursive: true });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* @method writeIntoFile
|
|
130
|
+
* @param {String|Object|Array} chunk Record<string, string>[]
|
|
131
|
+
* @param {WriteFileOptions} options WriteFileOptions
|
|
132
|
+
* @return void
|
|
133
|
+
*/
|
|
134
|
+
writeIntoFile(chunk, options) {
|
|
135
|
+
if (!this.writableStream) {
|
|
136
|
+
this.createNewFile();
|
|
137
|
+
}
|
|
138
|
+
this.writeIntoExistingFile(chunk, options);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* @method createNewFile
|
|
142
|
+
* @return {void}
|
|
143
|
+
* @description creating new chunk file
|
|
144
|
+
*/
|
|
145
|
+
createNewFile() {
|
|
146
|
+
const fileName = `${(0, uuid_1.v4)()}-${this.moduleName || 'chunk'}.${this.fileExt}`;
|
|
147
|
+
this.currentFileName = fileName;
|
|
148
|
+
this.writeIndexer[(0, keys_1.default)(this.writeIndexer).length + 1] = fileName;
|
|
149
|
+
this.currentFileRelativePath = `${this.basePath}/${fileName}`;
|
|
150
|
+
(0, node_fs_1.writeFileSync)(this.currentFileRelativePath, this.defaultInitContent);
|
|
151
|
+
this.writableStream = (0, node_fs_1.createWriteStream)(this.currentFileRelativePath, {
|
|
152
|
+
flags: 'a',
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* @method writeIntoExistingFile
|
|
157
|
+
* @param chunk Record<string, string>[] | object | Array<any> | string;
|
|
158
|
+
* @param options WriteFileOptions
|
|
159
|
+
* @returns void
|
|
160
|
+
*/
|
|
161
|
+
writeIntoExistingFile(chunk, options) {
|
|
162
|
+
var _a;
|
|
163
|
+
let fileContent = chunk;
|
|
164
|
+
let fileSizeReachedLimit = false;
|
|
165
|
+
const { keyName, mapKeyVal } = options || {
|
|
166
|
+
keyName: 'uid',
|
|
167
|
+
mapKeyVal: false,
|
|
168
|
+
};
|
|
169
|
+
if (mapKeyVal) {
|
|
170
|
+
fileContent = this.handleKeyValMapAndMetaData(chunk, keyName); // NOTE Map values as Key/value pair object
|
|
171
|
+
}
|
|
172
|
+
if (typeof fileContent === 'object') {
|
|
173
|
+
fileContent = JSON.stringify(fileContent).slice(1, -1);
|
|
174
|
+
}
|
|
175
|
+
const { size } = (0, node_fs_1.statSync)(this.currentFileRelativePath);
|
|
176
|
+
if ((options === null || options === void 0 ? void 0 : options.closeFile) === true || size / (1024 * 1024) >= this.chunkFileSize) {
|
|
177
|
+
// NOTE Each chunk file size Ex. 5 (MB)
|
|
178
|
+
fileSizeReachedLimit = true;
|
|
179
|
+
}
|
|
180
|
+
const suffix = fileSizeReachedLimit ? '}' : '';
|
|
181
|
+
fileContent = this.fileExt === 'json' ? `${this.prefixKey}${fileContent}${suffix}` : fileContent;
|
|
182
|
+
(_a = this.writableStream) === null || _a === void 0 ? void 0 : _a.write(fileContent);
|
|
183
|
+
if (!this.prefixKey)
|
|
184
|
+
this.prefixKey = ',';
|
|
185
|
+
if (fileSizeReachedLimit) {
|
|
186
|
+
this.closeFile((options === null || options === void 0 ? void 0 : options.closeFile) === true);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* @method handleKeyValMapAndMetaData
|
|
191
|
+
* @param chunk Chunk
|
|
192
|
+
* @param keyName string
|
|
193
|
+
* @returns Chunk
|
|
194
|
+
*/
|
|
195
|
+
handleKeyValMapAndMetaData(chunk, keyName) {
|
|
196
|
+
const fileContent = (0, helper_1.mapKeyAndVal)(chunk, keyName || 'uid', this.omitKeys); // NOTE Map values as Key/value pair object
|
|
197
|
+
// NOTE update metadata
|
|
198
|
+
if (this.keepMetadata) {
|
|
199
|
+
const metadata = (0, helper_1.getMetaData)(chunk, this.metaPickKeys, this.metaHandler);
|
|
200
|
+
if (metadata && !(0, isEmpty_1.default)(metadata)) {
|
|
201
|
+
if ((0, isEmpty_1.default)(this.metaData[this.currentFileName]))
|
|
202
|
+
this.metaData[this.currentFileName] = [];
|
|
203
|
+
this.metaData[this.currentFileName].push(...metadata);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return fileContent;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* @method completeFile
|
|
210
|
+
* @param closeIndexer boolean
|
|
211
|
+
* @return {void}
|
|
212
|
+
* @description writing chunks into existing file
|
|
213
|
+
*/
|
|
214
|
+
completeFile(closeIndexer) {
|
|
215
|
+
if (this.writableStream) {
|
|
216
|
+
if (this.fileExt === 'json') {
|
|
217
|
+
this.writableStream.write('}');
|
|
218
|
+
}
|
|
219
|
+
this.closeFile(closeIndexer);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* @method closeFile
|
|
224
|
+
* @param closeIndexer boolean
|
|
225
|
+
* @return {void}
|
|
226
|
+
* @description closing current write stream
|
|
227
|
+
*/
|
|
228
|
+
closeFile(closeIndexer = true) {
|
|
229
|
+
if (closeIndexer) {
|
|
230
|
+
// NOTE write file index details into a file
|
|
231
|
+
(0, node_fs_1.writeFileSync)(`${this.basePath}/${this.indexFileName}`, JSON.stringify(this.writeIndexer));
|
|
232
|
+
// NOTE write metadata into a file
|
|
233
|
+
if (this.keepMetadata) {
|
|
234
|
+
(0, node_fs_1.writeFileSync)(`${this.basePath}/metadata.json`, JSON.stringify(this.metaData));
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
if (this.writableStream instanceof node_fs_1.WriteStream) {
|
|
238
|
+
this.writableStream.end();
|
|
239
|
+
this.prefixKey = '';
|
|
240
|
+
this.writableStream = null;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
saveMeta(meta) {
|
|
244
|
+
(0, node_fs_1.writeFileSync)(`${this.basePath}/metadata.json`, JSON.stringify(meta));
|
|
245
|
+
}
|
|
246
|
+
getPlainMeta(basePath) {
|
|
247
|
+
const path = basePath || (0, node_path_1.resolve)(this.basePath, 'metadata.json');
|
|
248
|
+
if (!(0, node_fs_1.existsSync)(path))
|
|
249
|
+
return {};
|
|
250
|
+
return JSON.parse((0, node_fs_1.readFileSync)(path, { encoding: 'utf-8' }));
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* @method getFileByIndex
|
|
254
|
+
* @param _self FsUtility
|
|
255
|
+
* @param index number
|
|
256
|
+
* @returns Promise<string>
|
|
257
|
+
*/
|
|
258
|
+
getFileByIndex(index = 1) {
|
|
259
|
+
return new Promise((resolve, reject) => {
|
|
260
|
+
if (index <= 0) {
|
|
261
|
+
reject(new Error('Invalid index'));
|
|
262
|
+
return;
|
|
263
|
+
}
|
|
264
|
+
this.updatePageInfo(null, index);
|
|
265
|
+
if ((0, isEmpty_1.default)(this.readIndexer[index])) {
|
|
266
|
+
reject(new Error('File not found!'));
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const fileContent = (0, node_fs_1.readFileSync)((0, node_path_1.resolve)(this.basePath, this.readIndexer[index]), {
|
|
270
|
+
encoding: 'utf-8',
|
|
271
|
+
});
|
|
272
|
+
resolve(this.fileExt === 'json' ? JSON.parse(fileContent) : fileContent);
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* @method next
|
|
277
|
+
* @returns Promise<string>
|
|
278
|
+
*/
|
|
279
|
+
next() {
|
|
280
|
+
return new Promise((resolve, reject) => {
|
|
281
|
+
this.updatePageInfo(true);
|
|
282
|
+
if ((0, isEmpty_1.default)(this.readIndexer[this.pageInfo.after])) {
|
|
283
|
+
reject(new Error('File not found!'));
|
|
284
|
+
return;
|
|
285
|
+
}
|
|
286
|
+
const fileContent = (0, node_fs_1.readFileSync)((0, node_path_1.resolve)(this.basePath, this.readIndexer[this.pageInfo.after]), {
|
|
287
|
+
encoding: 'utf-8',
|
|
288
|
+
});
|
|
289
|
+
resolve(this.fileExt === 'json' ? JSON.parse(fileContent) : fileContent);
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
/**
|
|
293
|
+
* @method previous
|
|
294
|
+
* @param _self FsUtility
|
|
295
|
+
* @returns Promise<string>
|
|
296
|
+
*/
|
|
297
|
+
previous() {
|
|
298
|
+
return new Promise((resolve, reject) => {
|
|
299
|
+
this.updatePageInfo(false);
|
|
300
|
+
if ((0, isEmpty_1.default)(this.readIndexer[this.pageInfo.before])) {
|
|
301
|
+
reject(new Error('File not found'));
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const fileContent = (0, node_fs_1.readFileSync)((0, node_path_1.resolve)(this.basePath, this.readIndexer[this.pageInfo.before]), {
|
|
305
|
+
encoding: 'utf-8',
|
|
306
|
+
});
|
|
307
|
+
resolve(this.fileExt === 'json' ? JSON.parse(fileContent) : fileContent);
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* @method updatePageInfo
|
|
312
|
+
* @param _self FsUtility
|
|
313
|
+
* @param isNext boolean
|
|
314
|
+
* @param index number
|
|
315
|
+
* @returns void
|
|
316
|
+
*/
|
|
317
|
+
updatePageInfo(isNext = true, index = null) {
|
|
318
|
+
if (!this.pageInfo.pageInfoUpdated) {
|
|
319
|
+
this.readIndexer = this.indexFileContent;
|
|
320
|
+
this.pageInfo.pageInfoUpdated = true;
|
|
321
|
+
}
|
|
322
|
+
const { after, before } = this.pageInfo;
|
|
323
|
+
if (isNext === true) {
|
|
324
|
+
this.pageInfo.before = 1;
|
|
325
|
+
this.pageInfo.after = after + 1;
|
|
326
|
+
}
|
|
327
|
+
else if (isNext === false) {
|
|
328
|
+
this.pageInfo.after = 0;
|
|
329
|
+
this.pageInfo.before = before - 1;
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
this.pageInfo.after = index || 0;
|
|
333
|
+
this.pageInfo.before = 1;
|
|
334
|
+
}
|
|
335
|
+
/* eslint-disable unicorn/consistent-destructuring */
|
|
336
|
+
if (!(0, isEmpty_1.default)(this.readIndexer[this.pageInfo.after + 1])) {
|
|
337
|
+
this.pageInfo.hasNextPage = true;
|
|
338
|
+
}
|
|
339
|
+
/* eslint-disable unicorn/consistent-destructuring */
|
|
340
|
+
if (!(0, isEmpty_1.default)(this.readIndexer[this.pageInfo.after - 1])) {
|
|
341
|
+
this.pageInfo.hasPreviousPage = true;
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
removeFile(path) {
|
|
345
|
+
if ((0, node_fs_1.existsSync)(path))
|
|
346
|
+
(0, node_fs_1.unlinkSync)(path);
|
|
347
|
+
}
|
|
348
|
+
}
|
|
349
|
+
exports.default = FsUtility;
|
|
350
|
+
function getDirectories(source) {
|
|
351
|
+
if (!(0, node_fs_1.existsSync)(source))
|
|
352
|
+
return [];
|
|
353
|
+
return (0, node_fs_1.readdirSync)(source, { withFileTypes: true })
|
|
354
|
+
.filter((dirent) => dirent.isDirectory())
|
|
355
|
+
.map((dirent) => dirent.name);
|
|
356
|
+
}
|
|
357
|
+
exports.getDirectories = getDirectories;
|
|
358
|
+
async function getFileList(dirName, onlyName = true) {
|
|
359
|
+
if (!(0, node_fs_1.existsSync)(dirName))
|
|
360
|
+
return [];
|
|
361
|
+
let files = [];
|
|
362
|
+
const items = (0, node_fs_1.readdirSync)(dirName, { withFileTypes: true });
|
|
363
|
+
for (const item of items) {
|
|
364
|
+
if (item.isDirectory()) {
|
|
365
|
+
/* eslint-disable no-await-in-loop */
|
|
366
|
+
files = [...files, ...(await getFileList(`${dirName}/${item.name}`))];
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
files.push(onlyName ? item.name : `${dirName}/${item.name}`);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
return files;
|
|
373
|
+
}
|
|
374
|
+
exports.getFileList = getFileList;
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
declare function mapKeyAndVal(array: Array<Record<string, any>>, keyName: string | string[], omitKeys?: Array<string>): Record<string, unknown>;
|
|
2
|
+
declare function getMetaData(array: Array<Record<string, any>>, pickKeys: Array<string>, handler?: (array: Array<Record<string, any>>) => void): Array<Record<string, unknown>> | undefined;
|
|
3
|
+
export { mapKeyAndVal, getMetaData };
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getMetaData = exports.mapKeyAndVal = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const map_1 = tslib_1.__importDefault(require("lodash/map"));
|
|
6
|
+
const omit_1 = tslib_1.__importDefault(require("lodash/omit"));
|
|
7
|
+
const pick_1 = tslib_1.__importDefault(require("lodash/pick"));
|
|
8
|
+
const assign_1 = tslib_1.__importDefault(require("lodash/assign"));
|
|
9
|
+
const isEmpty_1 = tslib_1.__importDefault(require("lodash/isEmpty"));
|
|
10
|
+
const forEach_1 = tslib_1.__importDefault(require("lodash/forEach"));
|
|
11
|
+
function getKeysFromArray(keys, obj) {
|
|
12
|
+
let keyName = "";
|
|
13
|
+
(0, forEach_1.default)(keys, (key) => {
|
|
14
|
+
keyName += keyName ? `_${obj[key]}` : obj[key];
|
|
15
|
+
});
|
|
16
|
+
return keyName;
|
|
17
|
+
}
|
|
18
|
+
function mapKeyAndVal(array, keyName, omitKeys = []) {
|
|
19
|
+
return (0, assign_1.default)({}, ...(0, map_1.default)(array, (row) => {
|
|
20
|
+
if (Array.isArray(keyName))
|
|
21
|
+
return { [getKeysFromArray(keyName, row)]: (0, omit_1.default)(row, omitKeys) };
|
|
22
|
+
return { [row[keyName]]: (0, omit_1.default)(row, omitKeys) };
|
|
23
|
+
}));
|
|
24
|
+
}
|
|
25
|
+
exports.mapKeyAndVal = mapKeyAndVal;
|
|
26
|
+
function getMetaData(array, pickKeys, handler) {
|
|
27
|
+
if (handler instanceof Function)
|
|
28
|
+
handler(array);
|
|
29
|
+
if ((0, isEmpty_1.default)(array) || (0, isEmpty_1.default)(pickKeys))
|
|
30
|
+
return;
|
|
31
|
+
return (0, map_1.default)(array, (row) => (0, pick_1.default)(row, pickKeys));
|
|
32
|
+
}
|
|
33
|
+
exports.getMetaData = getMetaData;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.getFileList = exports.getDirectories = exports.FsUtility = exports.mapKeyAndVal = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const core_1 = tslib_1.__importStar(require("./core"));
|
|
6
|
+
exports.FsUtility = core_1.default;
|
|
7
|
+
Object.defineProperty(exports, "getDirectories", { enumerable: true, get: function () { return core_1.getDirectories; } });
|
|
8
|
+
Object.defineProperty(exports, "getFileList", { enumerable: true, get: function () { return core_1.getFileList; } });
|
|
9
|
+
tslib_1.__exportStar(require("./types"), exports);
|
|
10
|
+
var helper_1 = require("./helper");
|
|
11
|
+
Object.defineProperty(exports, "mapKeyAndVal", { enumerable: true, get: function () { return helper_1.mapKeyAndVal; } });
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
type FileType = "json" | "txt";
|
|
2
|
+
type Chunk = Record<string, unknown>[] | Record<string, unknown> | Array<unknown> | string;
|
|
3
|
+
type PageInfo = {
|
|
4
|
+
after: number;
|
|
5
|
+
before: number;
|
|
6
|
+
hasNextPage: boolean;
|
|
7
|
+
hasPreviousPage: boolean;
|
|
8
|
+
pageInfoUpdated?: boolean;
|
|
9
|
+
};
|
|
10
|
+
type WriteFileOptions = {
|
|
11
|
+
keyName?: string | string[];
|
|
12
|
+
closeFile?: boolean;
|
|
13
|
+
mapKeyVal?: boolean;
|
|
14
|
+
closeIndexer?: boolean;
|
|
15
|
+
};
|
|
16
|
+
type FsConstructorOptions = {
|
|
17
|
+
createDirIfNotExist?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* basePath is used to pass base paths of an content to be written to
|
|
20
|
+
*
|
|
21
|
+
* Example: ```./contents/data```
|
|
22
|
+
*/
|
|
23
|
+
basePath?: string;
|
|
24
|
+
/**
|
|
25
|
+
* chunk file extension
|
|
26
|
+
*
|
|
27
|
+
* Ex: ```fileExt: 'json' | 'txt'```
|
|
28
|
+
*/
|
|
29
|
+
fileExt?: FileType;
|
|
30
|
+
/**
|
|
31
|
+
* Name of the module data which is going to be written to drive
|
|
32
|
+
*
|
|
33
|
+
* Ex: ```moduleName: 'assets' | 'entries' | 'content-type'```
|
|
34
|
+
*/
|
|
35
|
+
moduleName?: string;
|
|
36
|
+
/**
|
|
37
|
+
* Name of the index manager file name. Which will have all chunk file details
|
|
38
|
+
*
|
|
39
|
+
* ```defaultValue: index.json```
|
|
40
|
+
*
|
|
41
|
+
* Ex: ```indexFileName: 'assets.json' | 'index.json'```
|
|
42
|
+
*/
|
|
43
|
+
indexFileName?: string;
|
|
44
|
+
/**
|
|
45
|
+
* Chunk file size in megabytes
|
|
46
|
+
*
|
|
47
|
+
* ```chunkFileSize: 5``` => 5Mb
|
|
48
|
+
*/
|
|
49
|
+
chunkFileSize?: number;
|
|
50
|
+
omitKeys?: Array<string>;
|
|
51
|
+
/**
|
|
52
|
+
* on initialization if any content needs to be put in the file which can be passed through this key
|
|
53
|
+
*
|
|
54
|
+
* Ex: ```defaultInitContent: '{ title: "test" }'```
|
|
55
|
+
*/
|
|
56
|
+
defaultInitContent?: string;
|
|
57
|
+
/**
|
|
58
|
+
* metaPickKeys is to pik list of key to keep like an index key of entity
|
|
59
|
+
*
|
|
60
|
+
* Ex. ```['title'] | handler: () => {}```
|
|
61
|
+
*
|
|
62
|
+
* Result will be in metadata file: ```{ title: ['title1', 'title2'], versionedAssets: [{ 89987iu89434: 4 }] }```
|
|
63
|
+
*/
|
|
64
|
+
metaPickKeys?: Array<string>;
|
|
65
|
+
keepMetadata?: boolean;
|
|
66
|
+
metaHandler?: (array: any) => any;
|
|
67
|
+
};
|
|
68
|
+
type ChunkFilesGetterType = Promise<Record<string, unknown> | Record<string, unknown>[] | Error>;
|
|
69
|
+
export { Chunk, FileType, PageInfo, WriteFileOptions, FsConstructorOptions, ChunkFilesGetterType };
|
package/lib/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { default as configHandler } from './config-handler';
|
|
|
7
7
|
export { default as managementSDKClient, managementSDKInitiator, ContentstackClient, ContentstackConfig, } from './contentstack-management-sdk';
|
|
8
8
|
export { default as printFlagDeprecation } from './flag-deprecation-check';
|
|
9
9
|
export * from './http-client';
|
|
10
|
+
export * from './fs-utility';
|
|
10
11
|
export { default as NodeCrypto } from './encrypter';
|
|
11
12
|
export { Args as args, Flags as flags, Command } from './cli-ux';
|
|
12
13
|
export * from './helpers';
|
package/lib/index.js
CHANGED
|
@@ -20,6 +20,7 @@ Object.defineProperty(exports, "managementSDKInitiator", { enumerable: true, get
|
|
|
20
20
|
var flag_deprecation_check_1 = require("./flag-deprecation-check");
|
|
21
21
|
Object.defineProperty(exports, "printFlagDeprecation", { enumerable: true, get: function () { return tslib_1.__importDefault(flag_deprecation_check_1).default; } });
|
|
22
22
|
tslib_1.__exportStar(require("./http-client"), exports);
|
|
23
|
+
tslib_1.__exportStar(require("./fs-utility"), exports);
|
|
23
24
|
var encrypter_1 = require("./encrypter");
|
|
24
25
|
Object.defineProperty(exports, "NodeCrypto", { enumerable: true, get: function () { return tslib_1.__importDefault(encrypter_1).default; } });
|
|
25
26
|
var cli_ux_2 = require("./cli-ux");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@contentstack/cli-utilities",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
4
4
|
"description": "Utilities for contentstack projects",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
"author": "contentstack",
|
|
33
33
|
"license": "MIT",
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@contentstack/management": "
|
|
36
|
-
"@oclif/core": "^2.
|
|
35
|
+
"@contentstack/management": "~1.10.0",
|
|
36
|
+
"@oclif/core": "^2.9.3",
|
|
37
37
|
"axios": "1.3.4",
|
|
38
38
|
"chalk": "^4.0.0",
|
|
39
39
|
"cli-cursor": "^3.1.0",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"inquirer": "8.2.4",
|
|
45
45
|
"inquirer-search-checkbox": "^1.0.0",
|
|
46
46
|
"inquirer-search-list": "^1.2.6",
|
|
47
|
+
"mkdirp": "^1.0.4",
|
|
47
48
|
"lodash": "^4.17.15",
|
|
48
49
|
"open": "^8.4.2",
|
|
49
50
|
"ora": "^5.4.0",
|
|
@@ -77,4 +78,4 @@
|
|
|
77
78
|
"tslib": "^1.13.0",
|
|
78
79
|
"typescript": "^4.9.3"
|
|
79
80
|
}
|
|
80
|
-
}
|
|
81
|
+
}
|