@jay-framework/fullstack-component 0.16.0 → 0.16.2

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 CHANGED
@@ -445,6 +445,34 @@ type ServiceResolver = (markers: any[]) => any[];
445
445
  declare global {
446
446
  var __JAY_SERVICE_RESOLVER__: ServiceResolver | undefined;
447
447
  }
448
+ /**
449
+ * Represents a file in a Jay action.
450
+ *
451
+ * On the **client**, browser `File` and `Blob` objects are assignable to this type
452
+ * (they have `name`, `type`, `size`). The framework converts them to FormData automatically.
453
+ *
454
+ * On the **server**, the framework populates `path` with a temp file location.
455
+ * The temp file is cleaned up after the handler returns.
456
+ */
457
+ interface JayFile {
458
+ /** Original filename */
459
+ name: string;
460
+ /** MIME type */
461
+ type: string;
462
+ /** File size in bytes */
463
+ size: number;
464
+ /** Absolute path to the temp file on disk (server-side only, always present in handlers) */
465
+ path?: string;
466
+ }
467
+ /**
468
+ * Options for file upload support.
469
+ */
470
+ interface FileUploadOptions {
471
+ /** Maximum file size in bytes (default: 10MB) */
472
+ maxFileSize?: number;
473
+ /** Maximum number of files (default: 10) */
474
+ maxFiles?: number;
475
+ }
448
476
  /**
449
477
  * Supported HTTP methods for actions and queries.
450
478
  */
@@ -499,6 +527,10 @@ interface JayActionDefinition<Input, Output, Services extends any[]> {
499
527
  cacheOptions?: CacheOptions;
500
528
  /** Service markers for dependency injection */
501
529
  services: ServiceMarkers<Services>;
530
+ /** Whether this action accepts file uploads (DL#131) */
531
+ acceptsFiles?: boolean;
532
+ /** File upload options (DL#131) */
533
+ fileOptions?: FileUploadOptions;
502
534
  /** The handler function */
503
535
  handler: (input: Input, ...services: Services) => Promise<Output>;
504
536
  }
@@ -518,6 +550,11 @@ interface JayActionBuilder<Services extends any[], Input, Output, DefaultMethod
518
550
  * Enable caching (typically for GET requests).
519
551
  */
520
552
  withCaching(options?: CacheOptions): JayActionBuilder<Services, Input, Output, DefaultMethod>;
553
+ /**
554
+ * Mark this action as accepting file uploads (DL#131).
555
+ * The handler will receive JayFile objects for file fields.
556
+ */
557
+ withFiles(options?: FileUploadOptions): JayActionBuilder<Services, Input, Output, DefaultMethod>;
521
558
  /**
522
559
  * Define the handler function. Input and output types are inferred from the handler signature.
523
560
  */
@@ -594,6 +631,10 @@ interface JayStreamActionDefinition<Input, Chunk, Services extends any[]> {
594
631
  method: 'POST';
595
632
  isStreaming: true;
596
633
  services: ServiceMarkers<Services>;
634
+ /** Whether this action accepts file uploads (DL#131) */
635
+ acceptsFiles?: boolean;
636
+ /** File upload options (DL#131) */
637
+ fileOptions?: FileUploadOptions;
597
638
  handler: (input: Input, ...services: Services) => AsyncIterable<Chunk>;
598
639
  }
599
640
  /**
@@ -601,6 +642,10 @@ interface JayStreamActionDefinition<Input, Chunk, Services extends any[]> {
601
642
  */
602
643
  interface JayStreamBuilder<Services extends any[]> {
603
644
  withServices<NewServices extends any[]>(...services: ServiceMarkers<NewServices>): JayStreamBuilder<NewServices>;
645
+ /**
646
+ * Mark this streaming action as accepting file uploads (DL#131).
647
+ */
648
+ withFiles(options?: FileUploadOptions): JayStreamBuilder<Services>;
604
649
  withHandler<I, C>(handler: (input: I, ...services: Services) => AsyncIterable<C>): JayStreamAction<I, C> & JayStreamActionDefinition<I, C, Services>;
605
650
  }
606
651
  /**
@@ -736,4 +781,4 @@ declare function makeJayInit(key?: string): JayInitBuilder<void>;
736
781
  */
737
782
  declare function isJayInit(obj: unknown): obj is JayInit<any>;
738
783
 
