soso-ppm 2.4.8

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.
@@ -0,0 +1,24 @@
1
+ name: Publish to npm
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - "v*"
7
+
8
+ jobs:
9
+ publish:
10
+ runs-on: ubuntu-latest
11
+
12
+ steps:
13
+ - uses: actions/checkout@v4
14
+
15
+ - uses: actions/setup-node@v4
16
+ with:
17
+ node-version: 18
18
+ registry-url: https://registry.npmjs.org/
19
+
20
+ - run: npm install
21
+
22
+ - run: npm publish
23
+ env:
24
+ NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 NitoGX
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Soso
2
+ A powerfull package manager!
3
+ ## What is "Soso"?
4
+ Soso is a powerfull package manager written in javascript using Node.js.
5
+ To install, publish, update packages, you'll need the pre-requesites below
6
+ ## Pre-requesites
7
+ - Node.js (https://nodejs.org)
8
+ - Git (https://git-scm.com/)
9
+ ## How to install?
10
+ First, clone the repo:
11
+ ```bash
12
+ git clone --branch master --single-branch https://github.com/Nitogx/soso-ppm.git
13
+ ```
14
+ Then, inside the repo folder, install the required packages:
15
+ ```bash
16
+ npm i
17
+ ```
18
+ And lastly, link it:
19
+ ```console
20
+ npm link
21
+ ```
22
+ ### How to use it?
23
+ In a new terminal run:
24
+ ```bash
25
+ soso -h
26
+ # Or
27
+ soso --help
28
+ ```
29
+ And you'll have a detailled guide about all commands!
30
+
31
+ ### Official Packages
32
+ [Hugging Face API for Soso PPM](https://github.com/Nitogx/huggingface-inference-wrapper/tree/master)
33
+ [Clark AI for Soso PPM](https://github.com/Nitogx/clarky/tree/master)
package/bin/soso.js ADDED
@@ -0,0 +1,78 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const { install } = require('../lib/commands/install');
5
+ const { publish } = require('../lib/commands/publish');
6
+ const { update } = require('../lib/commands/update');
7
+ const { info } = require('../lib/commands/info');
8
+ const { clean } = require('../lib/commands/clean');
9
+ const { printHelp, printVersion } = require('../lib/utils/help');
10
+ const { enableDebug } = require('../lib/utils/logger');
11
+
12
+ const args = process.argv.slice(2);
13
+ const command = args[0];
14
+
15
+ // Check for flags
16
+ const debug = args.includes('--debug') || args.includes('-d');
17
+ if (debug) {
18
+ enableDebug();
19
+ }
20
+
21
+ async function main() {
22
+ try {
23
+ switch (command) {
24
+ case 'install':
25
+ case 'i':
26
+ await install(args.slice(1));
27
+ break;
28
+
29
+ case 'publish':
30
+ await publish(args.slice(1));
31
+ break;
32
+
33
+ case 'update':
34
+ await update(args.slice(1));
35
+ break;
36
+
37
+ case 'info':
38
+ await info(args.slice(1));
39
+ break;
40
+
41
+ case 'cache':
42
+ if (args[1] === 'clean') {
43
+ await clean(args.slice(2));
44
+ } else {
45
+ console.error('Unknown cache command. Use: soso cache clean');
46
+ process.exit(1);
47
+ }
48
+ break;
49
+
50
+ case 'version':
51
+ case '-v':
52
+ case '--version':
53
+ printVersion();
54
+ break;
55
+
56
+ case 'help':
57
+ case '-h':
58
+ case '--help':
59
+ case undefined:
60
+ printHelp();
61
+ break;
62
+
63
+ default:
64
+ console.error(`Unknown command: ${command}`);
65
+ console.error('Run "soso help" for usage information.');
66
+ process.exit(1);
67
+ }
68
+ } catch (error) {
69
+ if (debug) {
70
+ console.error(error);
71
+ } else {
72
+ console.error(`Error: ${error.message}`);
73
+ }
74
+ process.exit(1);
75
+ }
76
+ }
77
+
78
+ main();
package/lib/cache.js ADDED
@@ -0,0 +1,196 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const crypto = require('crypto');
6
+ const { getCacheDir, ensureDir } = require('./config');
7
+ const { debug } = require('./utils/logger');
8
+
9
+ /**
10
+ * Cache manager for package storage
11
+ */
12
+ class CacheManager {
13
+ constructor() {
14
+ this.cacheDir = getCacheDir();
15
+ ensureDir(this.cacheDir);
16
+ }
17
+
18
+ /**
19
+ * Generate cache key for package
20
+ */
21
+ getCacheKey(name, version) {
22
+ const key = `${name}@${version}`;
23
+ return crypto.createHash('sha256').update(key).digest('hex');
24
+ }
25
+
26
+ /**
27
+ * Get cache path for package
28
+ */
29
+ getCachePath(name, version) {
30
+ const key = this.getCacheKey(name, version);
31
+ return path.join(this.cacheDir, key, 'package');
32
+ }
33
+
34
+ /**
35
+ * Check if package is cached
36
+ */
37
+ has(name, version) {
38
+ const cachePath = this.getCachePath(name, version);
39
+ const packageJsonPath = path.join(cachePath, 'package.json');
40
+ return fs.existsSync(packageJsonPath);
41
+ }
42
+
43
+ /**
44
+ * Get cached package path
45
+ */
46
+ get(name, version) {
47
+ if (!this.has(name, version)) {
48
+ return null;
49
+ }
50
+ return this.getCachePath(name, version);
51
+ }
52
+
53
+ /**
54
+ * Add package to cache
55
+ * @param {string} name - Package name
56
+ * @param {string} version - Package version
57
+ * @param {string} sourcePath - Path to package files
58
+ * @returns {string} Cache path
59
+ */
60
+ add(name, version, sourcePath) {
61
+ const cachePath = this.getCachePath(name, version);
62
+
63
+ debug(`Caching ${name}@${version} to ${cachePath}`);
64
+
65
+ ensureDir(cachePath);
66
+
67
+ // Copy all files from source to cache
68
+ this.copyRecursive(sourcePath, cachePath);
69
+
70
+ return cachePath;
71
+ }
72
+
73
+ /**
74
+ * Copy directory recursively
75
+ */
76
+ copyRecursive(src, dest) {
77
+ ensureDir(dest);
78
+
79
+ const entries = fs.readdirSync(src, { withFileTypes: true });
80
+
81
+ for (const entry of entries) {
82
+ const srcPath = path.join(src, entry.name);
83
+ const destPath = path.join(dest, entry.name);
84
+
85
+ if (entry.isDirectory()) {
86
+ this.copyRecursive(srcPath, destPath);
87
+ } else {
88
+ fs.copyFileSync(srcPath, destPath);
89
+ }
90
+ }
91
+ }
92
+
93
+ /**
94
+ * Calculate integrity hash for package
95
+ */
96
+ calculateIntegrity(packagePath) {
97
+ const hash = crypto.createHash('sha256');
98
+ this.hashDirectory(packagePath, hash);
99
+ return 'sha256-' + hash.digest('base64');
100
+ }
101
+
102
+ /**
103
+ * Hash directory contents recursively
104
+ */
105
+ hashDirectory(dir, hash) {
106
+ const entries = fs.readdirSync(dir, { withFileTypes: true })
107
+ .sort((a, b) => a.name.localeCompare(b.name));
108
+
109
+ for (const entry of entries) {
110
+ const fullPath = path.join(dir, entry.name);
111
+
112
+ // Skip node_modules
113
+ if (entry.name === 'node_modules') {
114
+ continue;
115
+ }
116
+
117
+ hash.update(entry.name);
118
+
119
+ if (entry.isDirectory()) {
120
+ this.hashDirectory(fullPath, hash);
121
+ } else {
122
+ const content = fs.readFileSync(fullPath);
123
+ hash.update(content);
124
+ }
125
+ }
126
+ }
127
+
128
+ /**
129
+ * Clear entire cache
130
+ */
131
+ clear() {
132
+ debug(`Clearing cache at ${this.cacheDir}`);
133
+
134
+ if (fs.existsSync(this.cacheDir)) {
135
+ this.removeRecursive(this.cacheDir);
136
+ ensureDir(this.cacheDir);
137
+ }
138
+ }
139
+
140
+ /**
141
+ * Remove directory recursively
142
+ */
143
+ removeRecursive(dir) {
144
+ if (!fs.existsSync(dir)) {
145
+ return;
146
+ }
147
+
148
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
149
+
150
+ for (const entry of entries) {
151
+ const fullPath = path.join(dir, entry.name);
152
+
153
+ if (entry.isDirectory()) {
154
+ this.removeRecursive(fullPath);
155
+ } else {
156
+ fs.unlinkSync(fullPath);
157
+ }
158
+ }
159
+
160
+ fs.rmdirSync(dir);
161
+ }
162
+
163
+ /**
164
+ * Get cache statistics
165
+ */
166
+ getStats() {
167
+ const entries = fs.readdirSync(this.cacheDir);
168
+ return {
169
+ packages: entries.length,
170
+ size: this.getDirectorySize(this.cacheDir)
171
+ };
172
+ }
173
+
174
+ /**
175
+ * Calculate directory size
176
+ */
177
+ getDirectorySize(dir) {
178
+ let size = 0;
179
+
180
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
181
+
182
+ for (const entry of entries) {
183
+ const fullPath = path.join(dir, entry.name);
184
+
185
+ if (entry.isDirectory()) {
186
+ size += this.getDirectorySize(fullPath);
187
+ } else {
188
+ size += fs.statSync(fullPath).size;
189
+ }
190
+ }
191
+
192
+ return size;
193
+ }
194
+ }
195
+
196
+ module.exports = { CacheManager };
@@ -0,0 +1,22 @@
1
+ 'use strict';
2
+
3
+ const { CacheManager } = require('../cache');
4
+ const { success, info } = require('../utils/logger');
5
+
6
+ /**
7
+ * Clean package cache
8
+ */
9
+ async function clean(args) {
10
+ const cache = new CacheManager();
11
+
12
+ info('Clearing package cache...');
13
+
14
+ const stats = cache.getStats();
15
+ const sizeMB = (stats.size / (1024 * 1024)).toFixed(2);
16
+
17
+ cache.clear();
18
+
19
+ success(`Cleared cache (${stats.packages} packages, ${sizeMB} MB)`);
20
+ }
21
+
22
+ module.exports = { clean };
@@ -0,0 +1,67 @@
1
+ 'use strict';
2
+
3
+ const chalk = require('chalk');
4
+ const { loadRegistry } = require('../config');
5
+ const { error } = require('../utils/logger');
6
+
7
+ /**
8
+ * Show package information
9
+ */
10
+ async function info(args) {
11
+ if (args.length === 0 || args[0].startsWith('-')) {
12
+ throw new Error('Package name required. Usage: soso info <package>');
13
+ }
14
+
15
+ const packageName = args[0];
16
+ const registry = loadRegistry();
17
+
18
+ const packageData = registry.packages[packageName];
19
+
20
+ if (!packageData) {
21
+ error(`Package not found: ${packageName}`);
22
+ console.log('\nAvailable packages:');
23
+ const packages = Object.keys(registry.packages).sort();
24
+ if (packages.length === 0) {
25
+ console.log(' (none)');
26
+ } else {
27
+ packages.forEach(name => console.log(` ${name}`));
28
+ }
29
+ process.exit(1);
30
+ }
31
+
32
+ // Display package information
33
+ console.log();
34
+ console.log(chalk.bold.cyan(packageData.name));
35
+ console.log();
36
+
37
+ const versions = Object.keys(packageData.versions).sort((a, b) => {
38
+ const semver = require('semver');
39
+ return semver.rcompare(a, b);
40
+ });
41
+
42
+ console.log(chalk.bold('Versions:'));
43
+ for (const version of versions) {
44
+ const versionData = packageData.versions[version];
45
+ const isLatest = version === versions[0];
46
+ const tag = isLatest ? chalk.green(' (latest)') : '';
47
+
48
+ console.log(` ${chalk.yellow(version)}${tag}`);
49
+ console.log(` ${chalk.gray('Git:')} ${versionData.gitUrl}#${versionData.tag}`);
50
+
51
+ if (versionData.publishedAt) {
52
+ const date = new Date(versionData.publishedAt).toLocaleString();
53
+ console.log(` ${chalk.gray('Published:')} ${date}`);
54
+ }
55
+
56
+ if (versionData.dependencies && Object.keys(versionData.dependencies).length > 0) {
57
+ console.log(` ${chalk.gray('Dependencies:')}`);
58
+ for (const [depName, depRange] of Object.entries(versionData.dependencies)) {
59
+ console.log(` ${depName}: ${depRange}`);
60
+ }
61
+ }
62
+
63
+ console.log();
64
+ }
65
+ }
66
+
67
+ module.exports = { info };
@@ -0,0 +1,220 @@
1
+ 'use strict';
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+ const { loadRegistry, ensureDir } = require('../config');
6
+ const { Resolver } = require('../resolver');
7
+ const { CacheManager } = require('../cache');
8
+ const { Lockfile } = require('../lockfile');
9
+ const { success, error, info, debug } = require('../utils/logger');
10
+ const git = require('../utils/git');
11
+ const os = require('os');
12
+
13
+ /**
14
+ * Install dependencies
15
+ */
16
+ async function install(args) {
17
+ const cwd = process.cwd();
18
+ const packageJsonPath = path.join(cwd, 'package.json');
19
+
20
+ // Load package.json
21
+ if (!fs.existsSync(packageJsonPath)) {
22
+ throw new Error('No package.json found in current directory');
23
+ }
24
+
25
+ const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
26
+
27
+ // Determine what to install
28
+ let specificPackage = null;
29
+ if (args.length > 0 && !args[0].startsWith('-')) {
30
+ specificPackage = args[0];
31
+ }
32
+
33
+ if (specificPackage) {
34
+ info(`Installing ${specificPackage}...`);
35
+ // Add to dependencies if not present
36
+ if (!packageJson.dependencies) {
37
+ packageJson.dependencies = {};
38
+ }
39
+ if (!packageJson.dependencies[specificPackage]) {
40
+ packageJson.dependencies[specificPackage] = '*';
41
+ fs.writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
42
+ }
43
+ } else {
44
+ info('Installing dependencies...');
45
+ }
46
+
47
+ const dependencies = packageJson.dependencies || {};
48
+
49
+ if (Object.keys(dependencies).length === 0) {
50
+ success('No dependencies to install');
51
+ return;
52
+ }
53
+
54
+ // Load registry and initialize components
55
+ const registry = loadRegistry();
56
+ const cache = new CacheManager();
57
+ const lockfile = new Lockfile(cwd);
58
+
59
+ // Resolve dependencies
60
+ info('Resolving dependency tree...');
61
+ const resolver = new Resolver(registry);
62
+ const resolved = await resolver.resolve(dependencies);
63
+
64
+ debug(`Resolved ${Object.keys(resolved).length} packages`);
65
+
66
+ // Prepare node_modules
67
+ const nodeModulesPath = path.join(cwd, 'node_modules');
68
+ ensureDir(nodeModulesPath);
69
+
70
+ // Install packages
71
+ const installed = {};
72
+
73
+ for (const [name, version] of Object.entries(resolved)) {
74
+ await installPackage(name, version, nodeModulesPath, cache, registry, installed);
75
+ }
76
+
77
+ // Write lockfile
78
+ lockfile.write(installed);
79
+
80
+ success(`Installed ${Object.keys(installed).length} packages`);
81
+ }
82
+
83
+ /**
84
+ * Install a single package
85
+ */
86
+ async function installPackage(name, version, nodeModulesPath, cache, registry, installed) {
87
+ info(`Installing ${name}@${version}...`);
88
+
89
+ // Check cache first
90
+ let sourcePath = cache.get(name, version);
91
+
92
+ if (sourcePath) {
93
+ debug(`Using cached ${name}@${version}`);
94
+ } else {
95
+ // Fetch from registry
96
+ sourcePath = await fetchPackage(name, version, registry, cache);
97
+ }
98
+
99
+ // Install to node_modules
100
+ const targetPath = getPackageInstallPath(name, nodeModulesPath);
101
+ ensureDir(path.dirname(targetPath));
102
+
103
+ // Copy from cache to node_modules
104
+ copyDirectory(sourcePath, targetPath);
105
+
106
+ // Calculate integrity
107
+ const integrity = cache.calculateIntegrity(sourcePath);
108
+
109
+ // Get package info from registry
110
+ const packageData = registry.packages[name];
111
+ const versionData = packageData.versions[version];
112
+
113
+ // Track installed package
114
+ installed[name] = {
115
+ version,
116
+ resolved: versionData.gitUrl,
117
+ integrity,
118
+ dependencies: versionData.dependencies || {}
119
+ };
120
+
121
+ debug(`Installed ${name}@${version} to ${targetPath}`);
122
+ }
123
+
124
+ /**
125
+ * Fetch package from registry
126
+ */
127
+ async function fetchPackage(name, version, registry, cache) {
128
+ const packageData = registry.packages[name];
129
+ if (!packageData) {
130
+ throw new Error(`Package not found in registry: ${name}`);
131
+ }
132
+
133
+ const versionData = packageData.versions[version];
134
+ if (!versionData) {
135
+ throw new Error(`Version ${version} not found for ${name}`);
136
+ }
137
+
138
+ const gitUrl = versionData.gitUrl;
139
+ const tag = `v${version}`;
140
+
141
+ debug(`Fetching ${name}@${version} from ${gitUrl}`);
142
+
143
+ // Create temporary directory for cloning
144
+ const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'soso-'));
145
+
146
+ try {
147
+ // Shallow clone at specific tag
148
+ await git.clone(gitUrl, tempDir, { shallow: true, branch: tag });
149
+
150
+ // Add to cache
151
+ const cachePath = cache.add(name, version, tempDir);
152
+
153
+ return cachePath;
154
+ } finally {
155
+ // Clean up temp directory
156
+ removeDirectory(tempDir);
157
+ }
158
+ }
159
+
160
+ /**
161
+ * Get installation path for package
162
+ */
163
+ function getPackageInstallPath(name, nodeModulesPath) {
164
+ if (name.startsWith('@')) {
165
+ // Scoped package: @scope/name -> node_modules/@scope/name
166
+ const parts = name.split('/');
167
+ return path.join(nodeModulesPath, parts[0], parts[1]);
168
+ }
169
+ return path.join(nodeModulesPath, name);
170
+ }
171
+
172
+ /**
173
+ * Copy directory recursively
174
+ */
175
+ function copyDirectory(src, dest) {
176
+ ensureDir(dest);
177
+
178
+ const entries = fs.readdirSync(src, { withFileTypes: true });
179
+
180
+ for (const entry of entries) {
181
+ const srcPath = path.join(src, entry.name);
182
+ const destPath = path.join(dest, entry.name);
183
+
184
+ // Skip .git directory
185
+ if (entry.name === '.git') {
186
+ continue;
187
+ }
188
+
189
+ if (entry.isDirectory()) {
190
+ copyDirectory(srcPath, destPath);
191
+ } else {
192
+ fs.copyFileSync(srcPath, destPath);
193
+ }
194
+ }
195
+ }
196
+
197
+ /**
198
+ * Remove directory recursively
199
+ */
200
+ function removeDirectory(dir) {
201
+ if (!fs.existsSync(dir)) {
202
+ return;
203
+ }
204
+
205
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
206
+
207
+ for (const entry of entries) {
208
+ const fullPath = path.join(dir, entry.name);
209
+
210
+ if (entry.isDirectory()) {
211
+ removeDirectory(fullPath);
212
+ } else {
213
+ fs.unlinkSync(fullPath);
214
+ }
215
+ }
216
+
217
+ fs.rmdirSync(dir);
218
+ }
219
+
220
+ module.exports = { install };