@fluxfiles/node 0.1.2 → 0.1.4
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 +20 -0
- package/dist/index.d.mts +19 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.js +12 -0
- package/dist/index.mjs +12 -0
- package/package.json +3 -2
- package/src/token.ts +16 -0
- package/src/types.ts +19 -0
package/README.md
CHANGED
|
@@ -48,6 +48,26 @@ const token = createToken({
|
|
|
48
48
|
});
|
|
49
49
|
```
|
|
50
50
|
|
|
51
|
+
### Enable Import from URL
|
|
52
|
+
|
|
53
|
+
Import-from-URL is **off by default**. Turn it on for a token by setting the
|
|
54
|
+
import options — no server-side per-tenant config is needed:
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
const token = createToken({
|
|
58
|
+
userId: 'user-42',
|
|
59
|
+
perms: ['read', 'write'],
|
|
60
|
+
allowUrlImport: true, // required — enables the feature
|
|
61
|
+
maxImportMb: 20, // optional — cap per import (MB)
|
|
62
|
+
importUrlAllowlist: ['*.unsplash.com'], // optional — restrict source hosts
|
|
63
|
+
// importPath, importRateLimit, importConcurrency also supported
|
|
64
|
+
});
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
The core then accepts `POST /api/fm/import-url` for that token (SSRF-guarded,
|
|
68
|
+
sharing the quota/dedup/variants pipeline). Server-wide defaults come from
|
|
69
|
+
`FLUXFILES_IMPORT_*` env vars on the core service.
|
|
70
|
+
|
|
51
71
|
### BYOB — encrypt a user's own bucket credentials
|
|
52
72
|
|
|
53
73
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -41,6 +41,25 @@ interface BaseTokenOptions {
|
|
|
41
41
|
rateWrite?: number;
|
|
42
42
|
/** Per-tenant image variant widths, e.g. `{ thumb: 150, medium: 768, large: 1920 }`. Omit to inherit. */
|
|
43
43
|
variants?: Partial<Record<'thumb' | 'medium' | 'large', number>> | null;
|
|
44
|
+
/** Enable Import-from-URL for this tenant (`POST /api/fm/import-url`). Default off. */
|
|
45
|
+
allowUrlImport?: boolean;
|
|
46
|
+
/** Max size per URL import, in MB (same unit as `maxUploadMb`). `0`/omitted = inherit (50). */
|
|
47
|
+
maxImportMb?: number;
|
|
48
|
+
/** Restrict imports to these host globs, e.g. `['*.unsplash.com']`. Omit = any public host. */
|
|
49
|
+
importUrlAllowlist?: string[];
|
|
50
|
+
/** Force imports into this path, ignoring the request path. */
|
|
51
|
+
importPath?: string;
|
|
52
|
+
/** Import-specific rate limit (req/min) and max concurrent imports. `0`/omitted = inherit. */
|
|
53
|
+
importRateLimit?: number;
|
|
54
|
+
importConcurrency?: number;
|
|
55
|
+
/** Enable inline video/audio preview for this tenant. Omit to inherit the default (true). */
|
|
56
|
+
mediaPreview?: boolean;
|
|
57
|
+
/** Presigned media-URL TTL (seconds) — longer so a long video doesn't expire mid-play. `0`/omitted = inherit (7200). */
|
|
58
|
+
previewUrlTtl?: number;
|
|
59
|
+
/** Max file size (MB) eligible for inline preview; larger media shows a download placeholder. `0`/omitted = inherit (500). */
|
|
60
|
+
maxPreviewMb?: number;
|
|
61
|
+
/** TTL (seconds) for per-file gated-local stream tokens. `0`/omitted = inherit (3600). */
|
|
62
|
+
streamTokenTtl?: number;
|
|
44
63
|
}
|
|
45
64
|
interface CreateTokenOptions extends BaseTokenOptions {
|
|
46
65
|
/** Disk names the token may access. */
|
package/dist/index.d.ts
CHANGED
|
@@ -41,6 +41,25 @@ interface BaseTokenOptions {
|
|
|
41
41
|
rateWrite?: number;
|
|
42
42
|
/** Per-tenant image variant widths, e.g. `{ thumb: 150, medium: 768, large: 1920 }`. Omit to inherit. */
|
|
43
43
|
variants?: Partial<Record<'thumb' | 'medium' | 'large', number>> | null;
|
|
44
|
+
/** Enable Import-from-URL for this tenant (`POST /api/fm/import-url`). Default off. */
|
|
45
|
+
allowUrlImport?: boolean;
|
|
46
|
+
/** Max size per URL import, in MB (same unit as `maxUploadMb`). `0`/omitted = inherit (50). */
|
|
47
|
+
maxImportMb?: number;
|
|
48
|
+
/** Restrict imports to these host globs, e.g. `['*.unsplash.com']`. Omit = any public host. */
|
|
49
|
+
importUrlAllowlist?: string[];
|
|
50
|
+
/** Force imports into this path, ignoring the request path. */
|
|
51
|
+
importPath?: string;
|
|
52
|
+
/** Import-specific rate limit (req/min) and max concurrent imports. `0`/omitted = inherit. */
|
|
53
|
+
importRateLimit?: number;
|
|
54
|
+
importConcurrency?: number;
|
|
55
|
+
/** Enable inline video/audio preview for this tenant. Omit to inherit the default (true). */
|
|
56
|
+
mediaPreview?: boolean;
|
|
57
|
+
/** Presigned media-URL TTL (seconds) — longer so a long video doesn't expire mid-play. `0`/omitted = inherit (7200). */
|
|
58
|
+
previewUrlTtl?: number;
|
|
59
|
+
/** Max file size (MB) eligible for inline preview; larger media shows a download placeholder. `0`/omitted = inherit (500). */
|
|
60
|
+
maxPreviewMb?: number;
|
|
61
|
+
/** TTL (seconds) for per-file gated-local stream tokens. `0`/omitted = inherit (3600). */
|
|
62
|
+
streamTokenTtl?: number;
|
|
44
63
|
}
|
|
45
64
|
interface CreateTokenOptions extends BaseTokenOptions {
|
|
46
65
|
/** Disk names the token may access. */
|
package/dist/index.js
CHANGED
|
@@ -142,6 +142,18 @@ function applyTenantOverrides(payload, opts) {
|
|
|
142
142
|
if (opts.rateWrite && opts.rateWrite > 0) payload.rate_write = Math.trunc(opts.rateWrite);
|
|
143
143
|
const variants = sanitizeVariants(opts.variants);
|
|
144
144
|
if (variants) payload.variants = variants;
|
|
145
|
+
if (opts.allowUrlImport) payload.allow_url_import = true;
|
|
146
|
+
if (opts.maxImportMb && opts.maxImportMb > 0) payload.max_import_mb = Math.trunc(opts.maxImportMb);
|
|
147
|
+
if (opts.importRateLimit && opts.importRateLimit > 0) payload.import_rate_limit = Math.trunc(opts.importRateLimit);
|
|
148
|
+
if (opts.importConcurrency && opts.importConcurrency > 0) payload.import_concurrency = Math.trunc(opts.importConcurrency);
|
|
149
|
+
if (opts.importPath) payload.import_path = String(opts.importPath);
|
|
150
|
+
if (Array.isArray(opts.importUrlAllowlist) && opts.importUrlAllowlist.length) {
|
|
151
|
+
payload.import_url_allowlist = opts.importUrlAllowlist.map((h) => String(h));
|
|
152
|
+
}
|
|
153
|
+
if (opts.mediaPreview !== void 0) payload.media_preview = !!opts.mediaPreview;
|
|
154
|
+
if (opts.previewUrlTtl && opts.previewUrlTtl > 0) payload.preview_url_ttl = Math.trunc(opts.previewUrlTtl);
|
|
155
|
+
if (opts.maxPreviewMb && opts.maxPreviewMb > 0) payload.max_preview_mb = Math.trunc(opts.maxPreviewMb);
|
|
156
|
+
if (opts.streamTokenTtl && opts.streamTokenTtl > 0) payload.stream_token_ttl = Math.trunc(opts.streamTokenTtl);
|
|
145
157
|
}
|
|
146
158
|
function validateByobDisk(name, config) {
|
|
147
159
|
if (!config || config.driver !== "s3") {
|
package/dist/index.mjs
CHANGED
|
@@ -120,6 +120,18 @@ function applyTenantOverrides(payload, opts) {
|
|
|
120
120
|
if (opts.rateWrite && opts.rateWrite > 0) payload.rate_write = Math.trunc(opts.rateWrite);
|
|
121
121
|
const variants = sanitizeVariants(opts.variants);
|
|
122
122
|
if (variants) payload.variants = variants;
|
|
123
|
+
if (opts.allowUrlImport) payload.allow_url_import = true;
|
|
124
|
+
if (opts.maxImportMb && opts.maxImportMb > 0) payload.max_import_mb = Math.trunc(opts.maxImportMb);
|
|
125
|
+
if (opts.importRateLimit && opts.importRateLimit > 0) payload.import_rate_limit = Math.trunc(opts.importRateLimit);
|
|
126
|
+
if (opts.importConcurrency && opts.importConcurrency > 0) payload.import_concurrency = Math.trunc(opts.importConcurrency);
|
|
127
|
+
if (opts.importPath) payload.import_path = String(opts.importPath);
|
|
128
|
+
if (Array.isArray(opts.importUrlAllowlist) && opts.importUrlAllowlist.length) {
|
|
129
|
+
payload.import_url_allowlist = opts.importUrlAllowlist.map((h) => String(h));
|
|
130
|
+
}
|
|
131
|
+
if (opts.mediaPreview !== void 0) payload.media_preview = !!opts.mediaPreview;
|
|
132
|
+
if (opts.previewUrlTtl && opts.previewUrlTtl > 0) payload.preview_url_ttl = Math.trunc(opts.previewUrlTtl);
|
|
133
|
+
if (opts.maxPreviewMb && opts.maxPreviewMb > 0) payload.max_preview_mb = Math.trunc(opts.maxPreviewMb);
|
|
134
|
+
if (opts.streamTokenTtl && opts.streamTokenTtl > 0) payload.stream_token_ttl = Math.trunc(opts.streamTokenTtl);
|
|
123
135
|
}
|
|
124
136
|
function validateByobDisk(name, config) {
|
|
125
137
|
if (!config || config.driver !== "s3") {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluxfiles/node",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.4",
|
|
4
4
|
"description": "Server-side Node/TypeScript SDK for minting FluxFiles JWTs (plain + BYOB), byte-compatible with the PHP core",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -16,7 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
|
-
"src"
|
|
19
|
+
"src",
|
|
20
|
+
"LICENSE"
|
|
20
21
|
],
|
|
21
22
|
"engines": {
|
|
22
23
|
"node": ">=16"
|
package/src/token.ts
CHANGED
|
@@ -104,6 +104,22 @@ function applyTenantOverrides(payload: Record<string, unknown>, opts: BaseTokenO
|
|
|
104
104
|
if (opts.rateWrite && opts.rateWrite > 0) payload.rate_write = Math.trunc(opts.rateWrite);
|
|
105
105
|
const variants = sanitizeVariants(opts.variants);
|
|
106
106
|
if (variants) payload.variants = variants;
|
|
107
|
+
|
|
108
|
+
// URL-import claims (the server sanitizes/clamps these on decode).
|
|
109
|
+
if (opts.allowUrlImport) payload.allow_url_import = true;
|
|
110
|
+
if (opts.maxImportMb && opts.maxImportMb > 0) payload.max_import_mb = Math.trunc(opts.maxImportMb);
|
|
111
|
+
if (opts.importRateLimit && opts.importRateLimit > 0) payload.import_rate_limit = Math.trunc(opts.importRateLimit);
|
|
112
|
+
if (opts.importConcurrency && opts.importConcurrency > 0) payload.import_concurrency = Math.trunc(opts.importConcurrency);
|
|
113
|
+
if (opts.importPath) payload.import_path = String(opts.importPath);
|
|
114
|
+
if (Array.isArray(opts.importUrlAllowlist) && opts.importUrlAllowlist.length) {
|
|
115
|
+
payload.import_url_allowlist = opts.importUrlAllowlist.map((h) => String(h));
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// Media-preview claims (the server sanitizes/clamps these on decode).
|
|
119
|
+
if (opts.mediaPreview !== undefined) payload.media_preview = !!opts.mediaPreview;
|
|
120
|
+
if (opts.previewUrlTtl && opts.previewUrlTtl > 0) payload.preview_url_ttl = Math.trunc(opts.previewUrlTtl);
|
|
121
|
+
if (opts.maxPreviewMb && opts.maxPreviewMb > 0) payload.max_preview_mb = Math.trunc(opts.maxPreviewMb);
|
|
122
|
+
if (opts.streamTokenTtl && opts.streamTokenTtl > 0) payload.stream_token_ttl = Math.trunc(opts.streamTokenTtl);
|
|
107
123
|
}
|
|
108
124
|
|
|
109
125
|
/**
|
package/src/types.ts
CHANGED
|
@@ -43,6 +43,25 @@ export interface BaseTokenOptions {
|
|
|
43
43
|
rateWrite?: number;
|
|
44
44
|
/** Per-tenant image variant widths, e.g. `{ thumb: 150, medium: 768, large: 1920 }`. Omit to inherit. */
|
|
45
45
|
variants?: Partial<Record<'thumb' | 'medium' | 'large', number>> | null;
|
|
46
|
+
/** Enable Import-from-URL for this tenant (`POST /api/fm/import-url`). Default off. */
|
|
47
|
+
allowUrlImport?: boolean;
|
|
48
|
+
/** Max size per URL import, in MB (same unit as `maxUploadMb`). `0`/omitted = inherit (50). */
|
|
49
|
+
maxImportMb?: number;
|
|
50
|
+
/** Restrict imports to these host globs, e.g. `['*.unsplash.com']`. Omit = any public host. */
|
|
51
|
+
importUrlAllowlist?: string[];
|
|
52
|
+
/** Force imports into this path, ignoring the request path. */
|
|
53
|
+
importPath?: string;
|
|
54
|
+
/** Import-specific rate limit (req/min) and max concurrent imports. `0`/omitted = inherit. */
|
|
55
|
+
importRateLimit?: number;
|
|
56
|
+
importConcurrency?: number;
|
|
57
|
+
/** Enable inline video/audio preview for this tenant. Omit to inherit the default (true). */
|
|
58
|
+
mediaPreview?: boolean;
|
|
59
|
+
/** Presigned media-URL TTL (seconds) — longer so a long video doesn't expire mid-play. `0`/omitted = inherit (7200). */
|
|
60
|
+
previewUrlTtl?: number;
|
|
61
|
+
/** Max file size (MB) eligible for inline preview; larger media shows a download placeholder. `0`/omitted = inherit (500). */
|
|
62
|
+
maxPreviewMb?: number;
|
|
63
|
+
/** TTL (seconds) for per-file gated-local stream tokens. `0`/omitted = inherit (3600). */
|
|
64
|
+
streamTokenTtl?: number;
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
export interface CreateTokenOptions extends BaseTokenOptions {
|