superprint 1.0.21 → 1.0.26
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 +13 -13
- package/cli.mjs +49 -49
- package/package.json +2 -2
- package/scripts/postinstall.mjs +4 -4
package/README.md
CHANGED
|
@@ -1,32 +1,32 @@
|
|
|
1
1
|
# SuperPrint
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Free browser-based **DTP (page layout)** software + **SP213 studio** for AI-generated layouts.
|
|
4
4
|
|
|
5
|
-
100% **local
|
|
5
|
+
100% **local**: AI models are downloaded once then run on your machine via **WebGPU** (WebLLM). No data ever leaves your computer.
|
|
6
6
|
|
|
7
|
-
##
|
|
7
|
+
## Install — a single command
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Prerequisite: [Node.js 18+](https://nodejs.org) (npm included).
|
|
10
10
|
|
|
11
11
|
```bash
|
|
12
12
|
npx superprint
|
|
13
13
|
```
|
|
14
14
|
|
|
15
|
-
> 💡 **Windows (PowerShell)
|
|
15
|
+
> 💡 **Windows (PowerShell)**: if you see a `PSSecurityException` error (script execution disabled), use `npx.cmd superprint` — the `.cmd` wrapper bypasses the PowerShell execution policy.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
On first launch, SuperPrint downloads the application (≈50 MB, only once), installs the dependencies and opens your browser at **http://localhost:5173**.
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
Identical on **Windows, macOS and Linux**.
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## Usage
|
|
22
22
|
|
|
23
|
-
- **Studio
|
|
24
|
-
- **SuperPrint Editor
|
|
23
|
+
- **SP213 Studio**: create your layouts by chatting with the AI.
|
|
24
|
+
- **SuperPrint Editor**: refine your layouts in the full DTP canvas (mm, bleed, safe zones…).
|
|
25
25
|
|
|
26
|
-
##
|
|
26
|
+
## Online
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
No install needed: [superprint.cc](https://superprint.cc) (web version, also available on mobile).
|
|
29
29
|
|
|
30
|
-
##
|
|
30
|
+
## License
|
|
31
31
|
|
|
32
32
|
MIT — © SuperPrint
|
package/cli.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
// ═══════════════════════════════════════════════════════════════
|
|
3
|
-
// SuperPrint — launcher
|
|
4
|
-
//
|
|
5
|
-
//
|
|
6
|
-
//
|
|
3
|
+
// SuperPrint — npm launcher
|
|
4
|
+
// A single command: npx superprint
|
|
5
|
+
// Downloads the app (once), installs deps, launches Vite.
|
|
6
|
+
// Works identically on Windows, macOS and Linux.
|
|
7
7
|
// ═══════════════════════════════════════════════════════════════
|
|
8
8
|
import { spawn, spawnSync } from 'node:child_process';
|
|
9
9
|
import { createWriteStream, existsSync, mkdirSync, readFileSync, statSync, writeFileSync, unlinkSync } from 'node:fs';
|
|
@@ -57,12 +57,12 @@ function info(m) { console.log(C.dim + ' · ' + m + C.reset); }
|
|
|
57
57
|
function warn(m) { console.log(C.yellow + ' ⚠ ' + m + C.reset); }
|
|
58
58
|
function fail(m) {
|
|
59
59
|
console.log('');
|
|
60
|
-
console.log(C.bgRed + C.white + '
|
|
60
|
+
console.log(C.bgRed + C.white + ' ERROR ' + C.reset);
|
|
61
61
|
console.log(C.red + ' ' + m + C.reset);
|
|
62
|
-
console.log(C.dim + '
|
|
62
|
+
console.log(C.dim + ' Download manually: https://app.zigmoon.com/sp213-local.zip' + C.reset);
|
|
63
63
|
}
|
|
64
64
|
|
|
65
|
-
// ──
|
|
65
|
+
// ── Network helpers ───────────────────────────────────────────
|
|
66
66
|
function httpsGetText(url, timeout = 20000) {
|
|
67
67
|
return new Promise((resolve, reject) => {
|
|
68
68
|
const req = httpsGet(url, (res) => {
|
|
@@ -88,7 +88,7 @@ function downloadFile(url, dest) {
|
|
|
88
88
|
received += chunk.length;
|
|
89
89
|
if (total) {
|
|
90
90
|
const pct = Math.floor((received / total) * 100);
|
|
91
|
-
if (pct !== lastPct) { lastPct = pct; process.stdout.write('\r ⬇
|
|
91
|
+
if (pct !== lastPct) { lastPct = pct; process.stdout.write('\r ⬇ Downloading… ' + pct + '% '); }
|
|
92
92
|
}
|
|
93
93
|
});
|
|
94
94
|
const out = createWriteStream(dest);
|
|
@@ -102,7 +102,7 @@ function downloadFile(url, dest) {
|
|
|
102
102
|
});
|
|
103
103
|
}
|
|
104
104
|
|
|
105
|
-
// ──
|
|
105
|
+
// ── Extraction ────────────────────────────────────────────────
|
|
106
106
|
function unzip(zipPath, destDir) {
|
|
107
107
|
if (isWin) {
|
|
108
108
|
const r = spawnSync('powershell', ['-NoProfile', '-Command',
|
|
@@ -123,7 +123,7 @@ function unzip(zipPath, destDir) {
|
|
|
123
123
|
return false;
|
|
124
124
|
}
|
|
125
125
|
|
|
126
|
-
// ──
|
|
126
|
+
// ── Existing install check ────────────────────────────────────
|
|
127
127
|
function isInstalled() {
|
|
128
128
|
return existsSync(path.join(APP_DIR, 'package.json'));
|
|
129
129
|
}
|
|
@@ -135,88 +135,88 @@ function installedVersion() {
|
|
|
135
135
|
async function main() {
|
|
136
136
|
console.log('');
|
|
137
137
|
console.log(C.cyan + C.bold + BANNER + C.reset);
|
|
138
|
-
console.log(C.bgDark + C.white + ' SUPERPRINT ·
|
|
139
|
-
console.log(C.dim + '
|
|
138
|
+
console.log(C.bgDark + C.white + ' SUPERPRINT · DTP + SP213 Studio · 100% local' + C.reset);
|
|
139
|
+
console.log(C.dim + ' No data ever leaves your machine.' + C.reset);
|
|
140
140
|
|
|
141
|
-
// ----
|
|
142
|
-
step(1, '
|
|
141
|
+
// ---- Step 1/4: check online version ----
|
|
142
|
+
step(1, 'Checking online version');
|
|
143
143
|
let onlineVersion = null;
|
|
144
144
|
try { onlineVersion = await httpsGetText(APP_VERSION_URL); } catch (e) {}
|
|
145
145
|
const localVer = installedVersion();
|
|
146
146
|
|
|
147
147
|
if (isInstalled()) {
|
|
148
148
|
if (onlineVersion && localVer && onlineVersion !== localVer) {
|
|
149
|
-
info('
|
|
150
|
-
//
|
|
149
|
+
info('Online version (' + onlineVersion + ') ≠ local (' + localVer + ') — updating.');
|
|
150
|
+
// Remove the old app to re-download the new one
|
|
151
151
|
const { rmSync } = await import('node:fs');
|
|
152
152
|
rmSync(APP_DIR, { recursive: true, force: true });
|
|
153
153
|
} else {
|
|
154
|
-
info('
|
|
154
|
+
info('Already installed (v' + (localVer || '?') + ') — skipping download.');
|
|
155
155
|
}
|
|
156
|
-
ok('SuperPrint
|
|
156
|
+
ok('SuperPrint is ready.');
|
|
157
157
|
} else {
|
|
158
|
-
info('
|
|
159
|
-
ok(onlineVersion ? '
|
|
158
|
+
info('First install — downloading the application.');
|
|
159
|
+
ok(onlineVersion ? 'Latest online version: v' + onlineVersion : 'Online version: superprint.cc');
|
|
160
160
|
}
|
|
161
161
|
|
|
162
|
-
// ----
|
|
162
|
+
// ---- Step 2/4: download + extract ----
|
|
163
163
|
if (!isInstalled()) {
|
|
164
|
-
step(2, '
|
|
165
|
-
info('Source
|
|
164
|
+
step(2, 'Downloading the application');
|
|
165
|
+
info('Source: ' + APP_ZIP_URL);
|
|
166
166
|
try {
|
|
167
167
|
await downloadFile(APP_ZIP_URL, ZIP_PATH);
|
|
168
|
-
ok('
|
|
168
|
+
ok('Downloaded (' + Math.round(statSync(ZIP_PATH).size / 1048576) + ' MB).');
|
|
169
169
|
} catch (e) {
|
|
170
|
-
fail('
|
|
170
|
+
fail('Download failed: ' + e.message);
|
|
171
171
|
process.exit(1);
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
step(3, '
|
|
175
|
-
info('
|
|
174
|
+
step(3, 'Extracting');
|
|
175
|
+
info('Into: ' + APP_DIR);
|
|
176
176
|
mkdirSync(APP_DIR, { recursive: true });
|
|
177
177
|
if (!unzip(ZIP_PATH, APP_DIR)) {
|
|
178
|
-
fail('
|
|
178
|
+
fail('Failed to extract the zip.');
|
|
179
179
|
process.exit(1);
|
|
180
180
|
}
|
|
181
|
-
ok('Application
|
|
181
|
+
ok('Application extracted.');
|
|
182
182
|
if (onlineVersion) {
|
|
183
183
|
try { mkdirSync(APP_DIR, { recursive: true }); } catch {}
|
|
184
184
|
try { writeFileSync(VERSION_FILE, onlineVersion); } catch {}
|
|
185
185
|
}
|
|
186
|
-
//
|
|
186
|
+
// Clean up the zip (save space)
|
|
187
187
|
try { unlinkSync(ZIP_PATH); } catch {}
|
|
188
188
|
}
|
|
189
189
|
|
|
190
|
-
// ----
|
|
190
|
+
// ---- Step 4/4: npm install if needed ----
|
|
191
191
|
if (!existsSync(path.join(APP_DIR, 'node_modules'))) {
|
|
192
|
-
step(4, '
|
|
193
|
-
info('
|
|
194
|
-
// shell:true
|
|
195
|
-
//
|
|
192
|
+
step(4, 'Installing dependencies (npm install)');
|
|
193
|
+
info('First install: a few minutes. Subsequent launches will be instant.');
|
|
194
|
+
// shell:true needed on Windows to launch npm (the .cmd wrappers
|
|
195
|
+
// fail with EINVAL via spawnSync without shell).
|
|
196
196
|
const r = spawnSync('npm', ['install', '--no-audit', '--no-fund'], {
|
|
197
197
|
stdio: 'inherit', cwd: APP_DIR, shell: true
|
|
198
198
|
});
|
|
199
|
-
if (r.status !== 0) { fail('
|
|
200
|
-
// npm 12+
|
|
201
|
-
//
|
|
202
|
-
//
|
|
199
|
+
if (r.status !== 0) { fail('npm install failed.'); process.exit(1); }
|
|
200
|
+
// npm 12+ blocks install scripts (e.g. esbuild needs its postinstall
|
|
201
|
+
// to place its native binary). We approve all: this is our own
|
|
202
|
+
// trusted application.
|
|
203
203
|
const appr = spawnSync('npm', ['install-scripts', 'approve', '--all'], {
|
|
204
204
|
stdio: 'inherit', cwd: APP_DIR, shell: true
|
|
205
205
|
});
|
|
206
206
|
if (appr.status !== 0) {
|
|
207
|
-
//
|
|
208
|
-
warn('
|
|
207
|
+
// Command missing (npm < 12): not an issue, scripts run by default.
|
|
208
|
+
warn('Install-scripts approval not available — ignored.');
|
|
209
209
|
}
|
|
210
|
-
ok('
|
|
210
|
+
ok('Dependencies installed.');
|
|
211
211
|
} else {
|
|
212
|
-
info('
|
|
213
|
-
ok('
|
|
212
|
+
info('Dependencies already installed.');
|
|
213
|
+
ok('Everything is ready.');
|
|
214
214
|
}
|
|
215
215
|
|
|
216
|
-
// ----
|
|
216
|
+
// ---- Launch Vite ----
|
|
217
217
|
console.log(SEP);
|
|
218
|
-
console.log(C.green + C.bold + '
|
|
219
|
-
console.log(C.dim + '
|
|
218
|
+
console.log(C.green + C.bold + ' Starting SuperPrint…' + C.reset);
|
|
219
|
+
console.log(C.dim + ' Open your browser at: http://localhost:5173' + C.reset);
|
|
220
220
|
console.log(SEP);
|
|
221
221
|
|
|
222
222
|
const viteBin = path.join(APP_DIR, 'node_modules', 'vite', 'bin', 'vite.js');
|
|
@@ -226,12 +226,12 @@ async function main() {
|
|
|
226
226
|
});
|
|
227
227
|
child.on('close', (code) => {
|
|
228
228
|
if (code !== 0 && code !== null) {
|
|
229
|
-
console.log(C.yellow + '\n
|
|
229
|
+
console.log(C.yellow + '\n The server stopped (code ' + code + ').' + C.reset);
|
|
230
230
|
}
|
|
231
231
|
});
|
|
232
232
|
}
|
|
233
233
|
|
|
234
234
|
main().catch((e) => {
|
|
235
|
-
console.error(C.red + '
|
|
235
|
+
console.error(C.red + ' Error: ' + (e && e.message ? e.message : e) + C.reset);
|
|
236
236
|
process.exit(1);
|
|
237
237
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "superprint",
|
|
3
|
-
"version": "1.0.
|
|
4
|
-
"description": "SuperPrint —
|
|
3
|
+
"version": "1.0.26",
|
|
4
|
+
"description": "SuperPrint — free browser-based DTP (page layout) software + SP213 AI layout studio. 100% local, no CDN, no data ever leaves your machine.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"superprint",
|
|
7
7
|
"sp213",
|
package/scripts/postinstall.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
//
|
|
2
|
+
// Shown after `npm install -g superprint` or `npx superprint`
|
|
3
3
|
console.log('');
|
|
4
4
|
console.log('\x1b[36m ═══════════════════════════════════════════════════════\x1b[0m');
|
|
5
|
-
console.log('\x1b[36m ║ SUPERPRINT —
|
|
5
|
+
console.log('\x1b[36m ║ SUPERPRINT — installed. Run with: npx superprint \x1b[0m');
|
|
6
6
|
console.log('\x1b[36m ═══════════════════════════════════════════════════════\x1b[0m');
|
|
7
|
-
console.log('\x1b[2m ·
|
|
8
|
-
console.log('\x1b[2m ·
|
|
7
|
+
console.log('\x1b[2m · DTP + SP213 AI studio · 100% local\x1b[0m');
|
|
8
|
+
console.log('\x1b[2m · No data ever leaves your machine.\x1b[0m');
|
|
9
9
|
console.log('');
|