739
- export { ActionError, type ActionInput, type ActionOutput, type AnyFastRenderResult, type AnyJayStackComponentDefinition, type AnySlowlyRenderResult, type Builder, type CacheOptions, type ClientError4xx, type ContractGeneratorFunction, type DynamicContractGenerator, type DynamicContractProps, type FastRenderResult, type GeneratedContractYaml, type HeadTag, type HttpMethod, type JayAction, type JayActionBuilder, type JayActionDefinition, type JayInit, type JayInitBuilder, type JayInitBuilderWithServer, type JayStackComponentDefinition, type JayStreamAction, type JayStreamActionDefinition, type JayStreamBuilder, type LoadParams, type PageProps, type PartialRender, type PhaseOutput, type PipelineFactory, type Redirect3xx, type RenderFast, type RenderOutcome, RenderPipeline, type RenderSlowly, type RequestQuery, type ServerError5xx, type ServiceInstances, type ServiceMarker, type ServiceMarkers, type Signals, type SlowlyRenderResult, type StreamChunk, type UrlParams, badRequest, clientError4xx, createJayService, forbidden, isJayAction, isJayInit, isJayStreamAction, makeContractGenerator, makeJayAction, makeJayInit, makeJayQuery, makeJayStackComponent, makeJayStream, notFound, partialRender, phaseOutput, redirect3xx, serverError5xx, unauthorized };
784
+ export { ActionError, type ActionInput, type ActionOutput, type AnyFastRenderResult, type AnyJayStackComponentDefinition, type AnySlowlyRenderResult, type Builder, type CacheOptions, type ClientError4xx, type ContractGeneratorFunction, type DynamicContractGenerator, type DynamicContractProps, type FastRenderResult, type FileUploadOptions, type GeneratedContractYaml, type HeadTag, type HttpMethod, type JayAction, type JayActionBuilder, type JayActionDefinition, type JayFile, type JayInit, type JayInitBuilder, type JayInitBuilderWithServer, type JayStackComponentDefinition, type JayStreamAction, type JayStreamActionDefinition, type JayStreamBuilder, type LoadParams, type PageProps, type PartialRender, type PhaseOutput, type PipelineFactory, type Redirect3xx, type RenderFast, type RenderOutcome, RenderPipeline, type RenderSlowly, type RequestQuery, type ServerError5xx, type ServiceInstances, type ServiceMarker, type ServiceMarkers, type Signals, type SlowlyRenderResult, type StreamChunk, type UrlParams, badRequest, clientError4xx, createJayService, forbidden, isJayAction, isJayInit, isJayStreamAction, makeContractGenerator, makeJayAction, makeJayInit, makeJayQuery, makeJayStackComponent, makeJayStream, notFound, partialRender, phaseOutput, redirect3xx, serverError5xx, unauthorized };
package/dist/index.js CHANGED
@@ -364,6 +364,8 @@ class JayActionBuilderImpl {
364
364
  __publicField(this, "_services", []);
365
365
  __publicField(this, "_method");
366
366
  __publicField(this, "_cacheOptions");
367
+ __publicField(this, "_acceptsFiles", false);
368
+ __publicField(this, "_fileOptions");
367
369
  this._actionName = _actionName;
368
370
  this._method = defaultMethod;
369
371
  }
@@ -379,11 +381,18 @@ class JayActionBuilderImpl {
379
381
  this._cacheOptions = options ?? { maxAge: 60 };
380
382
  return this;
381
383
  }
384
+ withFiles(options) {
385
+ this._acceptsFiles = true;
386
+ this._fileOptions = options;
387
+ return this;
388
+ }
382
389
  withHandler(handler) {
383
390
  const actionName = this._actionName;
384
391
  const method = this._method;
385
392
  const cacheOptions = this._cacheOptions;
386
393
  const serviceMarkers = this._services;
394
+ const acceptsFiles = this._acceptsFiles;
395
+ const fileOptions = this._fileOptions;
387
396
  const action = Object.assign(
388
397
  (input) => {
389
398
  const resolver = globalThis.__JAY_SERVICE_RESOLVER__;
@@ -396,7 +405,9 @@ class JayActionBuilderImpl {
396
405
  cacheOptions,
397
406
  services: serviceMarkers,
398
407
  handler,
399
- _brand: "JayAction"
408
+ _brand: "JayAction",
409
+ ...acceptsFiles && { acceptsFiles: true },
410
+ ...fileOptions && { fileOptions }
400
411
  }
401
412
  );
402
413
  return action;
@@ -414,15 +425,24 @@ function isJayAction(value) {
414
425
  class JayStreamBuilderImpl {
415
426
  constructor(_actionName) {
416
427
  __publicField(this, "_services", []);
428
+ __publicField(this, "_acceptsFiles", false);
429
+ __publicField(this, "_fileOptions");
417
430
  this._actionName = _actionName;
418
431
  }
419
432
  withServices(...services) {
420
433
  this._services = services;
421
434
  return this;
422
435
  }
436
+ withFiles(options) {
437
+ this._acceptsFiles = true;
438
+ this._fileOptions = options;
439
+ return this;
440
+ }
423
441
  withHandler(handler) {
424
442
  const actionName = this._actionName;
425
443
  const serviceMarkers = this._services;
444
+ const acceptsFiles = this._acceptsFiles;
445
+ const fileOptions = this._fileOptions;
426
446
  const action = Object.assign(
427
447
  (input) => {
428
448
  const resolver = globalThis.__JAY_SERVICE_RESOLVER__;
@@ -435,7 +455,9 @@ class JayStreamBuilderImpl {
435
455
  isStreaming: true,
436
456
  services: serviceMarkers,
437
457
  handler,
438
- _brand: "JayStreamAction"
458
+ _brand: "JayStreamAction",
459
+ ...acceptsFiles && { acceptsFiles: true },
460
+ ...fileOptions && { fileOptions }
439
461
  }
440
462
  );
441
463
  return action;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/fullstack-component",
3
- "version": "0.16.0",
3
+ "version": "0.16.2",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/index.js",
@@ -26,12 +26,12 @@
26
26
  "test:watch": "vitest"
27
27
  },
28
28
  "dependencies": {
29
- "@jay-framework/component": "^0.16.0",
30
- "@jay-framework/runtime": "^0.16.0"
29
+ "@jay-framework/component": "^0.16.2",
30
+ "@jay-framework/runtime": "^0.16.2"
31
31
  },
32
32
  "devDependencies": {
33
- "@jay-framework/dev-environment": "^0.16.0",
34
- "@jay-framework/jay-cli": "^0.16.0",
33
+ "@jay-framework/dev-environment": "^0.16.2",
34
+ "@jay-framework/jay-cli": "^0.16.2",
35
35
  "@types/express": "^5.0.2",
36
36
  "@types/node": "^22.15.21",
37
37
  "nodemon": "^3.0.3",