@jay-framework/fullstack-component 0.17.4 → 0.18.0

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
@@ -441,6 +441,7 @@ declare class RenderPipeline<T, TargetVS extends object = object, TargetCF exten
441
441
  viewState: TargetVS;
442
442
  carryForward: TargetCF;
443
443
  headTags?: HeadTag[];
444
+ responseHeaders?: Record<string, string>;
444
445
  }): Promise<RenderOutcome<TargetVS, TargetCF>>;
445
446
  /** Check if this pipeline is in a success state */
446
447
  isOk(): boolean;
@@ -476,15 +477,6 @@ interface JayFile {
476
477
  /** Absolute path to the temp file on disk (server-side only, always present in handlers) */
477
478
  path?: string;
478
479
  }
479
- /**
480
- * Options for file upload support.
481
- */
482
- interface FileUploadOptions {
483
- /** Maximum file size in bytes (default: 10MB) */
484
- maxFileSize?: number;
485
- /** Maximum number of files (default: 10) */
486
- maxFiles?: number;
487
- }
488
480
  /**
489
481
  * Supported HTTP methods for actions and queries.
490
482
  */
@@ -541,8 +533,6 @@ interface JayActionDefinition<Input, Output, Services extends any[]> {
541
533
  services: ServiceMarkers<Services>;
542
534
  /** Whether this action accepts file uploads (DL#131) */
543
535
  acceptsFiles?: boolean;
544
- /** File upload options (DL#131) */
545
- fileOptions?: FileUploadOptions;
546
536
  /** The handler function */
547
537
  handler: (input: Input, ...services: Services) => Promise<Output>;
548
538
  }
@@ -566,7 +556,7 @@ interface JayActionBuilder<Services extends any[], Input, Output, DefaultMethod
566
556
  * Mark this action as accepting file uploads (DL#131).
567
557
  * The handler will receive JayFile objects for file fields.
568
558
  */
569
- withFiles(options?: FileUploadOptions): JayActionBuilder<Services, Input, Output, DefaultMethod>;
559
+ withFiles(): JayActionBuilder<Services, Input, Output, DefaultMethod>;
570
560
  /**
571
561
  * Define the handler function. Input and output types are inferred from the handler signature.
572
562
  */
@@ -645,8 +635,6 @@ interface JayStreamActionDefinition<Input, Chunk, Services extends any[]> {
645
635
  services: ServiceMarkers<Services>;
646
636
  /** Whether this action accepts file uploads (DL#131) */
647
637
  acceptsFiles?: boolean;
648
- /** File upload options (DL#131) */
649
- fileOptions?: FileUploadOptions;
650
638
  handler: (input: Input, ...services: Services) => AsyncIterable<Chunk>;
651
639
  }
652
640
  /**
@@ -657,7 +645,7 @@ interface JayStreamBuilder<Services extends any[]> {
657
645
  /**
658
646
  * Mark this streaming action as accepting file uploads (DL#131).
659
647
  */
660
- withFiles(options?: FileUploadOptions): JayStreamBuilder<Services>;
648
+ withFiles(): JayStreamBuilder<Services>;
661
649
  withHandler<I, C>(handler: (input: I, ...services: Services) => AsyncIterable<C>): JayStreamAction<I, C> & JayStreamActionDefinition<I, C, Services>;
662
650
  }
