fileuni 0.0.1 → 0.0.2-alpha2

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/LICENSE CHANGED
@@ -1,21 +1,43 @@
1
- MIT License
2
-
3
- Copyright (c) 2026 FileUni Team
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.
1
+ FileUni Source License v1.0
2
+
3
+ Copyright (c) FileUni Authors
4
+ All rights reserved.
5
+
6
+ 1. Grant of Access
7
+
8
+ Permission is granted to access, read, and review the source code in this repository for:
9
+ - personal learning,
10
+ - technical review,
11
+ - security research and audit.
12
+
13
+ 2. Restrictions
14
+
15
+ Without prior written permission from FileUni Authors, you may NOT:
16
+ - use this source code for any commercial purpose,
17
+ - use this source code to build, distribute, or operate products or services that compete with FileUni,
18
+ - sublicense, sell, lease, or otherwise commercially exploit this source code,
19
+ - remove or alter copyright, attribution, or license notices.
20
+
21
+ 3. No Trademark Rights
22
+
23
+ This license does not grant any right to use the names, logos, trademarks, or branding of FileUni.
24
+
25
+ 4. Contributions
26
+
27
+ By submitting contributions (including pull requests, patches, or suggestions), you grant FileUni Authors a perpetual, worldwide, non-exclusive, royalty-free license to use, modify, and distribute your contributions as part of FileUni.
28
+
29
+ 5. Disclaimer of Warranty
30
+
31
+ THE SOURCE CODE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
32
+
33
+ 6. Limitation of Liability
34
+
35
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES, OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT, OR OTHERWISE, ARISING FROM OR IN CONNECTION WITH THE SOURCE CODE OR THE USE OR OTHER DEALINGS IN THE SOURCE CODE.
36
+
37
+ 7. Termination
38
+
39
+ Any violation of this license automatically terminates the rights granted under this license.
40
+
41
+ 8. Contact
42
+
43
+ For commercial licensing, special permissions, or partnership requests, please open an issue in this repository.
package/README.md CHANGED
@@ -1,13 +1,42 @@
1
1
  # fileuni
2
2
 
3
- FileUni - A modern file management solution.
3
+ FileUni CLI distributed through npm as a single package.
4
+ The package downloads the matching prebuilt binary from GitHub Releases during `postinstall`.
4
5
 
5
- ## Installation
6
+ ## Install
6
7
 
7
8
  ```bash
8
9
  npm install fileuni
9
10
  ```
10
11
 
12
+ ## Run
13
+
14
+ ```bash
15
+ npx fileuni --help
16
+ ```
17
+
18
+ ## Platform Override
19
+
20
+ The installer auto-detects the current platform.
21
+ You can override the target manually when you need a specific Linux runtime variant.
22
+
23
+ Examples:
24
+
25
+ ```bash
26
+ FILEUNI_NPM_LIBC=musl npm install fileuni
27
+ FILEUNI_NPM_TARGET=x86_64-unknown-linux-musl npm install fileuni
28
+ ```
29
+
30
+ ## Optional Controls
31
+
32
+ ```bash
33
+ FILEUNI_NPM_SKIP_DOWNLOAD=1 npm install fileuni
34
+ FILEUNI_NPM_BASE_URL=https://github.com/FileUni/FileUni-Project npm install fileuni
35
+ ```
36
+
11
37
  ## License
12
38
 
