@digicroz/node-server-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 +211 -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 +70 -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 +46 -0
- package/dist/types.d.ts +35 -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 +210 -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/nsk.schema.json +95 -0
- package/package.json +80 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import fs from "fs";
|
|
2
|
+
import path from "path";
|
|
3
|
+
export function createZodFiles(directoryPath) {
|
|
4
|
+
fs.readdir(directoryPath, (err, files) => {
|
|
5
|
+
if (err) {
|
|
6
|
+
console.error("Error reading directory:", err);
|
|
7
|
+
return;
|
|
8
|
+
}
|
|
9
|
+
files.forEach((file) => {
|
|
10
|
+
const filePath = path.join(directoryPath, file);
|
|
11
|
+
fs.stat(filePath, (err, stats) => {
|
|
12
|
+
if (err) {
|
|
13
|
+
console.error("Error accessing file:", err);
|
|
14
|
+
return;
|
|
15
|
+
}
|
|
16
|
+
if (stats.isDirectory()) {
|
|
17
|
+
// Recursively call for subdirectories
|
|
18
|
+
createZodFiles(filePath);
|
|
19
|
+
}
|
|
20
|
+
else if (file.endsWith(".ts") && !file.endsWith("Zod.ts")) {
|
|
21
|
+
const newFileName = `${path.parse(file).name}Zod.ts`;
|
|
22
|
+
const newFilePath = path.join(directoryPath, newFileName);
|
|
23
|
+
if (!fs.existsSync(newFilePath)) {
|
|
24
|
+
const newData = `export const ${path.parse(file).name}ZodSchema = {\n\t\n};\n`;
|
|
25
|
+
fs.writeFile(newFilePath, newData, (err) => {
|
|
26
|
+
if (err) {
|
|
27
|
+
console.error("Error creating new file:", err);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
console.log(`Created ${newFileName}`);
|
|
31
|
+
}
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
// console.log(`${newFileName} already exists, skipping...`);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
}
|
|
@@ -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("nsk")
|
|
17
|
+
.version(packageJson.version)
|
|
18
|
+
.description("PrimeXOP Backend Kit - CLI Tool");
|
|
19
|
+
program
|
|
20
|
+
.command("init")
|
|
21
|
+
.description("Initialize an empty nsk.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 nsk.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-server-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-server-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 nskPath = "file:C:/primexopRepos/nsk";
|
|
20
|
+
const originalVersion = packageJson.dependencies?.["@digicroz/node-server-kit"] ||
|
|
21
|
+
packageJson.devDependencies?.["@digicroz/node-server-kit"];
|
|
22
|
+
// Determine if it's in dependencies or devDependencies
|
|
23
|
+
let dependencyType = "dependencies";
|
|
24
|
+
if (!packageJson.dependencies?.["@digicroz/node-server-kit"] &&
|
|
25
|
+
packageJson.devDependencies?.["@digicroz/node-server-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-server-kit"] = nskPath;
|
|
34
|
+
// Save the updated package.json
|
|
35
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
36
|
+
console.log(`Updated @digicroz/node-server-kit to use local version: ${nskPath}`);
|
|
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-server-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,70 @@
|
|
|
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-server-kit"]) {
|
|
24
|
+
dependencyType = "dependencies";
|
|
25
|
+
originalVersion = packageJson.dependencies["@digicroz/node-server-kit"];
|
|
26
|
+
}
|
|
27
|
+
else if (packageJson.devDependencies?.["@digicroz/node-server-kit"]) {
|
|
28
|
+
dependencyType = "devDependencies";
|
|
29
|
+
originalVersion = packageJson.devDependencies["@digicroz/node-server-kit"];
|
|
30
|
+
}
|
|
31
|
+
if (!dependencyType) {
|
|
32
|
+
console.log("@digicroz/node-server-kit not found in dependencies or devDependencies. Will add to dependencies.");
|
|
33
|
+
dependencyType = "dependencies";
|
|
34
|
+
if (!packageJson[dependencyType]) {
|
|
35
|
+
packageJson[dependencyType] = {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Get the latest version from npm if 'latest' is specified
|
|
39
|
+
let versionToUse = prodVersion;
|
|
40
|
+
if (prodVersion === "latest") {
|
|
41
|
+
try {
|
|
42
|
+
const npmViewResult = execSync("npm view @digicroz/node-server-kit version", { encoding: "utf-8" }).trim();
|
|
43
|
+
versionToUse = `^${npmViewResult}`;
|
|
44
|
+
console.log(`Latest npm version found: ${npmViewResult}`);
|
|
45
|
+
}
|
|
46
|
+
catch (err) {
|
|
47
|
+
console.warn('Failed to get latest version from npm. Using "latest" tag instead.');
|
|
48
|
+
versionToUse = "latest";
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
// Update the dependency
|
|
52
|
+
packageJson[dependencyType]["@digicroz/node-server-kit"] = versionToUse;
|
|
53
|
+
// Save the updated package.json
|
|
54
|
+
fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));
|
|
55
|
+
console.log(`Updated @digicroz/node-server-kit to use production version: ${versionToUse}`);
|
|
56
|
+
if (originalVersion) {
|
|
57
|
+
console.log(`Original version was: ${originalVersion}`);
|
|
58
|
+
}
|
|
59
|
+
// Run npm install
|
|
60
|
+
console.log("Running npm install...");
|
|
61
|
+
execSync("npm install", {
|
|
62
|
+
stdio: "inherit",
|
|
63
|
+
cwd: targetDirectory,
|
|
64
|
+
});
|
|
65
|
+
console.log("Successfully installed the production version of @digicroz/node-server-kit");
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
console.error("Error adding production version:", error);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -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, "nsk.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>;
|