663
651
  /**
@@ -727,6 +715,60 @@ interface JayWebhookBuilder<Services extends any[]> {
727
715
  declare function makeWebhook(name: string): JayWebhookBuilder<[]>;
728
716
  declare function isJayWebhook(value: unknown): value is JayWebhook;
729
717
 
718
+ interface ConsoleContext {
719
+ projectRoot: string;
720
+ publicFolder: string;
721
+ build: {
722
+ frontend: string;
723
+ backend: string;
724
+ };
725
+ verbose: boolean;
726
+ log: (message: string) => void;
727
+ warn: (message: string) => void;
728
+ error: (message: string) => void;
729
+ }
730
+ declare const CONSOLE_CONTEXT: ServiceMarker<ConsoleContext>;
731
+ interface JayCliCommand<Input> {
732
+ commandName: string;
733
+ services: ServiceMarkers<any[]>;
734
+ handler: (input: Input, ...services: any[]) => Promise<{
735
+ success: boolean;
736
+ }>;
737
+ _brand: 'JayCliCommand';
738
+ }
739
+ interface JayCliCommandDefinition<Input, Services extends any[]> {
740
+ commandName: string;
741
+ services: ServiceMarkers<Services>;
742
+ handler: (input: Input, ...services: Services) => Promise<{
743
+ success: boolean;
744
+ }>;
745
+ }
746
+ declare function isJayCliCommand(value: unknown): value is JayCliCommand<unknown>;
747
+ interface JayCliCommandBuilder<Services extends any[]> {
748
+ withServices<NewServices extends any[]>(...services: ServiceMarkers<NewServices>): JayCliCommandBuilder<NewServices>;
749
+ withHandler<I>(handler: (input: I, ...services: Services) => Promise<{
750
+ success: boolean;
751
+ }>): JayCliCommand<I> & JayCliCommandDefinition<I, Services>;
752
+ }
753
+ /**
754
+ * Create a CLI command that can be run via `jay-stack run <plugin>/<command>`.
755
+ * Use for admin/batch operations: media upload, deployment, data sync, etc.
756
+ *
757
+ * @param name - Command name (e.g., 'upload-public')
758
+ *
759
+ * @example
760
+ * ```typescript
761
+ * export const uploadPublic = makeCliCommand('upload-public')
762
+ * .withServices(MEDIA_SERVICE, CONSOLE_CONTEXT)
763
+ * .withHandler(async (input: { folder?: string; dryRun?: boolean }, mediaService, console) => {
764
+ * console.log('Uploading files...');
765
+ * // ...
766
+ * return { success: true };
767
+ * });
768
+ * ```
769
+ */
770
+ declare function makeCliCommand(name: string): JayCliCommandBuilder<[]>;
771
+
730
772
  /**
731
773
  * Builder for plugin/project initialization with type-safe server-to-client data flow.
732
774
  *
@@ -829,4 +871,4 @@ declare function makeJayInit(key?: string): JayInitBuilder<void>;
829
871
  */
830
872
  declare function isJayInit(obj: unknown): obj is JayInit<any>;
831
873
 
