@coppsary/motionly 1.1.2 → 1.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
@@ -11,14 +11,18 @@
11
11
  </p>
12
12
 
13
13
  <p align="center">
14
- <img src="https://img.shields.io/badge/TypeScript-5.7-3178C6?style=flat&logo=typescript&logoColor=white" alt="TypeScript">
15
- <img src="https://img.shields.io/badge/Svelte-5.56-FF3E00?style=flat&logo=svelte&logoColor=white" alt="Svelte">
16
- <img src="https://img.shields.io/badge/Canvas-2D_Renderer-E34F26?style=flat&logo=html5&logoColor=white" alt="Canvas">
17
- <img src="https://img.shields.io/badge/GSAP-3.15-0AE448?style=flat&logo=greensock&logoColor=white" alt="GSAP">
18
- <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue?style=flat" alt="License"></a>
19
- <br>
14
+ <a href="https://www.producthunt.com/products/motionly">
15
+ <img src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1202670&theme=dark" alt="Motionly on Product Hunt" height="54" />
16
+ </a>
17
+ </p>
18
+
19
+ <p align="center">
20
+ <a href="https://www.npmjs.com/package/@coppsary/motionly">
21
+ <img src="https://img.shields.io/npm/dm/%40coppsary%2Fmotionly?style=flat&logo=npm&logoColor=white" alt="npm Downloads">
22
+ </a>
20
23
  <a href="https://motionly.mintlify.app/"><img src="https://img.shields.io/badge/Docs-Mintlify-7C3AED?style=flat" alt="Documentation"></a>
21
24
  <a href="https://github.com/COPPSARY/Motionly"><img src="https://img.shields.io/github/stars/COPPSARY/Motionly?style=flat" alt="GitHub Stars"></a>
25
+ <a href="LICENSE"><img src="https://img.shields.io/badge/License-Apache_2.0-blue?style=flat" alt="License"></a>
22
26
  </p>
23
27
 
24
28
  <p align="center">
package/bin/motionly.js CHANGED
@@ -308,6 +308,17 @@ async function readRequestBody(request, maximum = 5_000_000) {
308
308
  return source;
309
309
  }
310
310
 
311
+ async function readRequestBuffer(request, maximum = 200_000_000) {
312
+ const chunks = [];
313
+ let total = 0;
314
+ for await (const chunk of request) {
315
+ total += chunk.length;
316
+ if (total > maximum) throw new Error('TOO_LARGE');
317
+ chunks.push(chunk);
318
+ }
319
+ return Buffer.concat(chunks);
320
+ }
321
+
311
322
  function safeFile(rootPath, pathname) {
312
323
  const filePath = normalize(join(rootPath, pathname));
313
324
  return filePath === rootPath || filePath.startsWith(`${rootPath}${sep}`) ? filePath : null;
@@ -371,7 +382,7 @@ async function serveEditor(argv, projectFolder = null) {
371
382
  return;
372
383
  }
373
384
 
374
- if (pathname.startsWith('/assets/')) {
385
+ if (pathname.startsWith('/assets/') && (request.method === 'GET' || request.method === 'HEAD')) {
375
386
  const bundledAsset = safeFile(dist, pathname.slice(1));
376
387
  if (bundledAsset && (await exists(bundledAsset))) {
377
388
  await serveFile(response, bundledAsset, request.method);
@@ -381,10 +392,19 @@ async function serveEditor(argv, projectFolder = null) {
381
392
 
382
393
  if (assetsRoot && pathname.startsWith('/assets/')) {
383
394
  const filePath = safeFile(assetsRoot, pathname.slice('/assets/'.length));
384
- if (!filePath) {
395
+ if (!filePath || filePath === assetsRoot) {
385
396
  response.writeHead(403).end('Forbidden');
386
397
  return;
387
398
  }
399
+ if (request.method === 'PUT') {
400
+ // Save an uploaded/dragged asset into the project's on-disk assets folder
401
+ // so it can be reused, edited, or deleted like any other project media.
402
+ const data = await readRequestBuffer(request);
403
+ await mkdir(dirname(filePath), { recursive: true });
404
+ await writeFile(filePath, data);
405
+ response.writeHead(204, { 'X-Motionly-Asset': basename(filePath) }).end();
406
+ return;
407
+ }
388
408
  await serveFile(response, filePath, request.method);
389
409
  return;
390
410
  }
@@ -408,7 +428,7 @@ async function serveEditor(argv, projectFolder = null) {
408
428
  });
409
429
 
410
430
  server.listen(port, () => {
411
- const url = `http://localhost:${port}${projectRoot ? '/editor' : ''}`;
431
+ const url = `http://localhost:${port}`;
412
432
  console.log(
413
433
  `\n Motionly is running.\n Open this URL in your browser: ${url}${projectRoot ? `\n Project: ${projectRoot}` : ''}\n Press Ctrl+C to stop.\n`
414
434
  );