@dqcai/sqlite 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-all-source.md +1248 -0
- package/README-ps-gemini.md +1180 -0
- package/README.md +2653 -0
- package/lib/adapters/base-adapter.d.ts +8 -0
- package/lib/adapters/base-adapter.d.ts.map +1 -0
- package/lib/adapters/browser-adapter.d.ts +17 -0
- package/lib/adapters/browser-adapter.d.ts.map +1 -0
- package/lib/adapters/bun-adapter.d.ts +7 -0
- package/lib/adapters/bun-adapter.d.ts.map +1 -0
- package/lib/adapters/deno-adapter.d.ts +7 -0
- package/lib/adapters/deno-adapter.d.ts.map +1 -0
- package/lib/adapters/node-adapter.d.ts +7 -0
- package/lib/adapters/node-adapter.d.ts.map +1 -0
- package/lib/adapters/react-native-adapter.d.ts +20 -0
- package/lib/adapters/react-native-adapter.d.ts.map +1 -0
- package/lib/index.d.ts +18 -0
- package/lib/index.d.ts.map +1 -0
- package/lib/index.js +1 -0
- package/lib/index.js.map +1 -0
- package/lib/index.mjs +2 -0
- package/lib/index.mjs.map +1 -0
- package/lib/index.umd.js +1 -0
- package/lib/index.umd.js.map +1 -0
- package/lib/query-builder.d.ts +19 -0
- package/lib/query-builder.d.ts.map +1 -0
- package/lib/sqlite-manager.d.ts +11 -0
- package/lib/sqlite-manager.d.ts.map +1 -0
- package/lib/types.d.ts +45 -0
- package/lib/types.d.ts.map +1 -0
- package/package.json +63 -0
- package/scripts/obfuscate.mjs +155 -0
- package/scripts/version-manager.js +317 -0
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@dqcai/sqlite",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Universal SQLite adapter for Node.js, Browser, Deno, Bun, and React Native with a unified API and query builder.",
|
|
5
|
+
"main": "lib/index.js",
|
|
6
|
+
"types": "lib/index.d.ts",
|
|
7
|
+
"module": "lib/index.mjs",
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "rollup -c rollup.config.js",
|
|
10
|
+
"clean": "rimraf lib",
|
|
11
|
+
"prebuild": "npm run clean",
|
|
12
|
+
"obfuscate": "node ./scripts/obfuscate.mjs",
|
|
13
|
+
"prepublishOnly": "npm run build && npm run obfuscate",
|
|
14
|
+
"release": "npm publish --access public"
|
|
15
|
+
},
|
|
16
|
+
"keywords": [
|
|
17
|
+
"sqlite",
|
|
18
|
+
"dqcai",
|
|
19
|
+
"doanquoccuong",
|
|
20
|
+
"cuongdq",
|
|
21
|
+
"node",
|
|
22
|
+
"browser",
|
|
23
|
+
"deno",
|
|
24
|
+
"bun",
|
|
25
|
+
"react-native",
|
|
26
|
+
"expo",
|
|
27
|
+
"universal",
|
|
28
|
+
"database",
|
|
29
|
+
"query-builder"
|
|
30
|
+
],
|
|
31
|
+
"author": "Đoàn Quốc Cường",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"repository": {
|
|
34
|
+
"type": "git",
|
|
35
|
+
"url": "https://github.com/cuongdqpayment/dqcai-sqlite.git"
|
|
36
|
+
},
|
|
37
|
+
"bugs": {
|
|
38
|
+
"url": "https://github.com/cuongdqpayment/dqcai-sqlite/issues"
|
|
39
|
+
},
|
|
40
|
+
"homepage": "https://github.com/cuongdqpayment/dqcai-sqlite#readme",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@rollup/plugin-commonjs": "^28.0.6",
|
|
43
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
44
|
+
"@rollup/plugin-typescript": "^12.1.4",
|
|
45
|
+
"@types/node": "^18.0.0",
|
|
46
|
+
"esbuild": "^0.25.9",
|
|
47
|
+
"javascript-obfuscator": "^4.1.1",
|
|
48
|
+
"obfuscate": "^0.0.11",
|
|
49
|
+
"rimraf": "^6.0.1",
|
|
50
|
+
"rollup": "^4.49.0",
|
|
51
|
+
"rollup-plugin-esbuild": "^6.2.1",
|
|
52
|
+
"typescript": "^5.9.2"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"expo-sqlite": "^13.0.0",
|
|
56
|
+
"react-native-sqlite-storage": "^6.0.1",
|
|
57
|
+
"sqlite3": "^5.1.7",
|
|
58
|
+
"bun-types": "^1.0.0"
|
|
59
|
+
},
|
|
60
|
+
"publishConfig": {
|
|
61
|
+
"access": "public"
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
// scripts/obfuscate.mjs
|
|
2
|
+
import fs from 'fs';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import { fileURLToPath } from 'url';
|
|
5
|
+
import JavaScriptObfuscator from 'javascript-obfuscator';
|
|
6
|
+
import { glob } from 'glob';
|
|
7
|
+
|
|
8
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
9
|
+
const __dirname = path.dirname(__filename);
|
|
10
|
+
|
|
11
|
+
const obfuscationOptions = {
|
|
12
|
+
compact: true,
|
|
13
|
+
controlFlowFlattening: true,
|
|
14
|
+
controlFlowFlatteningThreshold: 0.5,
|
|
15
|
+
deadCodeInjection: true,
|
|
16
|
+
deadCodeInjectionThreshold: 0.2,
|
|
17
|
+
debugProtection: false,
|
|
18
|
+
disableConsoleOutput: false,
|
|
19
|
+
identifierNamesGenerator: 'hexadecimal',
|
|
20
|
+
numbersToExpressions: true,
|
|
21
|
+
renameGlobals: false,
|
|
22
|
+
selfDefending: true,
|
|
23
|
+
simplify: true,
|
|
24
|
+
sourceMap: false,
|
|
25
|
+
splitStrings: true,
|
|
26
|
+
splitStringsChunkLength: 5,
|
|
27
|
+
stringArray: true,
|
|
28
|
+
stringArrayCallsTransform: true,
|
|
29
|
+
stringArrayCallsTransformThreshold: 0.5,
|
|
30
|
+
stringArrayEncoding: ['base64'],
|
|
31
|
+
stringArrayThreshold: 0.75,
|
|
32
|
+
target: 'node'
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
async function obfuscateFiles() {
|
|
36
|
+
try {
|
|
37
|
+
console.log('🔒 Starting code obfuscation...');
|
|
38
|
+
|
|
39
|
+
const distDir = path.resolve(__dirname, '../lib');
|
|
40
|
+
console.log('📍 Debug: Resolved dist dir:', distDir);
|
|
41
|
+
|
|
42
|
+
if (!fs.existsSync(distDir)) {
|
|
43
|
+
console.error('❌ Dist directory not found. Please run build first.');
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Debug: List directory contents
|
|
48
|
+
const distContents = fs.readdirSync(distDir, { withFileTypes: true });
|
|
49
|
+
console.log('📍 Debug: Dist directory contents:');
|
|
50
|
+
distContents.forEach(item => {
|
|
51
|
+
console.log(` ${item.isDirectory() ? 'DIR' : 'FILE'}: ${item.name}`);
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Try different glob patterns
|
|
55
|
+
const patterns = [
|
|
56
|
+
'**/*.js',
|
|
57
|
+
'**/*.cjs',
|
|
58
|
+
'**/*.{js,cjs}',
|
|
59
|
+
'**/**.js',
|
|
60
|
+
'**/**.cjs'
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
let jsFiles = [];
|
|
64
|
+
|
|
65
|
+
for (const pattern of patterns) {
|
|
66
|
+
const fullPattern = path.join(distDir, pattern).replace(/\\/g, '/'); // Normalize for Windows
|
|
67
|
+
console.log(`📍 Debug: Trying pattern: ${fullPattern}`);
|
|
68
|
+
|
|
69
|
+
try {
|
|
70
|
+
const files = await glob(fullPattern, {
|
|
71
|
+
windowsPathsNoEscape: true,
|
|
72
|
+
posix: false
|
|
73
|
+
});
|
|
74
|
+
console.log(`📍 Debug: Pattern "${pattern}" found ${files.length} files`);
|
|
75
|
+
if (files.length > 0) {
|
|
76
|
+
jsFiles = files;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
} catch (err) {
|
|
80
|
+
console.log(`📍 Debug: Pattern "${pattern}" failed:`, err.message);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Fallback: Manual file search
|
|
85
|
+
if (jsFiles.length === 0) {
|
|
86
|
+
console.log('📍 Debug: Trying manual file search...');
|
|
87
|
+
|
|
88
|
+
function findJSFiles(dir) {
|
|
89
|
+
const files = [];
|
|
90
|
+
const items = fs.readdirSync(dir, { withFileTypes: true });
|
|
91
|
+
|
|
92
|
+
for (const item of items) {
|
|
93
|
+
const fullPath = path.join(dir, item.name);
|
|
94
|
+
if (item.isDirectory()) {
|
|
95
|
+
files.push(...findJSFiles(fullPath));
|
|
96
|
+
} else if (item.name.endsWith('.js') || item.name.endsWith('.cjs')) {
|
|
97
|
+
files.push(fullPath);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
return files;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
jsFiles = findJSFiles(distDir);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
console.log(`📁 Found ${jsFiles.length} JavaScript files to obfuscate`);
|
|
107
|
+
|
|
108
|
+
if (jsFiles.length === 0) {
|
|
109
|
+
console.log('⚠️ No JavaScript files found to obfuscate');
|
|
110
|
+
console.log('📍 Debug: Expected files like index.js, index.cjs, etc.');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// Show found files
|
|
115
|
+
jsFiles.forEach(file => {
|
|
116
|
+
console.log(` 📄 ${path.relative(distDir, file)}`);
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
for (const filePath of jsFiles) {
|
|
120
|
+
try {
|
|
121
|
+
console.log(`🔧 Processing: ${path.relative(distDir, filePath)}`);
|
|
122
|
+
|
|
123
|
+
const sourceCode = fs.readFileSync(filePath, 'utf8');
|
|
124
|
+
|
|
125
|
+
if (!sourceCode.trim()) {
|
|
126
|
+
console.log(`⏭️ Skipping empty file: ${path.relative(distDir, filePath)}`);
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
console.log(`📝 Obfuscating: ${path.basename(filePath)} (${sourceCode.length} chars)`);
|
|
131
|
+
|
|
132
|
+
const obfuscated = JavaScriptObfuscator.obfuscate(sourceCode, {
|
|
133
|
+
...obfuscationOptions,
|
|
134
|
+
inputFileName: path.basename(filePath)
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
const obfuscatedCode = obfuscated.getObfuscatedCode();
|
|
138
|
+
fs.writeFileSync(filePath, obfuscatedCode, 'utf8');
|
|
139
|
+
console.log(`✅ Obfuscated: ${path.relative(distDir, filePath)} (${obfuscatedCode.length} chars)`);
|
|
140
|
+
|
|
141
|
+
} catch (error) {
|
|
142
|
+
console.error(`❌ Failed to obfuscate ${filePath}:`, error.message);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
console.log('\n🎉 Obfuscation complete!');
|
|
147
|
+
|
|
148
|
+
} catch (error) {
|
|
149
|
+
console.error('❌ Obfuscation failed:', error.message);
|
|
150
|
+
console.error('❌ Stack trace:', error.stack);
|
|
151
|
+
process.exit(1);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
obfuscateFiles();
|
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
// #!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const readline = require('readline');
|
|
6
|
+
const { execSync } = require('child_process');
|
|
7
|
+
|
|
8
|
+
const rl = readline.createInterface({
|
|
9
|
+
input: process.stdin,
|
|
10
|
+
output: process.stdout
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const CHANGELOG_PATH = path.join(process.cwd(), 'CHANGELOG.md');
|
|
14
|
+
const PACKAGE_PATH = path.join(process.cwd(), 'package.json');
|
|
15
|
+
|
|
16
|
+
// Utility functions
|
|
17
|
+
function getCurrentDate() {
|
|
18
|
+
return new Date().toISOString().split('T')[0];
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function getCurrentVersion() {
|
|
22
|
+
const packageJson = JSON.parse(fs.readFileSync(PACKAGE_PATH, 'utf8'));
|
|
23
|
+
return packageJson.version;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function getNextVersion(current, type) {
|
|
27
|
+
const [major, minor, patch] = current.split('.').map(Number);
|
|
28
|
+
|
|
29
|
+
switch (type) {
|
|
30
|
+
case 'major':
|
|
31
|
+
return `${major + 1}.0.0`;
|
|
32
|
+
case 'minor':
|
|
33
|
+
return `${major}.${minor + 1}.0`;
|
|
34
|
+
case 'patch':
|
|
35
|
+
return `${major}.${minor}.${patch + 1}`;
|
|
36
|
+
default:
|
|
37
|
+
throw new Error('Invalid version type. Use: patch, minor, or major');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function prompt(question) {
|
|
42
|
+
return new Promise((resolve) => {
|
|
43
|
+
rl.question(question, resolve);
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Changelog functions
|
|
48
|
+
function readChangelog() {
|
|
49
|
+
if (!fs.existsSync(CHANGELOG_PATH)) {
|
|
50
|
+
console.error('❌ CHANGELOG.md not found!');
|
|
51
|
+
process.exit(1);
|
|
52
|
+
}
|
|
53
|
+
return fs.readFileSync(CHANGELOG_PATH, 'utf8');
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function extractUnreleasedChanges(changelog) {
|
|
57
|
+
const unreleasedSection = changelog.match(/## \[Unreleased\](.*?)(?=## \[|$)/s);
|
|
58
|
+
if (!unreleasedSection) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
const content = unreleasedSection[1].trim();
|
|
63
|
+
const changes = {
|
|
64
|
+
added: extractSection(content, 'Added'),
|
|
65
|
+
changed: extractSection(content, 'Changed'),
|
|
66
|
+
fixed: extractSection(content, 'Fixed'),
|
|
67
|
+
security: extractSection(content, 'Security'),
|
|
68
|
+
deprecated: extractSection(content, 'Deprecated'),
|
|
69
|
+
removed: extractSection(content, 'Removed')
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// Check if there are actual changes (not just placeholders)
|
|
73
|
+
const hasRealChanges = Object.values(changes).some(section =>
|
|
74
|
+
section && !section.includes('Placeholder')
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
return hasRealChanges ? changes : null;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function extractSection(content, sectionName) {
|
|
81
|
+
const regex = new RegExp(`### ${sectionName}(.*?)(?=### |$)`, 's');
|
|
82
|
+
const match = content.match(regex);
|
|
83
|
+
if (!match) return null;
|
|
84
|
+
|
|
85
|
+
return match[1].trim().split('\n')
|
|
86
|
+
.filter(line => line.trim() && line.startsWith('-'))
|
|
87
|
+
.map(line => line.trim())
|
|
88
|
+
.join('\n');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function updateChangelog(changelog, version, changes) {
|
|
92
|
+
const date = getCurrentDate();
|
|
93
|
+
const newVersionSection = createVersionSection(version, date, changes);
|
|
94
|
+
|
|
95
|
+
// Reset Unreleased section
|
|
96
|
+
const resetUnreleased = `## [Unreleased]
|
|
97
|
+
|
|
98
|
+
### Added
|
|
99
|
+
- Placeholder for new features
|
|
100
|
+
|
|
101
|
+
### Changed
|
|
102
|
+
- Placeholder for changes in existing functionality
|
|
103
|
+
|
|
104
|
+
### Fixed
|
|
105
|
+
- Placeholder for bug fixes
|
|
106
|
+
|
|
107
|
+
### Security
|
|
108
|
+
- Placeholder for security fixes
|
|
109
|
+
|
|
110
|
+
---
|
|
111
|
+
|
|
112
|
+
${newVersionSection}`;
|
|
113
|
+
|
|
114
|
+
// Replace the Unreleased section and add new version
|
|
115
|
+
const updatedChangelog = changelog.replace(
|
|
116
|
+
/## \[Unreleased\].*?(?=---)/s,
|
|
117
|
+
resetUnreleased
|
|
118
|
+
);
|
|
119
|
+
|
|
120
|
+
return updatedChangelog;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
function createVersionSection(version, date, changes) {
|
|
124
|
+
let section = `## [${version}] - ${date}\n\n`;
|
|
125
|
+
|
|
126
|
+
const sections = [
|
|
127
|
+
['Added', changes.added],
|
|
128
|
+
['Changed', changes.changed],
|
|
129
|
+
['Fixed', changes.fixed],
|
|
130
|
+
['Deprecated', changes.deprecated],
|
|
131
|
+
['Removed', changes.removed],
|
|
132
|
+
['Security', changes.security]
|
|
133
|
+
];
|
|
134
|
+
|
|
135
|
+
sections.forEach(([sectionName, content]) => {
|
|
136
|
+
if (content) {
|
|
137
|
+
section += `### ${sectionName}\n${content}\n\n`;
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
return section.trim() + '\n\n---\n';
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Interactive version release
|
|
145
|
+
async function interactiveRelease() {
|
|
146
|
+
console.log('🚀 @dqcai/logger Version Release Manager\n');
|
|
147
|
+
|
|
148
|
+
const currentVersion = getCurrentVersion();
|
|
149
|
+
console.log(`📦 Current version: ${currentVersion}`);
|
|
150
|
+
|
|
151
|
+
// Check for unreleased changes
|
|
152
|
+
const changelog = readChangelog();
|
|
153
|
+
const unreleasedChanges = extractUnreleasedChanges(changelog);
|
|
154
|
+
|
|
155
|
+
if (!unreleasedChanges) {
|
|
156
|
+
console.log('❌ No unreleased changes found in CHANGELOG.md');
|
|
157
|
+
console.log('Please add your changes to the [Unreleased] section first.');
|
|
158
|
+
process.exit(1);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
console.log('\n📋 Found unreleased changes:');
|
|
162
|
+
Object.entries(unreleasedChanges).forEach(([type, changes]) => {
|
|
163
|
+
if (changes) {
|
|
164
|
+
console.log(`\n🔸 ${type.toUpperCase()}:`);
|
|
165
|
+
changes.split('\n').forEach(change => {
|
|
166
|
+
console.log(` ${change}`);
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Ask for version type
|
|
172
|
+
console.log('\n🎯 What type of release is this?');
|
|
173
|
+
console.log('1. patch - Bug fixes (1.0.3 → 1.0.4)');
|
|
174
|
+
console.log('2. minor - New features (1.0.3 → 1.1.0)');
|
|
175
|
+
console.log('3. major - Breaking changes (1.0.3 → 2.0.0)');
|
|
176
|
+
|
|
177
|
+
const versionChoice = await prompt('Enter choice (1-3): ');
|
|
178
|
+
const versionTypes = { '1': 'patch', '2': 'minor', '3': 'major' };
|
|
179
|
+
const versionType = versionTypes[versionChoice];
|
|
180
|
+
|
|
181
|
+
if (!versionType) {
|
|
182
|
+
console.log('❌ Invalid choice');
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
const nextVersion = getNextVersion(currentVersion, versionType);
|
|
187
|
+
console.log(`\n🏷️ Next version will be: ${nextVersion}`);
|
|
188
|
+
|
|
189
|
+
// Ask for release notes
|
|
190
|
+
const releaseNotes = await prompt('\n📝 Add release notes (optional): ');
|
|
191
|
+
|
|
192
|
+
// Confirm release
|
|
193
|
+
const confirm = await prompt('\n❓ Continue with release? (y/N): ');
|
|
194
|
+
if (confirm.toLowerCase() !== 'y') {
|
|
195
|
+
console.log('❌ Release cancelled');
|
|
196
|
+
process.exit(0);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
try {
|
|
200
|
+
// Update changelog
|
|
201
|
+
console.log('\n📝 Updating CHANGELOG.md...');
|
|
202
|
+
const updatedChangelog = updateChangelog(changelog, nextVersion, unreleasedChanges);
|
|
203
|
+
fs.writeFileSync(CHANGELOG_PATH, updatedChangelog);
|
|
204
|
+
|
|
205
|
+
// Add release notes if provided
|
|
206
|
+
if (releaseNotes) {
|
|
207
|
+
console.log('📝 Adding release notes...');
|
|
208
|
+
// Add release notes to the version section
|
|
209
|
+
const changelogWithNotes = updatedChangelog.replace(
|
|
210
|
+
`## [${nextVersion}] - ${getCurrentDate()}`,
|
|
211
|
+
`## [${nextVersion}] - ${getCurrentDate()}\n\n> ${releaseNotes}`
|
|
212
|
+
);
|
|
213
|
+
fs.writeFileSync(CHANGELOG_PATH, changelogWithNotes);
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// Run tests
|
|
217
|
+
console.log('🧪 Running tests...');
|
|
218
|
+
execSync('npm test', { stdio: 'inherit' });
|
|
219
|
+
|
|
220
|
+
// Build
|
|
221
|
+
console.log('🏗️ Building package...');
|
|
222
|
+
execSync('npm run build', { stdio: 'inherit' });
|
|
223
|
+
|
|
224
|
+
// Version and commit
|
|
225
|
+
console.log('🏷️ Creating version commit...');
|
|
226
|
+
execSync(`npm version ${versionType} --message "chore: release v%s\n\nSee CHANGELOG.md for details"`, { stdio: 'inherit' });
|
|
227
|
+
|
|
228
|
+
// Ask about publishing
|
|
229
|
+
const shouldPublish = await prompt('\n📤 Publish to NPM? (y/N): ');
|
|
230
|
+
if (shouldPublish.toLowerCase() === 'y') {
|
|
231
|
+
console.log('📤 Publishing to NPM...');
|
|
232
|
+
execSync('npm publish --access public', { stdio: 'inherit' });
|
|
233
|
+
|
|
234
|
+
console.log('\n✅ Release completed successfully!');
|
|
235
|
+
console.log(`🎉 @dqcai/logger v${nextVersion} is now available on NPM`);
|
|
236
|
+
console.log(`📦 https://www.npmjs.com/package/@dqcai/logger/v/${nextVersion}`);
|
|
237
|
+
} else {
|
|
238
|
+
console.log('\n✅ Version created successfully!');
|
|
239
|
+
console.log('📝 Run `npm publish --access public` when ready to publish');
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
} catch (error) {
|
|
243
|
+
console.error('❌ Release failed:', error.message);
|
|
244
|
+
process.exit(1);
|
|
245
|
+
} finally {
|
|
246
|
+
rl.close();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// Generate release notes from git commits
|
|
251
|
+
function generateReleaseNotes() {
|
|
252
|
+
try {
|
|
253
|
+
const lastTag = execSync('git describe --tags --abbrev=0 HEAD~1', { encoding: 'utf8' }).trim();
|
|
254
|
+
const commits = execSync(`git log ${lastTag}..HEAD --pretty=format:"- %s (%h)"`, { encoding: 'utf8' });
|
|
255
|
+
|
|
256
|
+
console.log('\n📋 Generated release notes from git commits:\n');
|
|
257
|
+
console.log(commits);
|
|
258
|
+
|
|
259
|
+
} catch (error) {
|
|
260
|
+
console.log('ℹ️ Could not generate release notes from git commits');
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
// Main function
|
|
265
|
+
async function main() {
|
|
266
|
+
const command = process.argv[2];
|
|
267
|
+
|
|
268
|
+
switch (command) {
|
|
269
|
+
case 'release':
|
|
270
|
+
case 'interactive':
|
|
271
|
+
await interactiveRelease();
|
|
272
|
+
break;
|
|
273
|
+
|
|
274
|
+
case 'notes':
|
|
275
|
+
case 'generate-notes':
|
|
276
|
+
generateReleaseNotes();
|
|
277
|
+
break;
|
|
278
|
+
|
|
279
|
+
case 'check':
|
|
280
|
+
const changelog = readChangelog();
|
|
281
|
+
const changes = extractUnreleasedChanges(changelog);
|
|
282
|
+
if (changes) {
|
|
283
|
+
console.log('✅ Found unreleased changes in CHANGELOG.md');
|
|
284
|
+
Object.entries(changes).forEach(([type, content]) => {
|
|
285
|
+
if (content) {
|
|
286
|
+
console.log(`\n${type.toUpperCase()}:`);
|
|
287
|
+
console.log(content);
|
|
288
|
+
}
|
|
289
|
+
});
|
|
290
|
+
} else {
|
|
291
|
+
console.log('❌ No unreleased changes found');
|
|
292
|
+
}
|
|
293
|
+
break;
|
|
294
|
+
|
|
295
|
+
default:
|
|
296
|
+
console.log('📚 @dqcai/logger Version Manager');
|
|
297
|
+
console.log('\nUsage:');
|
|
298
|
+
console.log(' npm run version:release # Interactive release');
|
|
299
|
+
console.log(' npm run version:check # Check unreleased changes');
|
|
300
|
+
console.log(' npm run version:notes # Generate release notes from git');
|
|
301
|
+
console.log('\nOr directly:');
|
|
302
|
+
console.log(' node scripts/version-manager.js release');
|
|
303
|
+
console.log(' node scripts/version-manager.js check');
|
|
304
|
+
console.log(' node scripts/version-manager.js notes');
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
if (require.main === module) {
|
|
309
|
+
main().catch(console.error);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
module.exports = {
|
|
313
|
+
getCurrentVersion,
|
|
314
|
+
getNextVersion,
|
|
315
|
+
extractUnreleasedChanges,
|
|
316
|
+
updateChangelog
|
|
317
|
+
};
|