@fluxfiles/node 0.1.2 → 0.1.3

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 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,17 @@ 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;
44
55
  }
45
56
  interface CreateTokenOptions extends BaseTokenOptions {
46
57
  /** Disk names the token may access. */
package/dist/index.d.ts CHANGED
@@ -41,6 +41,17 @@ 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;
44
55
  }
45
56
  interface CreateTokenOptions extends BaseTokenOptions {
46
57
  /** Disk names the token may access. */
package/dist/index.js CHANGED
@@ -142,6 +142,14 @@ 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
+ }
145
153
  }
146
154
  function validateByobDisk(name, config) {
147
155
  if (!config || config.driver !== "s3") {
package/dist/index.mjs CHANGED
@@ -120,6 +120,14 @@ 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
+ }
123
131
  }
124
132
  function validateByobDisk(name, config) {
125
133
  if (!config || config.driver !== "s3") {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fluxfiles/node",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
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,16 @@ 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
+ }
107
117
  }
108
118
 
109
119
  /**
package/src/types.ts CHANGED
@@ -43,6 +43,17 @@ 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;
46
57
  }
47
58
 
48
59
  export interface CreateTokenOptions extends BaseTokenOptions {