@digicroz/node-server-kit 1.0.0 → 1.0.3
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 +1 -1
- package/dist/b2fPortalV3/b2fPortal.js +3 -2
- package/dist/b2fPortalV3/syncProjectCommons.js +11 -8
- package/dist/bin/{nbk.js → nsk.js} +3 -2
- package/dist/cli/deleteAndCopy.js +4 -4
- package/dist/cli/transfer2Shared.d.ts +1 -1
- package/dist/cli/transfer2Shared.js +90 -61
- package/package.json +4 -4
- /package/dist/bin/{nbk.d.ts → nsk.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -162,7 +162,7 @@ npx @digicroz/node-server-kit git-acp-all-repos
|
|
|
162
162
|
npx @digicroz/node-server-kit git-push-all-repos
|
|
163
163
|
|
|
164
164
|
# Transfer project files to shared backend repositories
|
|
165
|
-
npx @digicroz/node-server-kit transfer-2-shared
|
|
165
|
+
npx @digicroz/node-server-kit transfer-2-shared [branch]
|
|
166
166
|
|
|
167
167
|
# Create a shell script to initialize workspaces
|
|
168
168
|
npx @digicroz/node-server-kit create-init-workspace-shell-file
|
|
@@ -138,7 +138,8 @@ export const b2fPortalInit = async (b2fPortalProjects) => {
|
|
|
138
138
|
return;
|
|
139
139
|
}
|
|
140
140
|
const repositoryDistTrpcApiPath = join(repositoryBackedPortalDirPath, sectionDistTrpcApiPath.replace(clientRootDirPath, ""));
|
|
141
|
-
const repositoryPrismaClientPath = join(repositoryBackedPortalDirPath,
|
|
141
|
+
const repositoryPrismaClientPath = join(repositoryBackedPortalDirPath, "_prisma", "generated-client");
|
|
142
|
+
// console.log({ repositoryBackedPortalDirPath, repositoryPrismaClientPath })
|
|
142
143
|
// createModuleFiles(sectionSrcTrpcApiRoutesPath)
|
|
143
144
|
// create zod files
|
|
144
145
|
// createZodFiles(sectionSrcTrpcApiRoutesPath)
|
|
@@ -194,7 +195,7 @@ export const b2fPortalInit = async (b2fPortalProjects) => {
|
|
|
194
195
|
// "index.d.ts",
|
|
195
196
|
// "library.js",
|
|
196
197
|
// "library.d.ts",
|
|
197
|
-
".
|
|
198
|
+
".ts",
|
|
198
199
|
],
|
|
199
200
|
});
|
|
200
201
|
if (section.needNextJsPatch) {
|
|
@@ -6,9 +6,9 @@ import crypto from "node:crypto"; // Added crypto for file hashing
|
|
|
6
6
|
async function getFileHash(filePath) {
|
|
7
7
|
try {
|
|
8
8
|
const fileBuffer = await fsPromises.readFile(filePath);
|
|
9
|
-
const hashSum = crypto.createHash(
|
|
9
|
+
const hashSum = crypto.createHash("sha1");
|
|
10
10
|
hashSum.update(fileBuffer);
|
|
11
|
-
return hashSum.digest(
|
|
11
|
+
return hashSum.digest("hex");
|
|
12
12
|
}
|
|
13
13
|
catch (error) {
|
|
14
14
|
console.error(`Error calculating hash for file ${filePath}:`, error);
|
|
@@ -33,7 +33,7 @@ export async function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNa
|
|
|
33
33
|
try {
|
|
34
34
|
const fileContent = await fsPromises.readFile(jsonFilePath, "utf8");
|
|
35
35
|
// Handle empty file case
|
|
36
|
-
if (fileContent.trim() ===
|
|
36
|
+
if (fileContent.trim() === "") {
|
|
37
37
|
fileDetails = {};
|
|
38
38
|
}
|
|
39
39
|
else {
|
|
@@ -53,7 +53,7 @@ export async function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNa
|
|
|
53
53
|
else {
|
|
54
54
|
await fsPromises.writeFile(jsonFilePath, "{}");
|
|
55
55
|
}
|
|
56
|
-
async function updateFileDetails({ fileName, sourceFilePath, mtime, hash }) {
|
|
56
|
+
async function updateFileDetails({ fileName, sourceFilePath, mtime, hash, }) {
|
|
57
57
|
// const stats = await fsPromises.stat(sourceFilePath);
|
|
58
58
|
fileDetails[fileName] = {
|
|
59
59
|
sourceFilePath,
|
|
@@ -102,7 +102,8 @@ export async function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNa
|
|
|
102
102
|
else {
|
|
103
103
|
// Check if file matches patterns
|
|
104
104
|
if (fileNamePatterns.length === 0 ||
|
|
105
|
-
fileNamePatterns.some((pattern) => fileName.includes(pattern))) {
|
|
105
|
+
fileNamePatterns.some((pattern) => fileName.includes(pattern))) {
|
|
106
|
+
// Get source file hash and modified time
|
|
106
107
|
let sourceStats;
|
|
107
108
|
let sourceFileModifiedTime;
|
|
108
109
|
let sourceFileHash;
|
|
@@ -121,10 +122,11 @@ export async function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNa
|
|
|
121
122
|
!fileDetails[fileName] ||
|
|
122
123
|
!fileDetails[fileName]?.hash || // If hash doesn't exist (backwards compatibility)
|
|
123
124
|
fileDetails[fileName]?.hash !== sourceFileHash // Primary check: compare file hashes
|
|
124
|
-
) {
|
|
125
|
+
) {
|
|
126
|
+
// Copy or replace the file in the target directory
|
|
125
127
|
try {
|
|
126
128
|
await fsPromises.copyFile(sourcePath, targetPath);
|
|
127
|
-
console.log(`
|
|
129
|
+
console.log(`Synced file: ${path.relative(sourceDirPath, sourcePath)}`);
|
|
128
130
|
}
|
|
129
131
|
catch (error) {
|
|
130
132
|
console.error(`Error copying file from ${sourcePath} to ${targetPath}:`, error);
|
|
@@ -148,7 +150,8 @@ export async function syncFilesAndFolders({ sourceDirPath, targetDirPath, fileNa
|
|
|
148
150
|
const targetFilePath = path.join(targetDir, fileName);
|
|
149
151
|
// Check if the source file exists
|
|
150
152
|
const sourceExists = fs.existsSync(sourceFilePath);
|
|
151
|
-
if (!sourceExists) {
|
|
153
|
+
if (!sourceExists) {
|
|
154
|
+
// Delete the file from the target directory
|
|
152
155
|
if (fs.existsSync(targetFilePath)) {
|
|
153
156
|
try {
|
|
154
157
|
await fsPromises.unlink(targetFilePath);
|
|
@@ -56,8 +56,9 @@ program
|
|
|
56
56
|
program
|
|
57
57
|
.command("transfer-2-shared")
|
|
58
58
|
.description("Transfer project files to shared backend repositories")
|
|
59
|
-
.
|
|
60
|
-
|
|
59
|
+
.argument("[branch]", "Shared backend branch name", "main")
|
|
60
|
+
.action(async (branch) => {
|
|
61
|
+
await transfer2Shared(branch);
|
|
61
62
|
});
|
|
62
63
|
program
|
|
63
64
|
.command("create-init-workspace-shell-file")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import * as fs from
|
|
2
|
-
import * as path from
|
|
3
|
-
import { startProgress, successProgress, failProgress, updateProgress } from
|
|
1
|
+
import * as fs from "fs";
|
|
2
|
+
import * as path from "path";
|
|
3
|
+
import { startProgress, successProgress, failProgress, updateProgress, } from "../utils/progress.js";
|
|
4
4
|
/**
|
|
5
5
|
* Deletes all files in the target directory and copies all files from source directory
|
|
6
6
|
* @param sourcePath - Source directory path
|
|
@@ -31,7 +31,7 @@ export async function deleteAndCopy(sourcePath, targetPath) {
|
|
|
31
31
|
// Copy all files from source to target
|
|
32
32
|
updateProgress(spinner, `Copying files from ${sourcePath} to ${targetPath}`);
|
|
33
33
|
await copyDirectoryRecursive(sourcePath, targetPath, spinner);
|
|
34
|
-
successProgress(spinner, `Successfully
|
|
34
|
+
successProgress(spinner, `Successfully synced all files from ${path.basename(sourcePath)} to ${path.basename(targetPath)}`);
|
|
35
35
|
}
|
|
36
36
|
catch (error) {
|
|
37
37
|
failProgress(spinner, `Error during deleteAndCopy operation`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const transfer2Shared: () => Promise<void>;
|
|
1
|
+
export declare const transfer2Shared: (branchName?: string) => Promise<void>;
|
|
@@ -6,7 +6,7 @@ import { simpleGit } from "simple-git";
|
|
|
6
6
|
import { deleteAndCopy } from "./deleteAndCopy.js";
|
|
7
7
|
import { loadConfig } from "../utils/loadConfig.js";
|
|
8
8
|
import { createMultiProgress, failProgress, startProgress, successProgress, } from "../utils/progress.js";
|
|
9
|
-
export const transfer2Shared = async () => {
|
|
9
|
+
export const transfer2Shared = async (branchName = "main") => {
|
|
10
10
|
// Load projects from the configuration file
|
|
11
11
|
const config = loadConfig();
|
|
12
12
|
// Export projects for use in CLI tools
|
|
@@ -32,6 +32,7 @@ export const transfer2Shared = async () => {
|
|
|
32
32
|
mainSpinner.text = "Pulling latest changes from main repository";
|
|
33
33
|
await myGit.pull();
|
|
34
34
|
successProgress(mainSpinner, "Main repository checked successfully");
|
|
35
|
+
console.log(`Using shared backend branch: ${branchName}`);
|
|
35
36
|
const repositoryPackageJsonPath = join(clientRootDirPath, "package.json");
|
|
36
37
|
if (!fs.existsSync(repositoryPackageJsonPath)) {
|
|
37
38
|
console.log("repositoryPackageJsonPath does not exist");
|
|
@@ -54,11 +55,11 @@ export const transfer2Shared = async () => {
|
|
|
54
55
|
for (const project of b2fPortalProjects) {
|
|
55
56
|
const projectSpinner = startProgress(`Processing project: ${project.projectName}`);
|
|
56
57
|
try {
|
|
57
|
-
const
|
|
58
|
-
// console.log('
|
|
59
|
-
if (!fs.existsSync(
|
|
60
|
-
failProgress(projectSpinner, "
|
|
61
|
-
console.log({
|
|
58
|
+
const serverS2cPath = join(clientSrcDirPath, "_server-s2c");
|
|
59
|
+
// console.log('serverS2cPath', serverS2cPath);
|
|
60
|
+
if (!fs.existsSync(serverS2cPath)) {
|
|
61
|
+
failProgress(projectSpinner, "serverS2cPath does not exist");
|
|
62
|
+
console.log({ serverS2cPath: serverS2cPath });
|
|
62
63
|
projectProgress.incrementFailed(`Failed: ${project.projectName}`);
|
|
63
64
|
continue;
|
|
64
65
|
}
|
|
@@ -88,63 +89,91 @@ export const transfer2Shared = async () => {
|
|
|
88
89
|
projectSpinner.text = `Checking shared backend repository status for project: ${project.projectName}`;
|
|
89
90
|
const sharedBackendGit = simpleGit(options);
|
|
90
91
|
let sharedBackendGitStatus = await sharedBackendGit.status();
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
92
|
+
const originalSharedBranch = sharedBackendGitStatus.current;
|
|
93
|
+
let branchSwitched = false;
|
|
94
|
+
try {
|
|
95
|
+
if (branchName !== originalSharedBranch) {
|
|
96
|
+
projectSpinner.text = `Checking out branch ${branchName} in shared backend repository for project: ${project.projectName}`;
|
|
97
|
+
await sharedBackendGit.fetch();
|
|
98
|
+
const branchSummary = await sharedBackendGit.branch(["-a"]);
|
|
99
|
+
const branchExistsLocally = Boolean(branchSummary.branches[branchName]);
|
|
100
|
+
const branchExistsRemotely = branchSummary.all.includes(`remotes/origin/${branchName}`);
|
|
101
|
+
if (branchExistsLocally) {
|
|
102
|
+
await sharedBackendGit.checkout(branchName);
|
|
103
|
+
branchSwitched = true;
|
|
104
|
+
}
|
|
105
|
+
else if (branchExistsRemotely) {
|
|
106
|
+
await sharedBackendGit.checkoutBranch(branchName, `origin/${branchName}`);
|
|
107
|
+
branchSwitched = true;
|
|
108
|
+
}
|
|
109
|
+
else if (branchName === "main") {
|
|
110
|
+
await sharedBackendGit.checkout("main");
|
|
111
|
+
branchSwitched = originalSharedBranch !== "main";
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
failProgress(projectSpinner, `Shared backend branch ${branchName} does not exist locally or on origin.`);
|
|
115
|
+
projectProgress.incrementFailed(`Failed: ${project.projectName}`);
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
projectSpinner.text = `Pulling latest changes from shared backend repository for project: ${project.projectName}`;
|
|
120
|
+
await sharedBackendGit.pull("origin", branchName);
|
|
121
|
+
const sharedProjectSrcPath = join(sharedBackendPath, "src", project.projectBaseDirPath);
|
|
122
|
+
// console.log("sharedProjectSrcPath", sharedProjectSrcPath);
|
|
123
|
+
if (!fs.existsSync(sharedProjectSrcPath)) {
|
|
124
|
+
failProgress(projectSpinner, "sharedProjectSrcPath does not exist");
|
|
125
|
+
console.log({ sharedProjectSrcPath });
|
|
126
|
+
projectProgress.incrementFailed(`Failed: ${project.projectName}`);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
projectSpinner.text = `Copying files for project: ${project.projectName}`;
|
|
130
|
+
await deleteAndCopy(projectSrcPath, sharedProjectSrcPath);
|
|
131
|
+
projectSpinner.text = `Checking for changes in shared backend repository for project: ${project.projectName}`;
|
|
132
|
+
sharedBackendGitStatus = await sharedBackendGit.status();
|
|
133
|
+
const sharedBackendChanges = sharedBackendGitStatus.files.some((file) => file.path.startsWith(`src/${project.projectBaseDirPath}/`));
|
|
134
|
+
if (!sharedBackendChanges) {
|
|
135
|
+
successProgress(projectSpinner, `No changes detected in the sharedBackend directory for project: ${project.projectName}`);
|
|
136
|
+
projectProgress.incrementCompleted(`Completed: ${project.projectName} - No changes`);
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const repositoryCommitJsonPath = join(sharedBackendPath, "commit.json");
|
|
140
|
+
if (!fs.existsSync(repositoryCommitJsonPath)) {
|
|
141
|
+
failProgress(projectSpinner, "repositoryCommitJsonPath does not exist");
|
|
142
|
+
console.log({ sharedBackendPath });
|
|
143
|
+
projectProgress.incrementFailed(`Failed: ${project.projectName}`);
|
|
144
|
+
return;
|
|
145
|
+
}
|
|
146
|
+
const repositoryCommitJson = JSON.parse(fs.readFileSync(repositoryCommitJsonPath, "utf8"));
|
|
147
|
+
if (!repositoryCommitJson.last_commit) {
|
|
148
|
+
console.log("repositoryCommitJson.last_commit does not exist");
|
|
149
|
+
console.log({ clientRootDirPath });
|
|
150
|
+
}
|
|
151
|
+
const currentDate = new Date().toLocaleString();
|
|
152
|
+
// Update last_commit
|
|
153
|
+
repositoryCommitJson.last_commit = currentDate;
|
|
154
|
+
// Write the updated JSON back to the file
|
|
155
|
+
fs.writeFileSync(repositoryCommitJsonPath, JSON.stringify(repositoryCommitJson, null, 4), "utf8");
|
|
156
|
+
projectSpinner.text = `Committing changes to shared backend repository for project: ${project.projectName}`;
|
|
157
|
+
await sharedBackendGit.add(`commit.json`);
|
|
158
|
+
// Add only the b2fPortal folder
|
|
159
|
+
await sharedBackendGit.add(`src/${project.projectBaseDirPath}/*`);
|
|
160
|
+
// Commit with the current date and time
|
|
161
|
+
const commitMessage = `${currentDate} transfer2Shared from ${repositoryPackageJson.name}`;
|
|
162
|
+
await sharedBackendGit.commit(commitMessage);
|
|
163
|
+
// Push the commit to the branch
|
|
164
|
+
projectSpinner.text = `Pushing changes to shared backend repository for project: ${project.projectName}`;
|
|
165
|
+
await sharedBackendGit.push("origin", branchName);
|
|
166
|
+
successProgress(projectSpinner, `Changes committed and pushed successfully for project: ${project.projectName}`);
|
|
167
|
+
projectProgress.incrementCompleted(`Completed: ${project.projectName}`);
|
|
125
168
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
169
|
+
finally {
|
|
170
|
+
if (branchSwitched &&
|
|
171
|
+
originalSharedBranch &&
|
|
172
|
+
originalSharedBranch !== branchName) {
|
|
173
|
+
projectSpinner.text = `Restoring shared backend repository branch to ${originalSharedBranch}`;
|
|
174
|
+
await sharedBackendGit.checkout(originalSharedBranch);
|
|
175
|
+
}
|
|
130
176
|
}
|
|
131
|
-
const currentDate = new Date().toLocaleString();
|
|
132
|
-
// Update last_commit
|
|
133
|
-
repositoryCommitJson.last_commit = currentDate;
|
|
134
|
-
// Write the updated JSON back to the file
|
|
135
|
-
fs.writeFileSync(repositoryCommitJsonPath, JSON.stringify(repositoryCommitJson, null, 4), "utf8");
|
|
136
|
-
projectSpinner.text = `Committing changes to shared backend repository for project: ${project.projectName}`;
|
|
137
|
-
await sharedBackendGit.add(`commit.json`);
|
|
138
|
-
// Add only the b2fPortal folder
|
|
139
|
-
await sharedBackendGit.add(`src/${project.projectBaseDirPath}/*`);
|
|
140
|
-
// Commit with the current date and time
|
|
141
|
-
const commitMessage = `${currentDate} transfer2Shared from ${repositoryPackageJson.name}`;
|
|
142
|
-
await sharedBackendGit.commit(commitMessage);
|
|
143
|
-
// Push the commit to the main branch
|
|
144
|
-
projectSpinner.text = `Pushing changes to shared backend repository for project: ${project.projectName}`;
|
|
145
|
-
await sharedBackendGit.push("origin", "main");
|
|
146
|
-
successProgress(projectSpinner, `Changes committed and pushed successfully for project: ${project.projectName}`);
|
|
147
|
-
projectProgress.incrementCompleted(`Completed: ${project.projectName}`);
|
|
148
177
|
}
|
|
149
178
|
else {
|
|
150
179
|
failProgress(projectSpinner, "sharedBackendPath is not defined");
|
package/package.json
CHANGED
|
@@ -1,12 +1,11 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digicroz/node-server-kit",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.3",
|
|
4
4
|
"description": "NodeJS Backend Kit - A powerful TypeScript utility for managing backend projects with features like B2F Portal integration, cross-project validation, and Next.js support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"prepare": "husky install",
|
|
10
9
|
"dev": "npm run clean && tsc -w",
|
|
11
10
|
"clean": "rimraf dist && tsc",
|
|
12
11
|
"release:patch": "npm version patch",
|
|
@@ -15,7 +14,8 @@
|
|
|
15
14
|
"test": "vitest run",
|
|
16
15
|
"test:watch": "vitest",
|
|
17
16
|
"lint": "tsc --noEmit",
|
|
18
|
-
"prepublishOnly": "npm run build"
|
|
17
|
+
"prepublishOnly": "npm run build",
|
|
18
|
+
"prepare": "husky"
|
|
19
19
|
},
|
|
20
20
|
"files": [
|
|
21
21
|
"dist",
|
|
@@ -77,4 +77,4 @@
|
|
|
77
77
|
"rimraf": "^6.0.1",
|
|
78
78
|
"simple-git": "^3.27.0"
|
|
79
79
|
}
|
|
80
|
-
}
|
|
80
|
+
}
|
|
File without changes
|