@digicroz/node-backend-kit 1.0.0
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/README.md +255 -0
- package/dist/b2fPortalV3/b2fPortal.d.ts +2 -0
- package/dist/b2fPortalV3/b2fPortal.js +199 -0
- package/dist/b2fPortalV3/checkModuleRecords.d.ts +1 -0
- package/dist/b2fPortalV3/checkModuleRecords.js +60 -0
- package/dist/b2fPortalV3/checkModuleZodRecords.d.ts +1 -0
- package/dist/b2fPortalV3/checkModuleZodRecords.js +60 -0
- package/dist/b2fPortalV3/moduleFileCreator.d.ts +1 -0
- package/dist/b2fPortalV3/moduleFileCreator.js +42 -0
- package/dist/b2fPortalV3/moduleZodCreator.d.ts +1 -0
- package/dist/b2fPortalV3/moduleZodCreator.js +41 -0
- package/dist/b2fPortalV3/stripExtensions.d.ts +12 -0
- package/dist/b2fPortalV3/stripExtensions.js +51 -0
- package/dist/b2fPortalV3/syncProjectCommons.d.ts +8 -0
- package/dist/b2fPortalV3/syncProjectCommons.js +180 -0
- package/dist/bin/nbk.d.ts +2 -0
- package/dist/bin/nbk.js +83 -0
- package/dist/cli/addDevVersion.d.ts +1 -0
- package/dist/cli/addDevVersion.js +51 -0
- package/dist/cli/addProdVersion.d.ts +1 -0
- package/dist/cli/addProdVersion.js +71 -0
- package/dist/cli/createInitWorkspaceShellFile.d.ts +1 -0
- package/dist/cli/createInitWorkspaceShellFile.js +129 -0
- package/dist/cli/deleteAllRepos.d.ts +1 -0
- package/dist/cli/deleteAllRepos.js +62 -0
- package/dist/cli/deleteAndCopy.d.ts +6 -0
- package/dist/cli/deleteAndCopy.js +88 -0
- package/dist/cli/deployAllRepos.d.ts +1 -0
- package/dist/cli/deployAllRepos.js +202 -0
- package/dist/cli/fixConfigFile.d.ts +5 -0
- package/dist/cli/fixConfigFile.js +76 -0
- package/dist/cli/gitAcpAllRepos.d.ts +1 -0
- package/dist/cli/gitAcpAllRepos.js +156 -0
- package/dist/cli/gitPushAllRepos.d.ts +1 -0
- package/dist/cli/gitPushAllRepos.js +70 -0
- package/dist/cli/initConfig.d.ts +1 -0
- package/dist/cli/initConfig.js +23 -0
- package/dist/cli/transfer2Shared.d.ts +1 -0
- package/dist/cli/transfer2Shared.js +180 -0
- package/dist/configs/environment.d.ts +4 -0
- package/dist/configs/environment.js +7 -0
- package/dist/helpers/checkCrossProjectImports.d.ts +2 -0
- package/dist/helpers/checkCrossProjectImports.js +73 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +47 -0
- package/dist/types.d.ts +34 -0
- package/dist/types.js +4 -0
- package/dist/utils/jsonFile.d.ts +7 -0
- package/dist/utils/jsonFile.js +24 -0
- package/dist/utils/loadConfig.d.ts +8 -0
- package/dist/utils/loadConfig.js +203 -0
- package/dist/utils/path.d.ts +6 -0
- package/dist/utils/path.js +16 -0
- package/dist/utils/progress.d.ts +65 -0
- package/dist/utils/progress.js +108 -0
- package/dist/utils/vscodeSettings.d.ts +1 -0
- package/dist/utils/vscodeSettings.js +67 -0
- package/nbk.schema.json +95 -0
- package/package.json +80 -0
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recursively finds all .ts files in the provided directory.
|
|
3
|
+
* @param dir The directory to search.
|
|
4
|
+
* @returns An array of full paths to .ts files.
|
|
5
|
+
*/
|
|
6
|
+
export declare function getTsFiles(dir: string): string[];
|
|
7
|
+
/**
|
|
8
|
+
* Updates import/export statements in the given file by removing a trailing `.js` extension.
|
|
9
|
+
* Handles both static and dynamic import syntax.
|
|
10
|
+
* @param filePath Full path to the .ts file.
|
|
11
|
+
*/
|
|
12
|
+
export declare function updateImports(filePath: string): void;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
/**
|
|
4
|
+
* Recursively finds all .ts files in the provided directory.
|
|
5
|
+
* @param dir The directory to search.
|
|
6
|
+
* @returns An array of full paths to .ts files.
|
|
7
|
+
*/
|
|
8
|
+
export function getTsFiles(dir) {
|
|
9
|
+
let results = [];
|
|
10
|
+
const entries = fs.readdirSync(dir);
|
|
11
|
+
for (const entry of entries) {
|
|
12
|
+
const fullPath = path.join(dir, entry);
|
|
13
|
+
const stat = fs.statSync(fullPath);
|
|
14
|
+
if (stat.isDirectory()) {
|
|
15
|
+
results = results.concat(getTsFiles(fullPath));
|
|
16
|
+
}
|
|
17
|
+
else if (stat.isFile() && fullPath.endsWith(".ts") && !fullPath.endsWith(".d.ts")) {
|
|
18
|
+
results.push(fullPath);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
return results;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Updates import/export statements in the given file by removing a trailing `.js` extension.
|
|
25
|
+
* Handles both static and dynamic import syntax.
|
|
26
|
+
* @param filePath Full path to the .ts file.
|
|
27
|
+
*/
|
|
28
|
+
export function updateImports(filePath) {
|
|
29
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
30
|
+
let updatedContent = content;
|
|
31
|
+
// Regular expression for static imports/exports e.g.:
|
|
32
|
+
// import ... from 'module'
|
|
33
|
+
// export ... from "module"
|
|
34
|
+
const staticRegex = /((?:import|export)(?:[\s\S]*?)from\s+)(['"])([^'"]+\.js)(\2)/g;
|
|
35
|
+
updatedContent = updatedContent.replace(staticRegex, (_match, before, quote, modulePath, _quote) => {
|
|
36
|
+
// Remove the trailing ".js" from the module path.
|
|
37
|
+
const newModulePath = modulePath.replace(/\.js$/, "");
|
|
38
|
+
return `${before}${quote}${newModulePath}${quote}`;
|
|
39
|
+
});
|
|
40
|
+
// Regular expression for dynamic imports e.g.:
|
|
41
|
+
// import('module')
|
|
42
|
+
const dynamicRegex = /(\bimport\(\s*)(['"])([^'"]+\.js)(\2)/g;
|
|
43
|
+
updatedContent = updatedContent.replace(dynamicRegex, (_match, before, quote, modulePath, _quote) => {
|
|
44
|
+
const newModulePath = modulePath.replace(/\.js$/, "");
|
|
45
|
+
return `${before}${quote}${newModulePath}${quote}`;
|
|
46
|
+
});
|
|
47
|
+
if (updatedContent !== content) {
|
|
48
|
+
fs.writeFileSync(filePath, updatedContent, "utf-8");
|
|
49
|
+
// console.log(`Updated: ${filePath}`);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type TSyncFilesAndFoldersV2Params = {
|
|
2
|
+
sourceDirPath: string;
|
|
3
|
+
targetDirPath: string;
|
|
4
|
+
fileNamePatterns?: string[];
|
|
5
|
+
deleteExtraFilesInTarget?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNamePatterns, deleteExtraFilesInTarget, }: TSyncFilesAndFoldersV2Params): Promise<void>;
|
|
8
|
+
export {};
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import fsPromises from "node:fs/promises";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import crypto from "node:crypto"; // Added crypto for file hashing
|
|
5
|
+
// Utility function to calculate file hash
|
|
6
|
+
async function getFileHash(filePath) {
|
|
7
|
+
try {
|
|
8
|
+
const fileBuffer = await fsPromises.readFile(filePath);
|
|
9
|
+
const hashSum = crypto.createHash('sha1');
|
|
10
|
+
hashSum.update(fileBuffer);
|
|
11
|
+
return hashSum.digest('hex');
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
console.error(`Error calculating hash for file ${filePath}:`, error);
|
|
15
|
+
throw new Error(`Failed to calculate file hash: ${error.message}`);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
export async function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNamePatterns = [], deleteExtraFilesInTarget = true, }) {
|
|
19
|
+
// Create target directory if it doesn't exist
|
|
20
|
+
if (!fs.existsSync(targetDirPath)) {
|
|
21
|
+
try {
|
|
22
|
+
await fsPromises.mkdir(targetDirPath, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error(`Error creating target directory ${targetDirPath}:`, error);
|
|
26
|
+
throw new Error(`Failed to create target directory: ${error.message}`);
|
|
27
|
+
}
|
|
28
|
+
} // Load or initialize JSON file to store file details
|
|
29
|
+
const jsonFilePath = path.join(targetDirPath, "file_details.json");
|
|
30
|
+
let fileDetails = {};
|
|
31
|
+
let initialFileDetails = {};
|
|
32
|
+
if (fs.existsSync(jsonFilePath)) {
|
|
33
|
+
try {
|
|
34
|
+
const fileContent = await fsPromises.readFile(jsonFilePath, "utf8");
|
|
35
|
+
// Handle empty file case
|
|
36
|
+
if (fileContent.trim() === '') {
|
|
37
|
+
fileDetails = {};
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
fileDetails = JSON.parse(fileContent);
|
|
41
|
+
}
|
|
42
|
+
initialFileDetails = { ...fileDetails };
|
|
43
|
+
}
|
|
44
|
+
catch (error) {
|
|
45
|
+
console.error(`Error reading or parsing ${jsonFilePath}:`, error);
|
|
46
|
+
// Reset file details if there's an error
|
|
47
|
+
fileDetails = {};
|
|
48
|
+
initialFileDetails = {};
|
|
49
|
+
// Create a valid JSON file
|
|
50
|
+
await fsPromises.writeFile(jsonFilePath, "{}");
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
await fsPromises.writeFile(jsonFilePath, "{}");
|
|
55
|
+
}
|
|
56
|
+
async function updateFileDetails({ fileName, sourceFilePath, mtime, hash }) {
|
|
57
|
+
// const stats = await fsPromises.stat(sourceFilePath);
|
|
58
|
+
fileDetails[fileName] = {
|
|
59
|
+
sourceFilePath,
|
|
60
|
+
mtime,
|
|
61
|
+
localDate: new Date(mtime).toLocaleString(),
|
|
62
|
+
hash, // Store the hash in file details
|
|
63
|
+
};
|
|
64
|
+
if (JSON.stringify(fileDetails) !== JSON.stringify(initialFileDetails)) {
|
|
65
|
+
try {
|
|
66
|
+
await fsPromises.writeFile(jsonFilePath, JSON.stringify(fileDetails, null, 2));
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error(`Error writing to file ${jsonFilePath}:`, error);
|
|
70
|
+
// Continue execution since this is not critical
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
} // Traverse through source directory
|
|
74
|
+
let filesInSource;
|
|
75
|
+
try {
|
|
76
|
+
filesInSource = await fsPromises.readdir(sourceDirPath);
|
|
77
|
+
}
|
|
78
|
+
catch (error) {
|
|
79
|
+
console.error(`Error reading directory ${sourceDirPath}:`, error);
|
|
80
|
+
throw new Error(`Failed to read source directory: ${error.message}`);
|
|
81
|
+
}
|
|
82
|
+
for (const fileName of filesInSource) {
|
|
83
|
+
const sourcePath = path.join(sourceDirPath, fileName);
|
|
84
|
+
const targetPath = path.join(targetDirPath, fileName);
|
|
85
|
+
let stats;
|
|
86
|
+
try {
|
|
87
|
+
stats = await fsPromises.lstat(sourcePath);
|
|
88
|
+
}
|
|
89
|
+
catch (error) {
|
|
90
|
+
console.error(`Error getting stats for ${sourcePath}:`, error);
|
|
91
|
+
continue; // Skip this file/directory and move to next one
|
|
92
|
+
}
|
|
93
|
+
if (stats.isDirectory()) {
|
|
94
|
+
// Recursively sync directories
|
|
95
|
+
await syncFilesAndFolders({
|
|
96
|
+
sourceDirPath: sourcePath,
|
|
97
|
+
targetDirPath: targetPath,
|
|
98
|
+
fileNamePatterns,
|
|
99
|
+
deleteExtraFilesInTarget,
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// Check if file matches patterns
|
|
104
|
+
if (fileNamePatterns.length === 0 ||
|
|
105
|
+
fileNamePatterns.some((pattern) => fileName.includes(pattern))) { // Get source file hash and modified time
|
|
106
|
+
let sourceStats;
|
|
107
|
+
let sourceFileModifiedTime;
|
|
108
|
+
let sourceFileHash;
|
|
109
|
+
try {
|
|
110
|
+
sourceStats = await fsPromises.stat(sourcePath);
|
|
111
|
+
sourceFileModifiedTime = sourceStats.mtime.getTime();
|
|
112
|
+
sourceFileHash = await getFileHash(sourcePath);
|
|
113
|
+
}
|
|
114
|
+
catch (error) {
|
|
115
|
+
console.error(`Error getting file information for ${sourcePath}:`, error);
|
|
116
|
+
continue; // Skip this file and move to the next one
|
|
117
|
+
}
|
|
118
|
+
// Check if file exists in target and if it's modified or new
|
|
119
|
+
const targetExists = fs.existsSync(targetPath);
|
|
120
|
+
if (!targetExists ||
|
|
121
|
+
!fileDetails[fileName] ||
|
|
122
|
+
!fileDetails[fileName]?.hash || // If hash doesn't exist (backwards compatibility)
|
|
123
|
+
fileDetails[fileName]?.hash !== sourceFileHash // Primary check: compare file hashes
|
|
124
|
+
) { // Copy or replace the file in the target directory
|
|
125
|
+
try {
|
|
126
|
+
await fsPromises.copyFile(sourcePath, targetPath);
|
|
127
|
+
console.log(`Copied file: ${path.relative(sourceDirPath, sourcePath)}`);
|
|
128
|
+
}
|
|
129
|
+
catch (error) {
|
|
130
|
+
console.error(`Error copying file from ${sourcePath} to ${targetPath}:`, error);
|
|
131
|
+
// Continue with other files even if one fails
|
|
132
|
+
}
|
|
133
|
+
// Update file details with hash included
|
|
134
|
+
await updateFileDetails({
|
|
135
|
+
fileName,
|
|
136
|
+
sourceFilePath: sourcePath,
|
|
137
|
+
mtime: sourceFileModifiedTime,
|
|
138
|
+
hash: sourceFileHash,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
async function cleanUpFilesAndDirs(fileDetails, targetDir) {
|
|
145
|
+
// Iterate over fileDetails to check if source paths exist
|
|
146
|
+
for (const [fileName, detail] of Object.entries(fileDetails)) {
|
|
147
|
+
const sourceFilePath = detail.sourceFilePath;
|
|
148
|
+
const targetFilePath = path.join(targetDir, fileName);
|
|
149
|
+
// Check if the source file exists
|
|
150
|
+
const sourceExists = fs.existsSync(sourceFilePath);
|
|
151
|
+
if (!sourceExists) { // Delete the file from the target directory
|
|
152
|
+
if (fs.existsSync(targetFilePath)) {
|
|
153
|
+
try {
|
|
154
|
+
await fsPromises.unlink(targetFilePath);
|
|
155
|
+
// console.log(`Deleted target file: ${targetFilePath}`);
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
console.error(`Error deleting file ${targetFilePath}:`, error);
|
|
159
|
+
// Continue with other files even if deletion fails
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
// Delete the file entry from fileDetails
|
|
163
|
+
delete fileDetails[fileName];
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (JSON.stringify(fileDetails) !== JSON.stringify(initialFileDetails)) {
|
|
167
|
+
try {
|
|
168
|
+
await fsPromises.writeFile(jsonFilePath, JSON.stringify(fileDetails, null, 2));
|
|
169
|
+
}
|
|
170
|
+
catch (error) {
|
|
171
|
+
console.error(`Error writing to file ${jsonFilePath} in cleanup:`, error);
|
|
172
|
+
// Continue execution since this is not critical
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// Check for files in target directory that are not in source directory
|
|
177
|
+
if (deleteExtraFilesInTarget) {
|
|
178
|
+
await cleanUpFilesAndDirs(fileDetails, targetDirPath);
|
|
179
|
+
}
|
|
180
|
+
}
|
package/dist/bin/nbk.js
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { program } from 'commander';
|
|
3
|
+
import { deleteAllRepos } from '../cli/deleteAllRepos.js';
|
|
4
|
+
import { deployAllRepos } from '../cli/deployAllRepos.js';
|
|
5
|
+
import { gitAcpAllRepos } from '../cli/gitAcpAllRepos.js';
|
|
6
|
+
import { gitPushAllRepos } from '../cli/gitPushAllRepos.js';
|
|
7
|
+
import { transfer2Shared } from '../cli/transfer2Shared.js';
|
|
8
|
+
import { initConfig } from '../cli/initConfig.js';
|
|
9
|
+
import { fixConfigFile } from '../cli/fixConfigFile.js';
|
|
10
|
+
import { createInitWorkspaceShellFile } from '../cli/createInitWorkspaceShellFile.js';
|
|
11
|
+
import { addDevVersion } from '../cli/addDevVersion.js';
|
|
12
|
+
import { addProdVersion } from '../cli/addProdVersion.js';
|
|
13
|
+
import '../utils/progress.js';
|
|
14
|
+
import packageJson from '../../package.json' with { type: "json" };
|
|
15
|
+
program
|
|
16
|
+
.name('nbk')
|
|
17
|
+
.version(packageJson.version)
|
|
18
|
+
.description('PrimeXOP Backend Kit - CLI Tool');
|
|
19
|
+
program
|
|
20
|
+
.command('init')
|
|
21
|
+
.description('Initialize an empty nbk.config.json file in the project root')
|
|
22
|
+
.action(async () => {
|
|
23
|
+
await initConfig();
|
|
24
|
+
});
|
|
25
|
+
program
|
|
26
|
+
.command('delete-all-repos')
|
|
27
|
+
.description('Delete b2fPortal directory in all repositories')
|
|
28
|
+
.action(async () => {
|
|
29
|
+
await deleteAllRepos();
|
|
30
|
+
});
|
|
31
|
+
program
|
|
32
|
+
.command('deploy-all-repos')
|
|
33
|
+
.description('Deploy all repositories')
|
|
34
|
+
.action(async () => {
|
|
35
|
+
await deployAllRepos();
|
|
36
|
+
});
|
|
37
|
+
program
|
|
38
|
+
.command('git-acp-all-repos')
|
|
39
|
+
.description('Add, commit, and push changes in all repositories')
|
|
40
|
+
.action(async () => {
|
|
41
|
+
await gitAcpAllRepos();
|
|
42
|
+
});
|
|
43
|
+
program
|
|
44
|
+
.command('git-push-all-repos')
|
|
45
|
+
.description('Push b2fPortal changes in all repositories')
|
|
46
|
+
.action(async () => {
|
|
47
|
+
await gitPushAllRepos();
|
|
48
|
+
});
|
|
49
|
+
program
|
|
50
|
+
.command('fix-config-file')
|
|
51
|
+
.description('Fix JSON files by adding double quotes to keys and removing trailing commas')
|
|
52
|
+
.option('-p, --path <path>', 'Path to the JSON file to fix (defaults to nbk.config.json)')
|
|
53
|
+
.action(async (options) => {
|
|
54
|
+
await fixConfigFile(options.path);
|
|
55
|
+
});
|
|
56
|
+
program
|
|
57
|
+
.command('transfer-2-shared')
|
|
58
|
+
.description('Transfer project files to shared backend repositories')
|
|
59
|
+
.action(async () => {
|
|
60
|
+
await transfer2Shared();
|
|
61
|
+
});
|
|
62
|
+
program
|
|
63
|
+
.command('create-init-workspace-shell-file')
|
|
64
|
+
.description('Create a shell script to initialize and open project workspaces')
|
|
65
|
+
.action(async () => {
|
|
66
|
+
await createInitWorkspaceShellFile();
|
|
67
|
+
});
|
|
68
|
+
program
|
|
69
|
+
.command('add-dev-version')
|
|
70
|
+
.description('Update package.json to use local development version of @digicroz/node-backend-kit and run npm install')
|
|
71
|
+
.option('-d, --dir <directory>', 'Target directory containing package.json (defaults to current directory)')
|
|
72
|
+
.action(async (options) => {
|
|
73
|
+
await addDevVersion(options.dir);
|
|
74
|
+
});
|
|
75
|
+
program
|
|
76
|
+
.command('add-prod-version')
|
|
77
|
+
.description('Update package.json to use published version of @digicroz/node-backend-kit and run npm install')
|
|
78
|
+
.option('-d, --dir <directory>', 'Target directory containing package.json (defaults to current directory)')
|
|
79
|
+
.option('-v, --version <version>', 'Specific version to use (defaults to latest)')
|
|
80
|
+
.action(async (options) => {
|
|
81
|
+
await addProdVersion(options.dir, options.version);
|
|
82
|
+
});
|
|
83
|
+
program.parseAsync(process.argv);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function addDevVersion(targetDir?: string): Promise<void>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
export async function addDevVersion(targetDir) {
|
|
5
|
+
try {
|
|
6
|
+
// Use current directory if no target directory provided
|
|
7
|
+
const targetDirectory = targetDir || process.cwd();
|
|
8
|
+
const packageJsonPath = path.join(targetDirectory, "package.json");
|
|
9
|
+
// Check if package.json exists
|
|
10
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
11
|
+
console.error(`No package.json found in ${targetDirectory}`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
console.log(`Updating package.json in ${targetDirectory}`);
|
|
15
|
+
// Read the package.json file
|
|
16
|
+
const packageJsonContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
17
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
18
|
+
// Update or add the dependency
|
|
19
|
+
const nbkPath = "file:C:/primexopRepos/nbk";
|
|
20
|
+
const originalVersion = packageJson.dependencies?.["@digicroz/node-backend-kit"] ||
|
|
21
|
+
packageJson.devDependencies?.["@digicroz/node-backend-kit"];
|
|
22
|
+
// Determine if it's in dependencies or devDependencies
|
|
23
|
+
let dependencyType = "dependencies";
|
|
24
|
+
if (!packageJson.dependencies?.["@digicroz/node-backend-kit"] &&
|
|
25
|
+
packageJson.devDependencies?.["@digicroz/node-backend-kit"]) {
|
|
26
|
+
dependencyType = "devDependencies";
|
|
27
|
+
}
|
|
28
|
+
// Create the section if it doesn't exist
|
|
29
|
+
if (!packageJson[dependencyType]) {
|
|
30
|
+
packageJson[dependencyType] = {};
|
|
31
|
+
}
|
|
32
|
+
// Update the dependency
|
|
33
|
+
packageJson[dependencyType]["@digicroz/node-backend-kit"] = nbkPath;
|
|
34
|
+
// Save the updated package.json
|
|
35
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
36
|
+
console.log(`Updated @digicroz/node-backend-kit to use local version: ${nbkPath}`);
|
|
37
|
+
if (originalVersion) {
|
|
38
|
+
console.log(`Original version was: ${originalVersion}`);
|
|
39
|
+
}
|
|
40
|
+
// Run npm install
|
|
41
|
+
console.log("Running npm install...");
|
|
42
|
+
execSync("npm install", {
|
|
43
|
+
stdio: "inherit",
|
|
44
|
+
cwd: targetDirectory,
|
|
45
|
+
});
|
|
46
|
+
console.log("Successfully installed the local development version of @digicroz/node-backend-kit");
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
console.error("Error adding dev version:", error);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function addProdVersion(targetDir?: string, version?: string): Promise<void>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
export async function addProdVersion(targetDir, version) {
|
|
5
|
+
try {
|
|
6
|
+
// Use current directory if no target directory provided
|
|
7
|
+
const targetDirectory = targetDir || process.cwd();
|
|
8
|
+
const packageJsonPath = path.join(targetDirectory, "package.json");
|
|
9
|
+
// Check if package.json exists
|
|
10
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
11
|
+
console.error(`No package.json found in ${targetDirectory}`);
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
console.log(`Updating package.json in ${targetDirectory}`);
|
|
15
|
+
// Read the package.json file
|
|
16
|
+
const packageJsonContent = fs.readFileSync(packageJsonPath, "utf-8");
|
|
17
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
18
|
+
// Determine the target version to use
|
|
19
|
+
const prodVersion = version || "latest";
|
|
20
|
+
// Check if package is in dependencies or devDependencies
|
|
21
|
+
let dependencyType = null;
|
|
22
|
+
let originalVersion = null;
|
|
23
|
+
if (packageJson.dependencies?.["@digicroz/node-backend-kit"]) {
|
|
24
|
+
dependencyType = "dependencies";
|
|
25
|
+
originalVersion = packageJson.dependencies["@digicroz/node-backend-kit"];
|
|
26
|
+
}
|
|
27
|
+
else if (packageJson.devDependencies?.["@digicroz/node-backend-kit"]) {
|
|
28
|
+
dependencyType = "devDependencies";
|
|
29
|
+
originalVersion =
|
|
30
|
+
packageJson.devDependencies["@digicroz/node-backend-kit"];
|
|
31
|
+
}
|
|
32
|
+
if (!dependencyType) {
|
|
33
|
+
console.log("@digicroz/node-backend-kit not found in dependencies or devDependencies. Will add to dependencies.");
|
|
34
|
+
dependencyType = "dependencies";
|
|
35
|
+
if (!packageJson[dependencyType]) {
|
|
36
|
+
packageJson[dependencyType] = {};
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Get the latest version from npm if 'latest' is specified
|
|
40
|
+
let versionToUse = prodVersion;
|
|
41
|
+
if (prodVersion === "latest") {
|
|
42
|
+
try {
|
|
43
|
+
const npmViewResult = execSync("npm view @digicroz/node-backend-kit version", { encoding: "utf-8" }).trim();
|
|
44
|
+
versionToUse = `^${npmViewResult}`;
|
|
45
|
+
console.log(`Latest npm version found: ${npmViewResult}`);
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
console.warn('Failed to get latest version from npm. Using "latest" tag instead.');
|
|
49
|
+
versionToUse = "latest";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
// Update the dependency
|
|
53
|
+
packageJson[dependencyType]["@digicroz/node-backend-kit"] = versionToUse;
|
|
54
|
+
// Save the updated package.json
|
|
55
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
56
|
+
console.log(`Updated @digicroz/node-backend-kit to use production version: ${versionToUse}`);
|
|
57
|
+
if (originalVersion) {
|
|
58
|
+
console.log(`Original version was: ${originalVersion}`);
|
|
59
|
+
}
|
|
60
|
+
// Run npm install
|
|
61
|
+
console.log("Running npm install...");
|
|
62
|
+
execSync("npm install", {
|
|
63
|
+
stdio: "inherit",
|
|
64
|
+
cwd: targetDirectory,
|
|
65
|
+
});
|
|
66
|
+
console.log("Successfully installed the production version of @digicroz/node-backend-kit");
|
|
67
|
+
}
|
|
68
|
+
catch (error) {
|
|
69
|
+
console.error("Error adding production version:", error);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function createInitWorkspaceShellFile(): Promise<void>;
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
import { clientRootDirPath } from "../utils/path.js";
|
|
4
|
+
import { loadConfig } from "../utils/loadConfig.js";
|
|
5
|
+
export async function createInitWorkspaceShellFile() {
|
|
6
|
+
try {
|
|
7
|
+
// Load configuration
|
|
8
|
+
const configPath = path.join(clientRootDirPath, "nbk.config.json");
|
|
9
|
+
const config = loadConfig(configPath);
|
|
10
|
+
if (!config) {
|
|
11
|
+
console.error("Configuration file not found or invalid");
|
|
12
|
+
return;
|
|
13
|
+
}
|
|
14
|
+
// Create shell script content with escaped bash variables using $ prefix
|
|
15
|
+
let shellScriptContent = `#!/usr/bin/bash
|
|
16
|
+
|
|
17
|
+
current_path=\$(pwd)
|
|
18
|
+
echo "Current path is: \$current_path"
|
|
19
|
+
|
|
20
|
+
# Function to select editor
|
|
21
|
+
select_editor() {
|
|
22
|
+
# Default editor
|
|
23
|
+
EDITOR="code"
|
|
24
|
+
|
|
25
|
+
# Array of options
|
|
26
|
+
options=("VSCode" "Cursor" "Trae")
|
|
27
|
+
selected=0
|
|
28
|
+
|
|
29
|
+
# Function to print menu
|
|
30
|
+
print_menu() {
|
|
31
|
+
for i in "\${!options[@]}"; do
|
|
32
|
+
if [ \$i -eq \$selected ]; then
|
|
33
|
+
echo "> \${options[\$i]}"
|
|
34
|
+
else
|
|
35
|
+
echo " \${options[\$i]}"
|
|
36
|
+
fi
|
|
37
|
+
done
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
# Print initial menu
|
|
41
|
+
echo "Select editor (default: VSCode in 10 seconds):"
|
|
42
|
+
print_menu
|
|
43
|
+
|
|
44
|
+
# Start timer in background
|
|
45
|
+
(sleep 10; kill -USR1 \$$) & timer_pid=\$!
|
|
46
|
+
|
|
47
|
+
# Handle timer expiration
|
|
48
|
+
trap 'selected=0; break' USR1
|
|
49
|
+
|
|
50
|
+
# Read keys
|
|
51
|
+
while true; do
|
|
52
|
+
read -rsn1 key
|
|
53
|
+
case "\$key" in
|
|
54
|
+
A) # Up arrow
|
|
55
|
+
((selected--))
|
|
56
|
+
[ \$selected -lt 0 ] && selected=\$((\${#options[@]}-1))
|
|
57
|
+
clear
|
|
58
|
+
echo "Select editor (default: VSCode in 10 seconds):"
|
|
59
|
+
print_menu
|
|
60
|
+
;;
|
|
61
|
+
B) # Down arrow
|
|
62
|
+
((selected++))
|
|
63
|
+
[ \$selected -ge \${#options[@]} ] && selected=0
|
|
64
|
+
clear
|
|
65
|
+
echo "Select editor (default: VSCode in 10 seconds):"
|
|
66
|
+
print_menu
|
|
67
|
+
;;
|
|
68
|
+
"") # Enter key
|
|
69
|
+
kill \$timer_pid 2>/dev/null
|
|
70
|
+
break
|
|
71
|
+
;;
|
|
72
|
+
esac
|
|
73
|
+
done
|
|
74
|
+
|
|
75
|
+
# Kill timer if it's still running
|
|
76
|
+
kill \$timer_pid 2>/dev/null
|
|
77
|
+
|
|
78
|
+
# Set editor based on selection
|
|
79
|
+
if [ \$selected -eq 1 ]; then
|
|
80
|
+
EDITOR="cursor"
|
|
81
|
+
elif [ \$selected -eq 2 ]; then
|
|
82
|
+
EDITOR="trae"
|
|
83
|
+
fi
|
|
84
|
+
|
|
85
|
+
echo "Selected: \${options[\$selected]}"
|
|
86
|
+
return \$selected
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
# Call select editor function
|
|
90
|
+
select_editor
|
|
91
|
+
EDITOR_CHOICE=\$?
|
|
92
|
+
|
|
93
|
+
# Store the editor command
|
|
94
|
+
if [[ \$EDITOR_CHOICE -eq 1 ]]; then
|
|
95
|
+
EDITOR_CMD="cursor"
|
|
96
|
+
elif [[ \$EDITOR_CHOICE -eq 2 ]]; then
|
|
97
|
+
EDITOR_CMD="trae"
|
|
98
|
+
else
|
|
99
|
+
EDITOR_CMD="code"
|
|
100
|
+
fi
|
|
101
|
+
|
|
102
|
+
echo "Editor command: \$EDITOR_CMD"
|
|
103
|
+
|
|
104
|
+
`;
|
|
105
|
+
// Add project paths from configuration
|
|
106
|
+
for (const project of config.projects) {
|
|
107
|
+
shellScriptContent += `\n# Project: ${project.projectName}\n`;
|
|
108
|
+
shellScriptContent += `cd ${project.projectBaseDirPath}\n`;
|
|
109
|
+
shellScriptContent += `\$EDITOR_CMD .\n`;
|
|
110
|
+
// Add sections if they have repository paths
|
|
111
|
+
for (const section of project.sections) {
|
|
112
|
+
if (section.repository && section.repository.path) {
|
|
113
|
+
shellScriptContent += `\ncd ${section.repository.path}\n`;
|
|
114
|
+
shellScriptContent += `\$EDITOR_CMD .\n`;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Return to original directory after each project
|
|
118
|
+
shellScriptContent += `\ncd \$current_path\n`;
|
|
119
|
+
}
|
|
120
|
+
// Save shell script to file
|
|
121
|
+
const shellScriptPath = path.join(clientRootDirPath, "initWorkspace.sh");
|
|
122
|
+
fs.writeFileSync(shellScriptPath, shellScriptContent, { mode: 0o755 }); // Set execute permissions
|
|
123
|
+
console.log(`Shell script created at: ${shellScriptPath}`);
|
|
124
|
+
console.log("Remember to make it executable with: chmod +x initWorkspace.sh");
|
|
125
|
+
}
|
|
126
|
+
catch (error) {
|
|
127
|
+
console.error("Error creating workspace init shell file:", error);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function deleteAllRepos(): Promise<void>;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Import necessary modules
|
|
2
|
+
import { promises as fs } from "fs";
|
|
3
|
+
import { join } from "path";
|
|
4
|
+
import { clientRootDirPath } from "../utils/path.js";
|
|
5
|
+
import { isDeveloperAdarsh } from "../configs/environment.js";
|
|
6
|
+
import { loadConfig } from "../utils/loadConfig.js";
|
|
7
|
+
// Function to delete all files and directories within /b2fPortal
|
|
8
|
+
async function deleteB2fPortal(repoPath) {
|
|
9
|
+
// Construct the full path to /b2fPortal directory
|
|
10
|
+
const b2fPortalPath = join(repoPath, "b2fPortal");
|
|
11
|
+
try {
|
|
12
|
+
// Check if the directory exists
|
|
13
|
+
await fs.access(b2fPortalPath);
|
|
14
|
+
// Read all items in the b2fPortal directory
|
|
15
|
+
const items = await fs.readdir(b2fPortalPath);
|
|
16
|
+
// Iterate over each item and delete it
|
|
17
|
+
for (const item of items) {
|
|
18
|
+
const itemPath = join(b2fPortalPath, item);
|
|
19
|
+
const stat = await fs.lstat(itemPath);
|
|
20
|
+
if (stat.isDirectory()) {
|
|
21
|
+
// Recursively remove directories
|
|
22
|
+
await fs.rm(itemPath, { recursive: true, force: true });
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
// Remove files
|
|
26
|
+
await fs.unlink(itemPath);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
console.log("All files and directories deleted from /b2fPortal.");
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (error.code === "ENOENT") {
|
|
33
|
+
console.log("/b2fPortal directory does not exist.");
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
console.error("Error deleting /b2fPortal:", error);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export async function deleteAllRepos() {
|
|
41
|
+
// Load projects from the configuration file
|
|
42
|
+
const config = loadConfig();
|
|
43
|
+
// Export projects for use in CLI tools
|
|
44
|
+
let b2fPortalProjects = config.projects;
|
|
45
|
+
console.log("------------deleteAllRepos Started-------------");
|
|
46
|
+
if (!isDeveloperAdarsh) {
|
|
47
|
+
console.log("You are not allowed to run this command.");
|
|
48
|
+
return;
|
|
49
|
+
}
|
|
50
|
+
for (const project of b2fPortalProjects) {
|
|
51
|
+
for (const section of project.sections) {
|
|
52
|
+
if (isDeveloperAdarsh) {
|
|
53
|
+
const repositoryPath = join(clientRootDirPath, section.repository.path);
|
|
54
|
+
console.log({ repositoryPath });
|
|
55
|
+
console.log(`\n----------------${section.repository.name} started----------------`);
|
|
56
|
+
await deleteB2fPortal(repositoryPath);
|
|
57
|
+
console.log(`----------------${section.repository.name} finished----------------\n`);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// deleteAllRepos();
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Deletes all files in the target directory and copies all files from source directory
|
|
3
|
+
* @param sourcePath - Source directory path
|
|
4
|
+
* @param targetPath - Target directory path
|
|
5
|
+
*/
|
|
6
|
+
export declare function deleteAndCopy(sourcePath: string, targetPath: string): Promise<void>;
|