832
- 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 InvalidateContract, type JayAction, type JayActionBuilder, type JayActionDefinition, type JayFile, type JayInit, type JayInitBuilder, type JayInitBuilderWithServer, type JayStackComponentDefinition, type JayStreamAction, type JayStreamActionDefinition, type JayStreamBuilder, type JayWebhook, type JayWebhookBuilder, type LoadParams, type PageProps, type PartialRender, type PhaseOutput, type PipelineFactory, type Redirect3xx, type RenderFast, type RenderOutcome, RenderPipeline, type RenderSlowly, type RequestCookies, type RequestQuery, type ServerError5xx, type ServiceInstances, type ServiceMarker, type ServiceMarkers, type Signals, type SlowlyRenderResult, type StreamChunk, type UrlParams, type WebhookEvent, badRequest, clientError4xx, createJayService, forbidden, isJayAction, isJayInit, isJayStreamAction, isJayWebhook, makeContractGenerator, makeJayAction, makeJayInit, makeJayQuery, makeJayStackComponent, makeJayStream, makeWebhook, notFound, partialRender, phaseOutput, redirect3xx, serverError5xx, unauthorized };
874
+ export { ActionError, type ActionInput, type ActionOutput, type AnyFastRenderResult, type AnyJayStackComponentDefinition, type AnySlowlyRenderResult, type Builder, CONSOLE_CONTEXT, type CacheOptions, type ClientError4xx, type ConsoleContext, type ContractGeneratorFunction, type DynamicContractGenerator, type DynamicContractProps, type FastRenderResult, type GeneratedContractYaml, type HeadTag, type HttpMethod, type InvalidateContract, type JayAction, type JayActionBuilder, type JayActionDefinition, type JayCliCommand, type JayCliCommandBuilder, type JayCliCommandDefinition, type JayFile, type JayInit, type JayInitBuilder, type JayInitBuilderWithServer, type JayStackComponentDefinition, type JayStreamAction, type JayStreamActionDefinition, type JayStreamBuilder, type JayWebhook, type JayWebhookBuilder, type LoadParams, type PageProps, type PartialRender, type PhaseOutput, type PipelineFactory, type Redirect3xx, type RenderFast, type RenderOutcome, RenderPipeline, type RenderSlowly, type RequestCookies, type RequestQuery, type ServerError5xx, type ServiceInstances, type ServiceMarker, type ServiceMarkers, type Signals, type SlowlyRenderResult, type StreamChunk, type UrlParams, type WebhookEvent, badRequest, clientError4xx, createJayService, forbidden, isJayAction, isJayCliCommand, isJayInit, isJayStreamAction, isJayWebhook, makeCliCommand, makeContractGenerator, makeJayAction, makeJayInit, makeJayQuery, makeJayStackComponent, makeJayStream, makeWebhook, notFound, partialRender, phaseOutput, redirect3xx, serverError5xx, unauthorized };
package/dist/index.js CHANGED
@@ -341,8 +341,9 @@ class RenderPipeline {
341
341
  if (isErrorOutcome(resolvedValue)) {
342
342
  return resolvedValue;
343
343
  }
344
- const { viewState, carryForward, headTags } = fn(resolvedValue);
345
- return phaseOutput(viewState, carryForward, headTags ? { headTags } : void 0);
344
+ const { viewState, carryForward, headTags, responseHeaders } = fn(resolvedValue);
345
+ const options = headTags || responseHeaders ? { headTags, responseHeaders } : void 0;
346
+ return phaseOutput(viewState, carryForward, options);
346
347
  }
347
348
  // =========================================================================
348
349
  // Utility Methods
@@ -369,7 +370,6 @@ class JayActionBuilderImpl {
369
370
  __publicField(this, "_method");
370
371
  __publicField(this, "_cacheOptions");
371
372
  __publicField(this, "_acceptsFiles", false);
372
- __publicField(this, "_fileOptions");
373
373
  this._actionName = _actionName;
374
374
  this._method = defaultMethod;
375
375
  }
@@ -385,9 +385,8 @@ class JayActionBuilderImpl {
385
385
  this._cacheOptions = options ?? { maxAge: 60 };
386
386
  return this;
387
387
  }
