@fluxfiles/node 0.1.17 → 0.1.19
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 +22 -0
- package/dist/index.d.mts +16 -7
- package/dist/index.d.ts +16 -7
- package/dist/index.js +8 -4
- package/dist/index.mjs +8 -4
- package/package.json +1 -1
- package/src/token.ts +10 -4
- package/src/types.ts +16 -7
package/README.md
CHANGED
|
@@ -68,6 +68,28 @@ The core then accepts `POST /api/fm/import-url` for that token (SSRF-guarded,
|
|
|
68
68
|
sharing the quota/dedup/variants pipeline). Server-wide defaults come from
|
|
69
69
|
`FLUXFILES_IMPORT_*` env vars on the core service.
|
|
70
70
|
|
|
71
|
+
### SFTP disk: chmod & SSH terminal
|
|
72
|
+
|
|
73
|
+
When the token targets a FluxFiles server that has an **SFTP disk** configured
|
|
74
|
+
(`SFTP_*` env on that server — see the
|
|
75
|
+
[core README](https://github.com/thai-pc/fluxfiles#sftp-disk-vps--shared-hosting)),
|
|
76
|
+
you can hand a token the SFTP file-manager tools. `chmod` is on by default for SFTP;
|
|
77
|
+
the **SSH terminal** is opt-in (it grants shell access as the SSH user):
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
const token = createToken({
|
|
81
|
+
userId: 'admin-7',
|
|
82
|
+
perms: ['read', 'write'],
|
|
83
|
+
disks: ['sftp'], // an SFTP disk configured on the FluxFiles server
|
|
84
|
+
allowChmod: true, // cPanel-style permissions (default on for SFTP)
|
|
85
|
+
allowTerminal: true, // SSH terminal — opt-in, off by default
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
These are **standalone-core** features: `@fluxfiles/node` mints for a real
|
|
90
|
+
FluxFiles server (Docker / standalone), which serves them — they aren't available
|
|
91
|
+
behind the WordPress / Laravel-proxy adapters.
|
|
92
|
+
|
|
71
93
|
### BYOB — encrypt a user's own bucket credentials
|
|
72
94
|
|
|
73
95
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -100,17 +100,20 @@ interface BaseTokenOptions {
|
|
|
100
100
|
* access as the SSH user, so it's opt-in. Core-standalone: the token must target a real core
|
|
101
101
|
* (this SDK does), not a proxy adapter that doesn't serve /api/fm/terminal. */
|
|
102
102
|
allowTerminal?: boolean;
|
|
103
|
-
/**
|
|
104
|
-
*
|
|
103
|
+
/** Optional self-hosted PTY terminal URL (ttyd / gotty / wetty, or any PTY-over-WebSocket
|
|
104
|
+
* server the operator runs). When set (and `allowTerminal` is true), the UI embeds it for a
|
|
105
|
+
* true interactive terminal instead of the built-in command-runner. Free; must be http(s).
|
|
106
|
+
* Core-standalone only (like `allowTerminal`). */
|
|
107
|
+
terminalPtyUrl?: string;
|
|
108
|
+
/** Allow the Optimization feature (POST /api/fm/optimize) — recompress images to WebP +
|
|
109
|
+
* compress PDFs. **Free/core**; default **false** because it replaces/deletes originals, so
|
|
110
|
+
* it's an opt-in capability. */
|
|
105
111
|
allowOptimize?: boolean;
|
|
106
|
-
/** Auto-optimize images on upload (recompress to WebP in the pipeline). Default false
|
|
107
|
-
*
|
|
112
|
+
/** Auto-optimize images on upload (recompress to WebP in the pipeline). Default false.
|
|
113
|
+
* Free/core. */
|
|
108
114
|
autoOptimize?: boolean;
|
|
109
115
|
/** WebP quality for optimization, 40–95. `0`/omitted = inherit the server default (82). */
|
|
110
116
|
optimizeQuality?: number;
|
|
111
|
-
/** Target format for optimization: `'webp'` (default) or `'avif'` (falls back to
|
|
112
|
-
* WebP when the server build lacks AVIF). */
|
|
113
|
-
optimizeFormat?: 'webp' | 'avif';
|
|
114
117
|
/** Keep the original file when optimizing (default false = replace in place). */
|
|
115
118
|
optimizeKeepOriginal?: boolean;
|
|
116
119
|
/** Skip optimizing a file larger than this many MB (0/omitted = no limit). */
|
|
@@ -134,6 +137,7 @@ interface BaseTokenOptions {
|
|
|
134
137
|
/** Paid-module claims (3-layer gate: code installed + licensed + this claim).
|
|
135
138
|
* All default off; inert unless the module is installed & licensed on the server. */
|
|
136
139
|
allowShare?: boolean;
|
|
140
|
+
allowIntake?: boolean;
|
|
137
141
|
allowAiVision?: boolean;
|
|
138
142
|
allowOcr?: boolean;
|
|
139
143
|
allowVirusScan?: boolean;
|
|
@@ -171,6 +175,11 @@ interface BaseTokenOptions {
|
|
|
171
175
|
usageTopFoldersCount?: number;
|
|
172
176
|
/** Folder grouping depth for the usage breakdown. `0`/omitted = inherit (1). */
|
|
173
177
|
usageFolderDepth?: number;
|
|
178
|
+
/** Generic escape hatch: any JWT claim by its raw snake_case name (e.g.
|
|
179
|
+
* `{ allow_terminal: true, terminal_pty_url: '…', upload_collision: 'overwrite' }`).
|
|
180
|
+
* Merged last so explicit claims win; the server sanitizes on decode. The single
|
|
181
|
+
* place to set claims that don't have a typed option here. See docs/CONFIG.md. */
|
|
182
|
+
claims?: Record<string, unknown>;
|
|
174
183
|
}
|
|
175
184
|
interface CreateTokenOptions extends BaseTokenOptions {
|
|
176
185
|
/** Disk names the token may access. */
|
package/dist/index.d.ts
CHANGED
|
@@ -100,17 +100,20 @@ interface BaseTokenOptions {
|
|
|
100
100
|
* access as the SSH user, so it's opt-in. Core-standalone: the token must target a real core
|
|
101
101
|
* (this SDK does), not a proxy adapter that doesn't serve /api/fm/terminal. */
|
|
102
102
|
allowTerminal?: boolean;
|
|
103
|
-
/**
|
|
104
|
-
*
|
|
103
|
+
/** Optional self-hosted PTY terminal URL (ttyd / gotty / wetty, or any PTY-over-WebSocket
|
|
104
|
+
* server the operator runs). When set (and `allowTerminal` is true), the UI embeds it for a
|
|
105
|
+
* true interactive terminal instead of the built-in command-runner. Free; must be http(s).
|
|
106
|
+
* Core-standalone only (like `allowTerminal`). */
|
|
107
|
+
terminalPtyUrl?: string;
|
|
108
|
+
/** Allow the Optimization feature (POST /api/fm/optimize) — recompress images to WebP +
|
|
109
|
+
* compress PDFs. **Free/core**; default **false** because it replaces/deletes originals, so
|
|
110
|
+
* it's an opt-in capability. */
|
|
105
111
|
allowOptimize?: boolean;
|
|
106
|
-
/** Auto-optimize images on upload (recompress to WebP in the pipeline). Default false
|
|
107
|
-
*
|
|
112
|
+
/** Auto-optimize images on upload (recompress to WebP in the pipeline). Default false.
|
|
113
|
+
* Free/core. */
|
|
108
114
|
autoOptimize?: boolean;
|
|
109
115
|
/** WebP quality for optimization, 40–95. `0`/omitted = inherit the server default (82). */
|
|
110
116
|
optimizeQuality?: number;
|
|
111
|
-
/** Target format for optimization: `'webp'` (default) or `'avif'` (falls back to
|
|
112
|
-
* WebP when the server build lacks AVIF). */
|
|
113
|
-
optimizeFormat?: 'webp' | 'avif';
|
|
114
117
|
/** Keep the original file when optimizing (default false = replace in place). */
|
|
115
118
|
optimizeKeepOriginal?: boolean;
|
|
116
119
|
/** Skip optimizing a file larger than this many MB (0/omitted = no limit). */
|
|
@@ -134,6 +137,7 @@ interface BaseTokenOptions {
|
|
|
134
137
|
/** Paid-module claims (3-layer gate: code installed + licensed + this claim).
|
|
135
138
|
* All default off; inert unless the module is installed & licensed on the server. */
|
|
136
139
|
allowShare?: boolean;
|
|
140
|
+
allowIntake?: boolean;
|
|
137
141
|
allowAiVision?: boolean;
|
|
138
142
|
allowOcr?: boolean;
|
|
139
143
|
allowVirusScan?: boolean;
|
|
@@ -171,6 +175,11 @@ interface BaseTokenOptions {
|
|
|
171
175
|
usageTopFoldersCount?: number;
|
|
172
176
|
/** Folder grouping depth for the usage breakdown. `0`/omitted = inherit (1). */
|
|
173
177
|
usageFolderDepth?: number;
|
|
178
|
+
/** Generic escape hatch: any JWT claim by its raw snake_case name (e.g.
|
|
179
|
+
* `{ allow_terminal: true, terminal_pty_url: '…', upload_collision: 'overwrite' }`).
|
|
180
|
+
* Merged last so explicit claims win; the server sanitizes on decode. The single
|
|
181
|
+
* place to set claims that don't have a typed option here. See docs/CONFIG.md. */
|
|
182
|
+
claims?: Record<string, unknown>;
|
|
174
183
|
}
|
|
175
184
|
interface CreateTokenOptions extends BaseTokenOptions {
|
|
176
185
|
/** Disk names the token may access. */
|
package/dist/index.js
CHANGED
|
@@ -137,9 +137,9 @@ function sanitizeVariants(v) {
|
|
|
137
137
|
return Object.keys(out).length ? out : null;
|
|
138
138
|
}
|
|
139
139
|
var EDITION_PRESETS = {
|
|
140
|
-
pro: { allow_optimize: true, allow_share: true },
|
|
141
|
-
agency: { allow_optimize: true, allow_share: true },
|
|
142
|
-
enterprise: { allow_optimize: true, allow_share: true, allow_virus_scan: true }
|
|
140
|
+
pro: { allow_optimize: true, allow_share: true, allow_intake: true },
|
|
141
|
+
agency: { allow_optimize: true, allow_share: true, allow_intake: true },
|
|
142
|
+
enterprise: { allow_optimize: true, allow_share: true, allow_intake: true, allow_virus_scan: true, allow_c2pa: true }
|
|
143
143
|
};
|
|
144
144
|
function applyTenantOverrides(payload, opts) {
|
|
145
145
|
const preset = opts.edition ? EDITION_PRESETS[String(opts.edition).toLowerCase()] : void 0;
|
|
@@ -172,8 +172,10 @@ function applyTenantOverrides(payload, opts) {
|
|
|
172
172
|
if (opts.allowChmod !== void 0) payload.allow_chmod = !!opts.allowChmod;
|
|
173
173
|
if (opts.allowCodeEdit !== void 0) payload.allow_code_edit = !!opts.allowCodeEdit;
|
|
174
174
|
if (opts.allowTerminal !== void 0) payload.allow_terminal = !!opts.allowTerminal;
|
|
175
|
+
if (opts.terminalPtyUrl) payload.terminal_pty_url = String(opts.terminalPtyUrl);
|
|
175
176
|
if (opts.allowOptimize !== void 0) payload.allow_optimize = !!opts.allowOptimize;
|
|
176
177
|
if (opts.allowShare !== void 0) payload.allow_share = !!opts.allowShare;
|
|
178
|
+
if (opts.allowIntake !== void 0) payload.allow_intake = !!opts.allowIntake;
|
|
177
179
|
if (opts.allowAiVision !== void 0) payload.allow_ai_vision = !!opts.allowAiVision;
|
|
178
180
|
if (opts.allowOcr !== void 0) payload.allow_ocr = !!opts.allowOcr;
|
|
179
181
|
if (opts.allowVirusScan !== void 0) payload.allow_virus_scan = !!opts.allowVirusScan;
|
|
@@ -181,7 +183,6 @@ function applyTenantOverrides(payload, opts) {
|
|
|
181
183
|
if (opts.allowC2pa !== void 0) payload.allow_c2pa = !!opts.allowC2pa;
|
|
182
184
|
if (opts.autoOptimize !== void 0) payload.auto_optimize = !!opts.autoOptimize;
|
|
183
185
|
if (opts.optimizeQuality && opts.optimizeQuality > 0) payload.optimize_quality = Math.trunc(opts.optimizeQuality);
|
|
184
|
-
if (opts.optimizeFormat === "avif") payload.optimize_format = "avif";
|
|
185
186
|
if (opts.optimizeKeepOriginal !== void 0) payload.optimize_keep_original = !!opts.optimizeKeepOriginal;
|
|
186
187
|
if (opts.optimizeMaxMb && opts.optimizeMaxMb > 0) payload.optimize_max_mb = Math.trunc(opts.optimizeMaxMb);
|
|
187
188
|
if (opts.pdfLevel && ["screen", "ebook", "printer", "prepress", "default"].includes(opts.pdfLevel)) {
|
|
@@ -210,6 +211,9 @@ function applyTenantOverrides(payload, opts) {
|
|
|
210
211
|
if (opts.usageCriticalThreshold && opts.usageCriticalThreshold > 0) payload.usage_critical_threshold = Math.trunc(opts.usageCriticalThreshold);
|
|
211
212
|
if (opts.usageTopFoldersCount && opts.usageTopFoldersCount > 0) payload.usage_top_folders_count = Math.trunc(opts.usageTopFoldersCount);
|
|
212
213
|
if (opts.usageFolderDepth && opts.usageFolderDepth > 0) payload.usage_folder_depth = Math.trunc(opts.usageFolderDepth);
|
|
214
|
+
if (opts.claims) {
|
|
215
|
+
for (const [k, v] of Object.entries(opts.claims)) if (v !== void 0 && v !== null) payload[k] = v;
|
|
216
|
+
}
|
|
213
217
|
}
|
|
214
218
|
function validateByobDisk(name, config) {
|
|
215
219
|
if (!config || config.driver !== "s3" && config.driver !== "sftp") {
|
package/dist/index.mjs
CHANGED
|
@@ -115,9 +115,9 @@ function sanitizeVariants(v) {
|
|
|
115
115
|
return Object.keys(out).length ? out : null;
|
|
116
116
|
}
|
|
117
117
|
var EDITION_PRESETS = {
|
|
118
|
-
pro: { allow_optimize: true, allow_share: true },
|
|
119
|
-
agency: { allow_optimize: true, allow_share: true },
|
|
120
|
-
enterprise: { allow_optimize: true, allow_share: true, allow_virus_scan: true }
|
|
118
|
+
pro: { allow_optimize: true, allow_share: true, allow_intake: true },
|
|
119
|
+
agency: { allow_optimize: true, allow_share: true, allow_intake: true },
|
|
120
|
+
enterprise: { allow_optimize: true, allow_share: true, allow_intake: true, allow_virus_scan: true, allow_c2pa: true }
|
|
121
121
|
};
|
|
122
122
|
function applyTenantOverrides(payload, opts) {
|
|
123
123
|
const preset = opts.edition ? EDITION_PRESETS[String(opts.edition).toLowerCase()] : void 0;
|
|
@@ -150,8 +150,10 @@ function applyTenantOverrides(payload, opts) {
|
|
|
150
150
|
if (opts.allowChmod !== void 0) payload.allow_chmod = !!opts.allowChmod;
|
|
151
151
|
if (opts.allowCodeEdit !== void 0) payload.allow_code_edit = !!opts.allowCodeEdit;
|
|
152
152
|
if (opts.allowTerminal !== void 0) payload.allow_terminal = !!opts.allowTerminal;
|
|
153
|
+
if (opts.terminalPtyUrl) payload.terminal_pty_url = String(opts.terminalPtyUrl);
|
|
153
154
|
if (opts.allowOptimize !== void 0) payload.allow_optimize = !!opts.allowOptimize;
|
|
154
155
|
if (opts.allowShare !== void 0) payload.allow_share = !!opts.allowShare;
|
|
156
|
+
if (opts.allowIntake !== void 0) payload.allow_intake = !!opts.allowIntake;
|
|
155
157
|
if (opts.allowAiVision !== void 0) payload.allow_ai_vision = !!opts.allowAiVision;
|
|
156
158
|
if (opts.allowOcr !== void 0) payload.allow_ocr = !!opts.allowOcr;
|
|
157
159
|
if (opts.allowVirusScan !== void 0) payload.allow_virus_scan = !!opts.allowVirusScan;
|
|
@@ -159,7 +161,6 @@ function applyTenantOverrides(payload, opts) {
|
|
|
159
161
|
if (opts.allowC2pa !== void 0) payload.allow_c2pa = !!opts.allowC2pa;
|
|
160
162
|
if (opts.autoOptimize !== void 0) payload.auto_optimize = !!opts.autoOptimize;
|
|
161
163
|
if (opts.optimizeQuality && opts.optimizeQuality > 0) payload.optimize_quality = Math.trunc(opts.optimizeQuality);
|
|
162
|
-
if (opts.optimizeFormat === "avif") payload.optimize_format = "avif";
|
|
163
164
|
if (opts.optimizeKeepOriginal !== void 0) payload.optimize_keep_original = !!opts.optimizeKeepOriginal;
|
|
164
165
|
if (opts.optimizeMaxMb && opts.optimizeMaxMb > 0) payload.optimize_max_mb = Math.trunc(opts.optimizeMaxMb);
|
|
165
166
|
if (opts.pdfLevel && ["screen", "ebook", "printer", "prepress", "default"].includes(opts.pdfLevel)) {
|
|
@@ -188,6 +189,9 @@ function applyTenantOverrides(payload, opts) {
|
|
|
188
189
|
if (opts.usageCriticalThreshold && opts.usageCriticalThreshold > 0) payload.usage_critical_threshold = Math.trunc(opts.usageCriticalThreshold);
|
|
189
190
|
if (opts.usageTopFoldersCount && opts.usageTopFoldersCount > 0) payload.usage_top_folders_count = Math.trunc(opts.usageTopFoldersCount);
|
|
190
191
|
if (opts.usageFolderDepth && opts.usageFolderDepth > 0) payload.usage_folder_depth = Math.trunc(opts.usageFolderDepth);
|
|
192
|
+
if (opts.claims) {
|
|
193
|
+
for (const [k, v] of Object.entries(opts.claims)) if (v !== void 0 && v !== null) payload[k] = v;
|
|
194
|
+
}
|
|
191
195
|
}
|
|
192
196
|
function validateByobDisk(name, config) {
|
|
193
197
|
if (!config || config.driver !== "s3" && config.driver !== "sftp") {
|
package/package.json
CHANGED
package/src/token.ts
CHANGED
|
@@ -99,9 +99,9 @@ function sanitizeVariants(v: BaseTokenOptions['variants']): Record<string, numbe
|
|
|
99
99
|
|
|
100
100
|
/** Edition preset (DX sugar): default a tier's claims; explicit opts below win. */
|
|
101
101
|
const EDITION_PRESETS: Record<string, Record<string, boolean>> = {
|
|
102
|
-
pro: { allow_optimize: true, allow_share: true },
|
|
103
|
-
agency: { allow_optimize: true, allow_share: true },
|
|
104
|
-
enterprise: { allow_optimize: true, allow_share: true, allow_virus_scan: true },
|
|
102
|
+
pro: { allow_optimize: true, allow_share: true, allow_intake: true },
|
|
103
|
+
agency: { allow_optimize: true, allow_share: true, allow_intake: true },
|
|
104
|
+
enterprise: { allow_optimize: true, allow_share: true, allow_intake: true, allow_virus_scan: true, allow_c2pa: true },
|
|
105
105
|
};
|
|
106
106
|
|
|
107
107
|
/** Copy the optional per-tenant override claims into a payload when set. */
|
|
@@ -144,9 +144,11 @@ function applyTenantOverrides(payload: Record<string, unknown>, opts: BaseTokenO
|
|
|
144
144
|
// SSH terminal (SFTP disks). Core-standalone — the token must target a real core
|
|
145
145
|
// (Node mints for one), not a proxy adapter that doesn't serve /api/fm/terminal.
|
|
146
146
|
if (opts.allowTerminal !== undefined) payload.allow_terminal = !!opts.allowTerminal;
|
|
147
|
+
if (opts.terminalPtyUrl) payload.terminal_pty_url = String(opts.terminalPtyUrl);
|
|
147
148
|
if (opts.allowOptimize !== undefined) payload.allow_optimize = !!opts.allowOptimize;
|
|
148
149
|
// Other paid-module claims (inert unless the module is installed + licensed).
|
|
149
150
|
if (opts.allowShare !== undefined) payload.allow_share = !!opts.allowShare;
|
|
151
|
+
if (opts.allowIntake !== undefined) payload.allow_intake = !!opts.allowIntake;
|
|
150
152
|
if (opts.allowAiVision !== undefined) payload.allow_ai_vision = !!opts.allowAiVision;
|
|
151
153
|
if (opts.allowOcr !== undefined) payload.allow_ocr = !!opts.allowOcr;
|
|
152
154
|
if (opts.allowVirusScan !== undefined) payload.allow_virus_scan = !!opts.allowVirusScan;
|
|
@@ -154,7 +156,6 @@ function applyTenantOverrides(payload: Record<string, unknown>, opts: BaseTokenO
|
|
|
154
156
|
if (opts.allowC2pa !== undefined) payload.allow_c2pa = !!opts.allowC2pa;
|
|
155
157
|
if (opts.autoOptimize !== undefined) payload.auto_optimize = !!opts.autoOptimize;
|
|
156
158
|
if (opts.optimizeQuality && opts.optimizeQuality > 0) payload.optimize_quality = Math.trunc(opts.optimizeQuality);
|
|
157
|
-
if (opts.optimizeFormat === 'avif') payload.optimize_format = 'avif';
|
|
158
159
|
if (opts.optimizeKeepOriginal !== undefined) payload.optimize_keep_original = !!opts.optimizeKeepOriginal;
|
|
159
160
|
if (opts.optimizeMaxMb && opts.optimizeMaxMb > 0) payload.optimize_max_mb = Math.trunc(opts.optimizeMaxMb);
|
|
160
161
|
if (opts.pdfLevel && ['screen', 'ebook', 'printer', 'prepress', 'default'].includes(opts.pdfLevel)) {
|
|
@@ -185,6 +186,11 @@ function applyTenantOverrides(payload: Record<string, unknown>, opts: BaseTokenO
|
|
|
185
186
|
if (opts.usageCriticalThreshold && opts.usageCriticalThreshold > 0) payload.usage_critical_threshold = Math.trunc(opts.usageCriticalThreshold);
|
|
186
187
|
if (opts.usageTopFoldersCount && opts.usageTopFoldersCount > 0) payload.usage_top_folders_count = Math.trunc(opts.usageTopFoldersCount);
|
|
187
188
|
if (opts.usageFolderDepth && opts.usageFolderDepth > 0) payload.usage_folder_depth = Math.trunc(opts.usageFolderDepth);
|
|
189
|
+
|
|
190
|
+
// Generic escape hatch: ANY claim by its raw (snake_case) name. Merged last so an
|
|
191
|
+
// explicit claim wins over a preset/group default. The server sanitizes on decode.
|
|
192
|
+
// See docs/CONFIG.md for the full claim list.
|
|
193
|
+
if (opts.claims) for (const [k, v] of Object.entries(opts.claims)) if (v !== undefined && v !== null) payload[k] = v;
|
|
188
194
|
}
|
|
189
195
|
|
|
190
196
|
/**
|
package/src/types.ts
CHANGED
|
@@ -104,17 +104,20 @@ export interface BaseTokenOptions {
|
|
|
104
104
|
* access as the SSH user, so it's opt-in. Core-standalone: the token must target a real core
|
|
105
105
|
* (this SDK does), not a proxy adapter that doesn't serve /api/fm/terminal. */
|
|
106
106
|
allowTerminal?: boolean;
|
|
107
|
-
/**
|
|
108
|
-
*
|
|
107
|
+
/** Optional self-hosted PTY terminal URL (ttyd / gotty / wetty, or any PTY-over-WebSocket
|
|
108
|
+
* server the operator runs). When set (and `allowTerminal` is true), the UI embeds it for a
|
|
109
|
+
* true interactive terminal instead of the built-in command-runner. Free; must be http(s).
|
|
110
|
+
* Core-standalone only (like `allowTerminal`). */
|
|
111
|
+
terminalPtyUrl?: string;
|
|
112
|
+
/** Allow the Optimization feature (POST /api/fm/optimize) — recompress images to WebP +
|
|
113
|
+
* compress PDFs. **Free/core**; default **false** because it replaces/deletes originals, so
|
|
114
|
+
* it's an opt-in capability. */
|
|
109
115
|
allowOptimize?: boolean;
|
|
110
|
-
/** Auto-optimize images on upload (recompress to WebP in the pipeline). Default false
|
|
111
|
-
*
|
|
116
|
+
/** Auto-optimize images on upload (recompress to WebP in the pipeline). Default false.
|
|
117
|
+
* Free/core. */
|
|
112
118
|
autoOptimize?: boolean;
|
|
113
119
|
/** WebP quality for optimization, 40–95. `0`/omitted = inherit the server default (82). */
|
|
114
120
|
optimizeQuality?: number;
|
|
115
|
-
/** Target format for optimization: `'webp'` (default) or `'avif'` (falls back to
|
|
116
|
-
* WebP when the server build lacks AVIF). */
|
|
117
|
-
optimizeFormat?: 'webp' | 'avif';
|
|
118
121
|
/** Keep the original file when optimizing (default false = replace in place). */
|
|
119
122
|
optimizeKeepOriginal?: boolean;
|
|
120
123
|
/** Skip optimizing a file larger than this many MB (0/omitted = no limit). */
|
|
@@ -138,6 +141,7 @@ export interface BaseTokenOptions {
|
|
|
138
141
|
/** Paid-module claims (3-layer gate: code installed + licensed + this claim).
|
|
139
142
|
* All default off; inert unless the module is installed & licensed on the server. */
|
|
140
143
|
allowShare?: boolean;
|
|
144
|
+
allowIntake?: boolean;
|
|
141
145
|
allowAiVision?: boolean;
|
|
142
146
|
allowOcr?: boolean;
|
|
143
147
|
allowVirusScan?: boolean;
|
|
@@ -175,6 +179,11 @@ export interface BaseTokenOptions {
|
|
|
175
179
|
usageTopFoldersCount?: number;
|
|
176
180
|
/** Folder grouping depth for the usage breakdown. `0`/omitted = inherit (1). */
|
|
177
181
|
usageFolderDepth?: number;
|
|
182
|
+
/** Generic escape hatch: any JWT claim by its raw snake_case name (e.g.
|
|
183
|
+
* `{ allow_terminal: true, terminal_pty_url: '…', upload_collision: 'overwrite' }`).
|
|
184
|
+
* Merged last so explicit claims win; the server sanitizes on decode. The single
|
|
185
|
+
* place to set claims that don't have a typed option here. See docs/CONFIG.md. */
|
|
186
|
+
claims?: Record<string, unknown>;
|
|
178
187
|
}
|
|
179
188
|
|
|
180
189
|
export interface CreateTokenOptions extends BaseTokenOptions {
|