13
- MIT
39
+ This project is licensed under the FileUni Community Source License v1.0.
40
+
41
+ For the full license text, please see:
42
+ https://github.com/FileUni/FileUni-Project/blob/main/LICENSE
package/bin/fileuni.js ADDED
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { spawn } = require('node:child_process');
4
+ const { ensureInstalled } = require('../scripts/fileuni-common.cjs');
5
+
6
+ (async () => {
7
+ const binaryPath = await ensureInstalled();
8
+ const child = spawn(binaryPath, process.argv.slice(2), { stdio: 'inherit' });
9
+
10
+ child.on('exit', (code, signal) => {
11
+ if (signal) {
12
+ process.kill(process.pid, signal);
13
+ return;
14
+ }
15
+ process.exit(code ?? 0);
16
+ });
17
+ })();
package/package.json CHANGED
@@ -1,39 +1,32 @@
1
1
  {
2
2
  "name": "fileuni",
3
- "version": "0.0.1",
4
- "description": "FileUni - A modern file management solution",
5
- "keywords": [
6
- "file",
7
- "management",
8
- "storage"
9
- ],
10
- "license": "MIT",
11
- "author": "FileUni Team",
12
- "repository": {
13
- "type": "git",
14
- "url": "https://github.com/fileuni/fileuni-workspace.git",
15
- "directory": "packages_for_fileuni/npm"
16
- },
17
- "bugs": {
18
- "url": "https://github.com/fileuni/fileuni-workspace/issues"
19
- },
3
+ "version": "0.0.2-alpha2",
4
+ "description": "FileUni CLI distributed through npm with on-demand platform binary downloads.",
5
+ "license": "UNLICENSED",
6
+ "repository": "https://github.com/FileUni/FileUni-Project",
20
7
  "homepage": "https://fileuni.com",
21
- "type": "module",
22
- "main": "./dist/index.js",
23
- "types": "./dist/index.d.ts",
24
- "exports": {
25
- ".": {
26
- "import": "./dist/index.js",
27
- "types": "./dist/index.d.ts"
28
- }
8
+ "bugs": {
9
+ "url": "https://github.com/fileuni/FileUni-WorkSpace/issues"
29
10
  },
30
11
  "files": [
31
- "dist",
12
+ "bin",
13
+ "scripts",
32
14
  "README.md",
33
15
  "LICENSE"
34
16
  ],
17
+ "bin": {
18
+ "fileuni": "bin/fileuni.js"
19
+ },
20
+ "scripts": {
21
+ "postinstall": "node ./scripts/postinstall.cjs"
22
+ },
23
+ "dependencies": {
24
+ "adm-zip": "^0.5.16"
25
+ },
35
26
  "engines": {
36
27
  "node": ">=18.0.0"
37
28
  },
38
- "scripts": {}
29
+ "publishConfig": {
30
+ "access": "public"
31
+ }
39
32
  }
@@ -0,0 +1,179 @@
1
+ const fs = require('node:fs');
2
+ const fsp = require('node:fs/promises');
3
+ const os = require('node:os');
4
+ const path = require('node:path');
5
+ const AdmZip = require('adm-zip');
6
+
7
+ const manifest = require('./fileuni-manifest.json');
8
+ const packageRoot = path.resolve(__dirname, '..');
9
+ const binDir = path.join(packageRoot, 'bin');
10
+ const binaryBasePath = path.join(binDir, 'fileuni-bin');
11
+ const metadataPath = path.join(binDir, 'fileuni-target.json');
12
+
13
+ function normalizeLibc(input) {
14
+ if (!input) {
15
+ return null;
16
+ }
17
+
18
+ const value = String(input).trim().toLowerCase();
19
+ if (value === 'gnu' || value === 'glibc') {
20
+ return 'gnu';
21
+ }
22
+ if (value === 'musl') {
23
+ return 'musl';
24
+ }
25
+ return null;
26
+ }
27
+
28
+ function detectLibc() {
29
+ const envLibc = normalizeLibc(process.env.FILEUNI_NPM_LIBC || process.env.npm_config_fileuni_libc);
30
+ if (envLibc) {
31
+ return envLibc;
32
+ }
33
+
34
+ if (process.platform !== 'linux') {
35
+ return null;
36
+ }
37
+
38
+ const report = process.report;
39
+ if (report && typeof report.getReport === 'function') {
40
+ const glibcVersion = report.getReport()?.header?.glibcVersionRuntime;
41
+ if (glibcVersion) {
42
+ return 'gnu';
43
+ }
44
+ }
45
+
46
+ return 'musl';
47
+ }
48
+
49
+ function supportedTargets() {
50
+ return manifest.targets.map((entry) => entry.target).sort();
51
+ }
52
+
53
+ function selectTarget() {
54
+ const explicitTarget = process.env.FILEUNI_NPM_TARGET || process.env.npm_config_fileuni_target;
55
+ if (explicitTarget) {
56
+ const match = manifest.targets.find((entry) => entry.target === explicitTarget);
57
+ if (!match) {
58
+ throw new Error(`Unsupported FILEUNI_NPM_TARGET: ${explicitTarget}. Supported targets: ${supportedTargets().join(', ')}`);
59
+ }
60
+ return match;
61
+ }
62
+
63
+ const libc = detectLibc();
64
+ const candidates = manifest.targets.filter((entry) => entry.os === process.platform && entry.arch === process.arch);
65
+ if (candidates.length === 0) {
66
+ throw new Error(`Unsupported platform: ${process.platform}/${process.arch}. Supported targets: ${supportedTargets().join(', ')}`);
67
+ }
68
+
69
+ if (process.platform !== 'linux') {
70
+ return candidates[0];
71
+ }
72
+
73
+ const preferredLibc = libc || 'gnu';
74
+ const exact = candidates.find((entry) => entry.libc === preferredLibc);
75
+ if (exact) {
76
+ return exact;
77
+ }
78
+
79
+ const fallbackGnu = candidates.find((entry) => entry.libc === 'gnu');
80
+ if (fallbackGnu) {
81
+ return fallbackGnu;
82
+ }
83
+
84
+ return candidates[0];
85
+ }
86
+
87
+ function binaryPathFor(entry) {
88
+ return entry.binary_name.endsWith('.exe') ? `${binaryBasePath}.exe` : binaryBasePath;
89
+ }
90
+
91
+ async function readInstalledMetadata() {
92
+ try {
93
+ const raw = await fsp.readFile(metadataPath, 'utf-8');
94
+ return JSON.parse(raw);
95
+ } catch (error) {
96
+ if (error && error.code === 'ENOENT') {
97
+ return null;
98
+ }
99
+ throw error;
100
+ }
101
+ }
102
+
103
+ async function writeInstalledMetadata(entry) {
104
+ await fsp.writeFile(
105
+ metadataPath,
106
+ `${JSON.stringify({ target: entry.target, asset_name: entry.asset_name, release_tag: manifest.release_tag }, null, 2)}\n`,
107
+ 'utf-8',
108
+ );
109
+ }
110
+
111
+ function releaseBaseUrl() {
112
+ const customBaseUrl = process.env.FILEUNI_NPM_BASE_URL;
113
+ if (customBaseUrl) {
114
+ return customBaseUrl.replace(/\/$/, '');
115
+ }
116
+ return `https://github.com/${manifest.repository}`;
117
+ }
118
+
119
+ function releaseAssetUrl(entry) {
120
+ return `${releaseBaseUrl()}/releases/download/${manifest.release_tag}/${entry.asset_name}`;
121
+ }
122
+
123
+ async function downloadAsset(entry, zipPath) {
124
+ const response = await fetch(releaseAssetUrl(entry));
125
+ if (!response.ok) {
126
+ throw new Error(`Failed to download ${entry.asset_name}: HTTP ${response.status} ${response.statusText}`);
127
+ }
128
+
129
+ const buffer = Buffer.from(await response.arrayBuffer());
130
+ await fsp.writeFile(zipPath, buffer);
131
+ }
132
+
133
+ async function installTarget(entry) {
134
+ await fsp.mkdir(binDir, { recursive: true });
135
+ const tmpDir = await fsp.mkdtemp(path.join(os.tmpdir(), 'fileuni-npm-'));
136
+ const zipPath = path.join(tmpDir, 'fileuni.zip');
137
+
138
+ try {
139
+ await downloadAsset(entry, zipPath);
140
+
141
+ const extractDir = path.join(tmpDir, 'extract');
142
+ await fsp.mkdir(extractDir, { recursive: true });
143
+ const archive = new AdmZip(zipPath);
144
+ archive.extractAllTo(extractDir, true);
145
+
146
+ const targetBinary = binaryPathFor(entry);
147
+ const extractedBinary = path.join(extractDir, entry.binary_name);
148
+ if (!fs.existsSync(extractedBinary)) {
149
+ throw new Error(`Downloaded archive does not contain ${entry.binary_name}`);
150
+ }
151
+
152
+ await fsp.copyFile(extractedBinary, targetBinary);
153
+ if (!entry.binary_name.endsWith('.exe')) {
154
+ await fsp.chmod(targetBinary, 0o755);
155
+ }
156
+ await writeInstalledMetadata(entry);
157
+ return targetBinary;
158
+ } finally {
159
+ await fsp.rm(tmpDir, { recursive: true, force: true });
160
+ }
161
+ }
162
+
163
+ async function ensureInstalled() {
164
+ const entry = selectTarget();
165
+ const targetBinary = binaryPathFor(entry);
166
+ const metadata = await readInstalledMetadata();
167
+
168
+ if (metadata && metadata.target === entry.target && fs.existsSync(targetBinary)) {
169
+ return targetBinary;
170
+ }
171
+
172
+ return installTarget(entry);
173
+ }
174
+
175
+ module.exports = {
176
+ ensureInstalled,
177
+ selectTarget,
178
+ supportedTargets,
179
+ };
@@ -0,0 +1,143 @@
1
+ {
2
+ "repository": "FileUni/FileUni-Project",
3
+ "release_tag": "manually_20260310_145953",
4
+ "version": "0.0.2-alpha2",
5
+ "targets": [
6
+ {
7
+ "target": "x86_64-unknown-linux-gnu",
8
+ "os": "linux",
9
+ "arch": "x64",
10
+ "libc": "gnu",
11
+ "binary_name": "fileuni",
12
+ "asset_name": "FileUni-cli-x86_64-linux-gnu.zip"
13
+ },
14
+ {
15
+ "target": "x86_64-unknown-linux-musl",
16
+ "os": "linux",
17
+ "arch": "x64",
18
+ "libc": "musl",
19
+ "binary_name": "fileuni",
20
+ "asset_name": "FileUni-cli-x86_64-linux-musl.zip"
21
+ },
22
+ {
23
+ "target": "aarch64-unknown-linux-gnu",
24
+ "os": "linux",
25
+ "arch": "arm64",
26
+ "libc": "gnu",
27
+ "binary_name": "fileuni",
28
+ "asset_name": "FileUni-cli-aarch64-linux-gnu.zip"
29
+ },
30
+ {
31
+ "target": "aarch64-unknown-linux-musl",
32
+ "os": "linux",
33
+ "arch": "arm64",
34
+ "libc": "musl",
35
+ "binary_name": "fileuni",
36
+ "asset_name": "FileUni-cli-aarch64-linux-musl.zip"
37
+ },
38
+ {
39
+ "target": "i686-unknown-linux-gnu",
40
+ "os": "linux",
41
+ "arch": "ia32",
42
+ "libc": "gnu",
43
+ "binary_name": "fileuni",
44
+ "asset_name": "FileUni-cli-x86_32-linux-gnu.zip"
45
+ },
46
+ {
47
+ "target": "i686-unknown-linux-musl",
48
+ "os": "linux",
49
+ "arch": "ia32",
50
+ "libc": "musl",
51
+ "binary_name": "fileuni",
52
+ "asset_name": "FileUni-cli-x86_32-linux-musl.zip"
53
+ },
54
+ {
55
+ "target": "arm-unknown-linux-gnueabi",
56
+ "os": "linux",
57
+ "arch": "arm",
58
+ "libc": "gnu",
59
+ "binary_name": "fileuni",
60
+ "asset_name": "FileUni-cli-arm-linux-gnu.zip"
61
+ },
62
+ {
63
+ "target": "armv7-unknown-linux-musleabihf",
64
+ "os": "linux",
65
+ "arch": "arm",
66
+ "libc": "musl",
67
+ "binary_name": "fileuni",
68
+ "asset_name": "FileUni-cli-armv7-linux-musl.zip"
69
+ },
70
+ {
71
+ "target": "riscv64gc-unknown-linux-gnu",
72
+ "os": "linux",
73
+ "arch": "riscv64",
74
+ "libc": "gnu",
75
+ "binary_name": "fileuni",
76
+ "asset_name": "FileUni-cli-riscv64gc-linux-gnu.zip"
77
+ },
78
+ {
79
+ "target": "powerpc64le-unknown-linux-gnu",
80
+ "os": "linux",
81
+ "arch": "ppc64",
82
+ "libc": "gnu",
83
+ "binary_name": "fileuni",
84
+ "asset_name": "FileUni-cli-powerpc64le-linux-gnu.zip"
85
+ },
86
+ {
87
+ "target": "x86_64-pc-windows-msvc",
88
+ "os": "win32",
89
+ "arch": "x64",
90
+ "binary_name": "fileuni.exe",
91
+ "asset_name": "FileUni-cli-x86_64-windows-msvc.exe.zip"
92
+ },
93
+ {
94
+ "target": "i686-pc-windows-msvc",
95
+ "os": "win32",
96
+ "arch": "ia32",
97
+ "binary_name": "fileuni.exe",
98
+ "asset_name": "FileUni-cli-x86_32-windows-msvc.exe.zip"
99
+ },
100
+ {
101
+ "target": "x86_64-apple-darwin",
102
+ "os": "darwin",
103
+ "arch": "x64",
104
+ "binary_name": "fileuni",
105
+ "asset_name": "FileUni-cli-x86_64-macos-darwin.zip"
106
+ },
107
+ {
108
+ "target": "aarch64-apple-darwin",
109
+ "os": "darwin",
110
+ "arch": "arm64",
111
+ "binary_name": "fileuni",
112
+ "asset_name": "FileUni-cli-aarch64-macos-darwin.zip"
113
+ },
114
+ {
115
+ "target": "aarch64-linux-android",
116
+ "os": "android",
117
+ "arch": "arm64",
118
+ "binary_name": "fileuni",
119
+ "asset_name": "FileUni-cli-aarch64-android-cli.zip"
120
+ },
121
+ {
122
+ "target": "armv7-linux-androideabi",
123
+ "os": "android",
124
+ "arch": "arm",
125
+ "binary_name": "fileuni",
126
+ "asset_name": "FileUni-cli-armv7-android-cli.zip"
127
+ },
128
+ {
129
+ "target": "x86_64-linux-android",
130
+ "os": "android",
131
+ "arch": "x64",
132
+ "binary_name": "fileuni",
133
+ "asset_name": "FileUni-cli-x86_64-android-cli.zip"
134
+ },
135
+ {
136
+ "target": "x86_64-unknown-freebsd",
137
+ "os": "freebsd",
138
+ "arch": "x64",
139
+ "binary_name": "fileuni",
140
+ "asset_name": "FileUni-cli-x86_64-freebsd-freebsd.zip"
141
+ }
142
+ ]
143
+ }
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { ensureInstalled } = require('./fileuni-common.cjs');
4
+
5
+ (async () => {
6
+ if (process.env.FILEUNI_NPM_SKIP_DOWNLOAD === '1') {
7
+ console.log('[fileuni] Skipping binary download because FILEUNI_NPM_SKIP_DOWNLOAD=1');
8
+ return;
9
+ }
10
+
11
+ const binaryPath = await ensureInstalled();
12
+ console.log(`[fileuni] Installed binary: ${binaryPath}`);
13
+ })().catch((error) => {
14
+ console.error(`[fileuni] ${error instanceof Error ? error.message : String(error)}`);
15
+ process.exit(1);
16
+ });