388
- withFiles(options) {
388
+ withFiles() {
389
389
  this._acceptsFiles = true;
390
- this._fileOptions = options;
391
390
  return this;
392
391
  }
393
392
  withHandler(handler) {
@@ -396,7 +395,6 @@ class JayActionBuilderImpl {
396
395
  const cacheOptions = this._cacheOptions;
397
396
  const serviceMarkers = this._services;
398
397
  const acceptsFiles = this._acceptsFiles;
399
- const fileOptions = this._fileOptions;
400
398
  const action = Object.assign(
401
399
  (input) => {
402
400
  const resolver = globalThis.__JAY_SERVICE_RESOLVER__;
@@ -410,8 +408,7 @@ class JayActionBuilderImpl {
410
408
  services: serviceMarkers,
411
409
  handler,
412
410
  _brand: "JayAction",
413
- ...acceptsFiles && { acceptsFiles: true },
414
- ...fileOptions && { fileOptions }
411
+ ...acceptsFiles && { acceptsFiles: true }
415
412
  }
416
413
  );
417
414
  return action;
@@ -430,23 +427,20 @@ class JayStreamBuilderImpl {
430
427
  constructor(_actionName) {
431
428
  __publicField(this, "_services", []);
432
429
  __publicField(this, "_acceptsFiles", false);
433
- __publicField(this, "_fileOptions");
434
430
  this._actionName = _actionName;
435
431
  }
436
432
  withServices(...services) {
437
433
  this._services = services;
438
434
  return this;
439
435
  }
440
- withFiles(options) {
436
+ withFiles() {
441
437
  this._acceptsFiles = true;
442
- this._fileOptions = options;
443
438
  return this;
444
439
  }
445
440
  withHandler(handler) {
446
441
  const actionName = this._actionName;
447
442
  const serviceMarkers = this._services;
448
443
  const acceptsFiles = this._acceptsFiles;
449
- const fileOptions = this._fileOptions;
450
444
  const action = Object.assign(
451
445
  (input) => {
452
446
  const resolver = globalThis.__JAY_SERVICE_RESOLVER__;
@@ -460,8 +454,7 @@ class JayStreamBuilderImpl {
460
454
  services: serviceMarkers,
461
455
  handler,
462
456
  _brand: "JayStreamAction",
463
- ...acceptsFiles && { acceptsFiles: true },
464
- ...fileOptions && { fileOptions }
457
+ ...acceptsFiles && { acceptsFiles: true }
465
458
  }
466
459
  );
467
460
  return action;
@@ -497,6 +490,31 @@ function makeWebhook(name) {
497
490
  function isJayWebhook(value) {
498
491
  return typeof value === "object" && value !== null && value._brand === "JayWebhook" && typeof value.webhookName === "string";
499
492
  }
493
+ const CONSOLE_CONTEXT = createJayService("ConsoleContext");
494
+ function isJayCliCommand(value) {
495
+ return typeof value === "object" && value !== null && "_brand" in value && value._brand === "JayCliCommand";
496
+ }
497
+ class JayCliCommandBuilderImpl {
498
+ constructor(_commandName) {
499
+ __publicField(this, "_services", []);
500
+ this._commandName = _commandName;
501
+ }
502
+ withServices(...services) {
503
+ this._services = services;
504
+ return this;
505
+ }
506
+ withHandler(handler) {
507
+ return {
508
+ commandName: this._commandName,
509
+ services: this._services,
510
+ handler,
511
+ _brand: "JayCliCommand"
512
+ };
513
+ }
514
+ }
515
+ function makeCliCommand(name) {
516
+ return new JayCliCommandBuilderImpl(name);
517
+ }
500
518
  function makeJayInit(key) {
501
519
  const resolvedKey = key ?? "__JAY_INIT_KEY__";
502
520
  return {
@@ -534,15 +552,18 @@ function isJayInit(obj) {
534
552
  }
535
553
  export {
536
554
  ActionError,
555
+ CONSOLE_CONTEXT,
537
556
  RenderPipeline,
538
557
  badRequest,
539
558
  clientError4xx,
540
559
  createJayService,
541
560
  forbidden,
542
561
  isJayAction,
562
+ isJayCliCommand,
543
563
  isJayInit,
544
564
  isJayStreamAction,
545
565
  isJayWebhook,
566
+ makeCliCommand,
546
567
  makeContractGenerator,
547
568
  makeJayAction,
548
569
  makeJayInit,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jay-framework/fullstack-component",
3
- "version": "0.17.4",
3
+ "version": "0.18.0",
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.17.4",
30
- "@jay-framework/runtime": "^0.17.4"
29
+ "@jay-framework/component": "^0.18.0",
30
+ "@jay-framework/runtime": "^0.18.0"
31
31
  },
32
32
  "devDependencies": {
33
- "@jay-framework/dev-environment": "^0.17.4",
34
- "@jay-framework/jay-cli": "^0.17.4",
33
+ "@jay-framework/dev-environment": "^0.18.0",
34
+ "@jay-framework/jay-cli": "^0.18.0",
35
35
  "@types/express": "^5.0.2",
36
36
  "@types/node": "^22.15.21",
37
37
  "nodemon": "^3.0.3",