@kumwe/studio-media 0.1.0-alpha.2 → 0.1.0-alpha.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/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/upload-policy.d.ts +35 -0
- package/dist/upload-policy.d.ts.map +1 -0
- package/dist/upload-policy.js +71 -0
- package/dist/upload-policy.js.map +1 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { MediaLibrary, MEDIA_PROVIDER_FAILURE, selectBestRendition, type MediaLibraryListener, type MediaLibraryState, type MediaLibraryStatus, type MediaProvider, type MediaUploadRequest, } from './media-library.js';
|
|
2
2
|
export { MediaUploadController, MEDIA_UPLOAD_FAILURE, MEDIA_UPLOAD_TOO_LARGE, type MediaUploadChunk, type MediaUploadControllerOptions, type MediaUploadListener, type MediaUploadTransport, } from './upload-controller.js';
|
|
3
|
+
export { evaluateUploadPolicy, planFromPolicy, type MediaUploadPolicy, type MediaUploadPolicyDecision, } from './upload-policy.js';
|
|
3
4
|
export { validateMediaReference } from './validate-media-reference.js';
|
|
4
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,kBAAkB,EACvB,KAAK,aAAa,EAClB,KAAK,kBAAkB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,EACtB,KAAK,gBAAgB,EACrB,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,GAC1B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,KAAK,iBAAiB,EACtB,KAAK,yBAAyB,GAC/B,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export { MediaLibrary, MEDIA_PROVIDER_FAILURE, selectBestRendition, } from './media-library.js';
|
|
2
2
|
export { MediaUploadController, MEDIA_UPLOAD_FAILURE, MEDIA_UPLOAD_TOO_LARGE, } from './upload-controller.js';
|
|
3
|
+
export { evaluateUploadPolicy, planFromPolicy, } from './upload-policy.js';
|
|
3
4
|
export { validateMediaReference } from './validate-media-reference.js';
|
|
4
5
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,GAMpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,GAKvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,GAMpB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACpB,sBAAsB,GAKvB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,cAAc,GAGf,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,sBAAsB,EAAE,MAAM,+BAA+B,CAAC"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { MediaUploadPlan, MediaUploadRequestDescriptor, StudioDiagnostic } from '@kumwe/studio-protocol';
|
|
2
|
+
/**
|
|
3
|
+
* The host-declared upload policy: the bounded upload plan the host grants
|
|
4
|
+
* (`MediaUploadPlan`) plus the declared media types it accepts. This is the
|
|
5
|
+
* policy shape the canonical vectors in `schemas/vectors/media/` fix; the
|
|
6
|
+
* host remains authoritative and re-verifies everything server-side.
|
|
7
|
+
*/
|
|
8
|
+
export interface MediaUploadPolicy {
|
|
9
|
+
acceptedMediaTypes: readonly string[];
|
|
10
|
+
chunkBytes?: number;
|
|
11
|
+
maximumBytes: number;
|
|
12
|
+
resumable: boolean;
|
|
13
|
+
}
|
|
14
|
+
export type MediaUploadPolicyDecision = {
|
|
15
|
+
failure: StudioDiagnostic;
|
|
16
|
+
outcome: 'rejected';
|
|
17
|
+
} | {
|
|
18
|
+
outcome: 'accepted';
|
|
19
|
+
plan: MediaUploadPlan;
|
|
20
|
+
};
|
|
21
|
+
/** The deterministic upload plan a policy grants, independent of any request. */
|
|
22
|
+
export declare function planFromPolicy(policy: MediaUploadPolicy): MediaUploadPlan;
|
|
23
|
+
/**
|
|
24
|
+
* Evaluates one upload request against a host-declared policy, in the fixed
|
|
25
|
+
* order filename, media type, size. Rejections use the closed media failure
|
|
26
|
+
* vocabulary: an oversize request fails with `studio.media/upload-too-large`
|
|
27
|
+
* carrying the byte counts only as machine-readable diagnostic parameters
|
|
28
|
+
* (the exact diagnostic `MediaUploadController` raises at the same boundary),
|
|
29
|
+
* and every other violation fails with the generic
|
|
30
|
+
* `studio.media/upload-failed` — user-facing messages never echo the raw
|
|
31
|
+
* size, media type, or filename. The canonical corpus in
|
|
32
|
+
* `schemas/vectors/media/` replays this decision.
|
|
33
|
+
*/
|
|
34
|
+
export declare function evaluateUploadPolicy(policy: MediaUploadPolicy, request: MediaUploadRequestDescriptor): MediaUploadPolicyDecision;
|
|
35
|
+
//# sourceMappingURL=upload-policy.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-policy.d.ts","sourceRoot":"","sources":["../src/upload-policy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,eAAe,EACf,4BAA4B,EAC5B,gBAAgB,EACjB,MAAM,wBAAwB,CAAC;AAGhC;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,kBAAkB,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,yBAAyB,GACjC;IAAE,OAAO,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,UAAU,CAAA;CAAE,GAClD;IAAE,OAAO,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,eAAe,CAAA;CAAE,CAAC;AAEnD,iFAAiF;AACjF,wBAAgB,cAAc,CAAC,MAAM,EAAE,iBAAiB,GAAG,eAAe,CASzE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE,4BAA4B,GACpC,yBAAyB,CA4B3B"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { MEDIA_UPLOAD_FAILURE, MEDIA_UPLOAD_TOO_LARGE } from './upload-controller.js';
|
|
2
|
+
/** The deterministic upload plan a policy grants, independent of any request. */
|
|
3
|
+
export function planFromPolicy(policy) {
|
|
4
|
+
const plan = {
|
|
5
|
+
maximumBytes: policy.maximumBytes,
|
|
6
|
+
resumable: policy.resumable,
|
|
7
|
+
};
|
|
8
|
+
if (policy.chunkBytes !== undefined) {
|
|
9
|
+
plan.chunkBytes = policy.chunkBytes;
|
|
10
|
+
}
|
|
11
|
+
return plan;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Evaluates one upload request against a host-declared policy, in the fixed
|
|
15
|
+
* order filename, media type, size. Rejections use the closed media failure
|
|
16
|
+
* vocabulary: an oversize request fails with `studio.media/upload-too-large`
|
|
17
|
+
* carrying the byte counts only as machine-readable diagnostic parameters
|
|
18
|
+
* (the exact diagnostic `MediaUploadController` raises at the same boundary),
|
|
19
|
+
* and every other violation fails with the generic
|
|
20
|
+
* `studio.media/upload-failed` — user-facing messages never echo the raw
|
|
21
|
+
* size, media type, or filename. The canonical corpus in
|
|
22
|
+
* `schemas/vectors/media/` replays this decision.
|
|
23
|
+
*/
|
|
24
|
+
export function evaluateUploadPolicy(policy, request) {
|
|
25
|
+
if (!isCanonicalFilename(request.filename) ||
|
|
26
|
+
!policy.acceptedMediaTypes.includes(request.mediaType) ||
|
|
27
|
+
!Number.isInteger(request.byteSize) ||
|
|
28
|
+
request.byteSize < 1) {
|
|
29
|
+
return {
|
|
30
|
+
failure: {
|
|
31
|
+
code: 'studio.media/upload-failed',
|
|
32
|
+
message: { ...MEDIA_UPLOAD_FAILURE },
|
|
33
|
+
severity: 'error',
|
|
34
|
+
},
|
|
35
|
+
outcome: 'rejected',
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
if (request.byteSize > policy.maximumBytes) {
|
|
39
|
+
return {
|
|
40
|
+
failure: {
|
|
41
|
+
code: 'studio.media/upload-too-large',
|
|
42
|
+
message: { ...MEDIA_UPLOAD_TOO_LARGE },
|
|
43
|
+
parameters: { byteSize: request.byteSize, maximumBytes: policy.maximumBytes },
|
|
44
|
+
severity: 'error',
|
|
45
|
+
},
|
|
46
|
+
outcome: 'rejected',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
return { outcome: 'accepted', plan: planFromPolicy(policy) };
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Mirrors the filename rule of `media-upload-session.schema.json`: one to 255
|
|
53
|
+
* code points, no C0 control characters, no DEL, and no path separators —
|
|
54
|
+
* per the media contract, filenames are display metadata, never storage
|
|
55
|
+
* paths.
|
|
56
|
+
*/
|
|
57
|
+
function isCanonicalFilename(filename) {
|
|
58
|
+
let length = 0;
|
|
59
|
+
for (const character of filename) {
|
|
60
|
+
length += 1;
|
|
61
|
+
if (length > 255) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const codePoint = character.codePointAt(0) ?? 0;
|
|
65
|
+
if (codePoint <= 0x1f || codePoint === 0x7f || character === '/' || character === '\\') {
|
|
66
|
+
return false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return length >= 1;
|
|
70
|
+
}
|
|
71
|
+
//# sourceMappingURL=upload-policy.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-policy.js","sourceRoot":"","sources":["../src/upload-policy.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,oBAAoB,EAAE,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAmBtF,iFAAiF;AACjF,MAAM,UAAU,cAAc,CAAC,MAAyB;IACtD,MAAM,IAAI,GAAoB;QAC5B,YAAY,EAAE,MAAM,CAAC,YAAY;QACjC,SAAS,EAAE,MAAM,CAAC,SAAS;KAC5B,CAAC;IACF,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC;IACtC,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAAyB,EACzB,OAAqC;IAErC,IACE,CAAC,mBAAmB,CAAC,OAAO,CAAC,QAAQ,CAAC;QACtC,CAAC,MAAM,CAAC,kBAAkB,CAAC,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QACtD,CAAC,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC;QACnC,OAAO,CAAC,QAAQ,GAAG,CAAC,EACpB,CAAC;QACD,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EAAE,4BAA4B;gBAClC,OAAO,EAAE,EAAE,GAAG,oBAAoB,EAAE;gBACpC,QAAQ,EAAE,OAAO;aAClB;YACD,OAAO,EAAE,UAAU;SACpB,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,GAAG,MAAM,CAAC,YAAY,EAAE,CAAC;QAC3C,OAAO;YACL,OAAO,EAAE;gBACP,IAAI,EAAE,+BAA+B;gBACrC,OAAO,EAAE,EAAE,GAAG,sBAAsB,EAAE;gBACtC,UAAU,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE;gBAC7E,QAAQ,EAAE,OAAO;aAClB;YACD,OAAO,EAAE,UAAU;SACpB,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC;AAC/D,CAAC;AAED;;;;;GAKG;AACH,SAAS,mBAAmB,CAAC,QAAgB;IAC3C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,KAAK,MAAM,SAAS,IAAI,QAAQ,EAAE,CAAC;QACjC,MAAM,IAAI,CAAC,CAAC;QACZ,IAAI,MAAM,GAAG,GAAG,EAAE,CAAC;YACjB,OAAO,KAAK,CAAC;QACf,CAAC;QACD,MAAM,SAAS,GAAG,SAAS,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;QAChD,IAAI,SAAS,IAAI,IAAI,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,GAAG,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YACvF,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;IACD,OAAO,MAAM,IAAI,CAAC,CAAC;AACrB,CAAC"}
|