@@ -20,7 +20,36 @@ import {
2020 PRODUCTION ,
2121 INSPECT_DEBUGGER_PORT ,
2222 cancellableMethods ,
23- LOG_CLIENT_INIT_TIMEOUT_MS
23+ LOG_CLIENT_INIT_TIMEOUT_MS ,
24+ // Backward-compatible individual header constants
25+ CACHE_CONTROL_HEADER ,
26+ SEGMENT_HEADER ,
27+ SESSION_HEADER ,
28+ PRODUCT_HEADER ,
29+ LOCALE_HEADER ,
30+ FORWARDED_HOST_HEADER ,
31+ TENANT_HEADER ,
32+ BINDING_HEADER ,
33+ META_HEADER ,
34+ META_HEADER_BUCKET ,
35+ ETAG_HEADER ,
36+ ACCOUNT_HEADER ,
37+ CREDENTIAL_HEADER ,
38+ REQUEST_ID_HEADER ,
39+ ROUTER_CACHE_HEADER ,
40+ OPERATION_ID_HEADER ,
41+ PLATFORM_HEADER ,
42+ WORKSPACE_IS_PRODUCTION_HEADER ,
43+ WORKSPACE_HEADER ,
44+ EVENT_KEY_HEADER ,
45+ EVENT_SENDER_HEADER ,
46+ EVENT_SUBJECT_HEADER ,
47+ EVENT_HANDLER_ID_HEADER ,
48+ COLOSSUS_ROUTE_DECLARER_HEADER ,
49+ COLOSSUS_ROUTE_ID_HEADER ,
50+ COLOSSUS_PARAMS_HEADER ,
51+ TRACE_ID_HEADER ,
52+ PROVIDER_HEADER
2453} from './constants'
2554
2655describe ( 'constants' , ( ) => {
@@ -426,5 +455,218 @@ describe('constants', () => {
426455 expect ( APP ) . toHaveProperty ( prop )
427456 } )
428457 } )
458+
459+ describe ( 'Individual header constants (deprecated)' , ( ) => {
460+ test ( 'all individual header constants should be defined' , ( ) => {
461+ expect ( CACHE_CONTROL_HEADER ) . toBeDefined ( )
462+ expect ( SEGMENT_HEADER ) . toBeDefined ( )
463+ expect ( SESSION_HEADER ) . toBeDefined ( )
464+ expect ( PRODUCT_HEADER ) . toBeDefined ( )
465+ expect ( LOCALE_HEADER ) . toBeDefined ( )
466+ expect ( FORWARDED_HOST_HEADER ) . toBeDefined ( )
467+ expect ( TENANT_HEADER ) . toBeDefined ( )
468+ expect ( BINDING_HEADER ) . toBeDefined ( )
469+ expect ( META_HEADER ) . toBeDefined ( )
470+ expect ( META_HEADER_BUCKET ) . toBeDefined ( )
471+ expect ( ETAG_HEADER ) . toBeDefined ( )
472+ expect ( ACCOUNT_HEADER ) . toBeDefined ( )
473+ expect ( CREDENTIAL_HEADER ) . toBeDefined ( )
474+ expect ( REQUEST_ID_HEADER ) . toBeDefined ( )
475+ expect ( ROUTER_CACHE_HEADER ) . toBeDefined ( )
476+ expect ( OPERATION_ID_HEADER ) . toBeDefined ( )
477+ expect ( PLATFORM_HEADER ) . toBeDefined ( )
478+ expect ( WORKSPACE_IS_PRODUCTION_HEADER ) . toBeDefined ( )
479+ expect ( WORKSPACE_HEADER ) . toBeDefined ( )
480+ expect ( EVENT_KEY_HEADER ) . toBeDefined ( )
481+ expect ( EVENT_SENDER_HEADER ) . toBeDefined ( )
482+ expect ( EVENT_SUBJECT_HEADER ) . toBeDefined ( )
483+ expect ( EVENT_HANDLER_ID_HEADER ) . toBeDefined ( )
484+ expect ( COLOSSUS_ROUTE_DECLARER_HEADER ) . toBeDefined ( )
485+ expect ( COLOSSUS_ROUTE_ID_HEADER ) . toBeDefined ( )
486+ expect ( COLOSSUS_PARAMS_HEADER ) . toBeDefined ( )
487+ expect ( TRACE_ID_HEADER ) . toBeDefined ( )
488+ expect ( PROVIDER_HEADER ) . toBeDefined ( )
489+ } )
490+
491+ test ( 'individual constants should equal HeaderKeys values' , ( ) => {
492+ expect ( CACHE_CONTROL_HEADER ) . toBe ( HeaderKeys . CACHE_CONTROL )
493+ expect ( SEGMENT_HEADER ) . toBe ( HeaderKeys . SEGMENT )
494+ expect ( SESSION_HEADER ) . toBe ( HeaderKeys . SESSION )
495+ expect ( PRODUCT_HEADER ) . toBe ( HeaderKeys . PRODUCT )
496+ expect ( LOCALE_HEADER ) . toBe ( HeaderKeys . LOCALE )
497+ expect ( FORWARDED_HOST_HEADER ) . toBe ( HeaderKeys . FORWARDED_HOST )
498+ expect ( TENANT_HEADER ) . toBe ( HeaderKeys . TENANT )
499+ expect ( BINDING_HEADER ) . toBe ( HeaderKeys . BINDING )
500+ expect ( META_HEADER ) . toBe ( HeaderKeys . META )
501+ expect ( META_HEADER_BUCKET ) . toBe ( HeaderKeys . META_BUCKET )
502+ expect ( ETAG_HEADER ) . toBe ( HeaderKeys . ETAG )
503+ expect ( ACCOUNT_HEADER ) . toBe ( HeaderKeys . ACCOUNT )
504+ expect ( CREDENTIAL_HEADER ) . toBe ( HeaderKeys . CREDENTIAL )
505+ expect ( REQUEST_ID_HEADER ) . toBe ( HeaderKeys . REQUEST_ID )
506+ expect ( ROUTER_CACHE_HEADER ) . toBe ( HeaderKeys . ROUTER_CACHE )
507+ expect ( OPERATION_ID_HEADER ) . toBe ( HeaderKeys . OPERATION_ID )
508+ expect ( PLATFORM_HEADER ) . toBe ( HeaderKeys . PLATFORM )
509+ expect ( WORKSPACE_IS_PRODUCTION_HEADER ) . toBe ( HeaderKeys . WORKSPACE_IS_PRODUCTION )
510+ expect ( WORKSPACE_HEADER ) . toBe ( HeaderKeys . WORKSPACE )
511+ expect ( EVENT_KEY_HEADER ) . toBe ( HeaderKeys . EVENT_KEY )
512+ expect ( EVENT_SENDER_HEADER ) . toBe ( HeaderKeys . EVENT_SENDER )
513+ expect ( EVENT_SUBJECT_HEADER ) . toBe ( HeaderKeys . EVENT_SUBJECT )
514+ expect ( EVENT_HANDLER_ID_HEADER ) . toBe ( HeaderKeys . EVENT_HANDLER_ID )
515+ expect ( COLOSSUS_ROUTE_DECLARER_HEADER ) . toBe ( HeaderKeys . COLOSSUS_ROUTE_DECLARER )
516+ expect ( COLOSSUS_ROUTE_ID_HEADER ) . toBe ( HeaderKeys . COLOSSUS_ROUTE_ID )
517+ expect ( COLOSSUS_PARAMS_HEADER ) . toBe ( HeaderKeys . COLOSSUS_PARAMS )
518+ expect ( TRACE_ID_HEADER ) . toBe ( HeaderKeys . TRACE_ID )
519+ expect ( PROVIDER_HEADER ) . toBe ( HeaderKeys . PROVIDER )
520+ } )
521+
522+ test ( 'critical individual constants should have expected string values' , ( ) => {
523+ expect ( TENANT_HEADER ) . toBe ( 'x-vtex-tenant' )
524+ expect ( BINDING_HEADER ) . toBe ( 'x-vtex-binding' )
525+ expect ( LOCALE_HEADER ) . toBe ( 'x-vtex-locale' )
526+ expect ( SEGMENT_HEADER ) . toBe ( 'x-vtex-segment' )
527+ expect ( SESSION_HEADER ) . toBe ( 'x-vtex-session' )
528+ expect ( ACCOUNT_HEADER ) . toBe ( 'x-vtex-account' )
529+ expect ( WORKSPACE_HEADER ) . toBe ( 'x-vtex-workspace' )
530+ } )
531+
532+ test ( 'individual constants should be strings' , ( ) => {
533+ expect ( typeof TENANT_HEADER ) . toBe ( 'string' )
534+ expect ( typeof BINDING_HEADER ) . toBe ( 'string' )
535+ expect ( typeof LOCALE_HEADER ) . toBe ( 'string' )
536+ expect ( typeof SEGMENT_HEADER ) . toBe ( 'string' )
537+ } )
538+
539+ test ( 'constants can be used as object keys without runtime errors' , ( ) => {
540+ // This is how IO apps use them in practice
541+ const headers = {
542+ [ TENANT_HEADER ] : 'example-value' ,
543+ [ BINDING_HEADER ] : 'example-binding' ,
544+ [ LOCALE_HEADER ] : 'en-US' ,
545+ [ SEGMENT_HEADER ] : 'segment-token' ,
546+ [ SESSION_HEADER ] : 'session-token' ,
547+ [ ACCOUNT_HEADER ] : 'account-name' ,
548+ [ WORKSPACE_HEADER ] : 'master'
549+ }
550+
551+ expect ( headers [ 'x-vtex-tenant' ] ) . toBe ( 'example-value' )
552+ expect ( headers [ 'x-vtex-binding' ] ) . toBe ( 'example-binding' )
553+ expect ( headers [ 'x-vtex-locale' ] ) . toBe ( 'en-US' )
554+ expect ( headers [ 'x-vtex-segment' ] ) . toBe ( 'segment-token' )
555+ expect ( Object . keys ( headers ) ) . toHaveLength ( 7 )
556+
557+ // Verify no undefined keys were created
558+ Object . keys ( headers ) . forEach ( key => {
559+ expect ( key ) . not . toBe ( 'undefined' )
560+ expect ( headers [ key ] ) . toBeDefined ( )
561+ } )
562+ } )
563+
564+ test ( 'constants can be destructured from module exports' , ( ) => {
565+ // Simulates: import { TENANT_HEADER, BINDING_HEADER } from '@vtex/api'
566+ const constants = require ( './constants' )
567+ const {
568+ TENANT_HEADER : tenant ,
569+ BINDING_HEADER : binding ,
570+ LOCALE_HEADER : locale ,
571+ SEGMENT_HEADER : segment
572+ } = constants
573+
574+ expect ( tenant ) . toBeDefined ( )
575+ expect ( binding ) . toBeDefined ( )
576+ expect ( locale ) . toBeDefined ( )
577+ expect ( segment ) . toBeDefined ( )
578+
579+ expect ( tenant ) . toBe ( 'x-vtex-tenant' )
580+ expect ( binding ) . toBe ( 'x-vtex-binding' )
581+ expect ( locale ) . toBe ( 'x-vtex-locale' )
582+ expect ( segment ) . toBe ( 'x-vtex-segment' )
583+
584+ // Ensure they're not undefined
585+ expect ( tenant ) . not . toBe ( undefined )
586+ expect ( binding ) . not . toBe ( undefined )
587+ } )
588+
589+ test ( 'individual constants are compatible with VaryHeaders type' , ( ) => {
590+ // VaryHeaders type uses HeaderKeys internally, but should accept old constants
591+ const varyHeaderValues : string [ ] = [ SEGMENT_HEADER , SESSION_HEADER , PRODUCT_HEADER , LOCALE_HEADER ]
592+
593+ varyHeaderValues . forEach ( header => {
594+ expect ( typeof header ) . toBe ( 'string' )
595+ expect ( header . length ) . toBeGreaterThan ( 0 )
596+ // VTEX headers follow x-vtex- pattern, except standard headers like cache-control
597+ expect ( header ) . toMatch ( / ^ x - v t e x - | ^ c a c h e - c o n t r o l $ | ^ e t a g $ / )
598+ } )
599+
600+ // Verify they match the type definition (HeaderKeys values)
601+ const expectedVaryHeaders = [
602+ HeaderKeys . SEGMENT ,
603+ HeaderKeys . SESSION ,
604+ HeaderKeys . PRODUCT ,
605+ HeaderKeys . LOCALE
606+ ]
607+
608+ expect ( varyHeaderValues ) . toEqual ( expectedVaryHeaders )
609+
610+ // Ensure VaryHeaders type inference works
611+ expect ( SEGMENT_HEADER ) . toBe ( HeaderKeys . SEGMENT )
612+ expect ( SESSION_HEADER ) . toBe ( HeaderKeys . SESSION )
613+ expect ( PRODUCT_HEADER ) . toBe ( HeaderKeys . PRODUCT )
614+ expect ( LOCALE_HEADER ) . toBe ( HeaderKeys . LOCALE )
615+ } )
616+
617+ test ( 'constants work correctly as header keys in realistic scenarios' , ( ) => {
618+ // Simulates IO apps usage patterns
619+ const mockBinding = { locale : 'en-US' , currency : 'USD' }
620+ const mockTenant = { locale : 'pt-BR' }
621+ const mockSegmentToken = 'eyJjYW1wYWlnbnMiOm51bGx9'
622+ const mockSessionToken = 'session-abc-123'
623+
624+ // Pattern 1: Building headers object
625+ const requestHeaders = {
626+ [ BINDING_HEADER ] : JSON . stringify ( mockBinding ) ,
627+ [ TENANT_HEADER ] : mockTenant . locale ,
628+ [ LOCALE_HEADER ] : 'en-US' ,
629+ [ SEGMENT_HEADER ] : mockSegmentToken ,
630+ [ SESSION_HEADER ] : mockSessionToken ,
631+ [ ACCOUNT_HEADER ] : 'vtexstore' ,
632+ [ WORKSPACE_HEADER ] : 'master'
633+ }
634+
635+ expect ( requestHeaders [ 'x-vtex-binding' ] ) . toBe ( JSON . stringify ( mockBinding ) )
636+ expect ( requestHeaders [ 'x-vtex-tenant' ] ) . toBe ( 'pt-BR' )
637+ expect ( requestHeaders [ 'x-vtex-locale' ] ) . toBe ( 'en-US' )
638+ expect ( requestHeaders [ 'x-vtex-segment' ] ) . toBe ( mockSegmentToken )
639+ expect ( requestHeaders [ 'x-vtex-session' ] ) . toBe ( mockSessionToken )
640+
641+ // Pattern 2: Conditional header setting
642+ const conditionalHeaders : Record < string , string > = { }
643+ if ( mockSegmentToken ) {
644+ conditionalHeaders [ SEGMENT_HEADER ] = mockSegmentToken
645+ }
646+ if ( mockSessionToken ) {
647+ conditionalHeaders [ SESSION_HEADER ] = mockSessionToken
648+ }
649+
650+ expect ( conditionalHeaders [ 'x-vtex-segment' ] ) . toBe ( mockSegmentToken )
651+ expect ( conditionalHeaders [ 'x-vtex-session' ] ) . toBe ( mockSessionToken )
652+ expect ( Object . keys ( conditionalHeaders ) ) . toHaveLength ( 2 )
653+
654+ // Pattern 3: Reading from headers object
655+ const incomingHeaders : Record < string , string > = {
656+ 'x-vtex-tenant' : 'es-AR' ,
657+ 'x-vtex-binding' : '{"locale":"es-AR"}' ,
658+ 'x-vtex-account' : 'mystore'
659+ }
660+
661+ expect ( incomingHeaders [ TENANT_HEADER ] ) . toBe ( 'es-AR' )
662+ expect ( incomingHeaders [ BINDING_HEADER ] ) . toBe ( '{"locale":"es-AR"}' )
663+ expect ( incomingHeaders [ ACCOUNT_HEADER ] ) . toBe ( 'mystore' )
664+
665+ // Verify no undefined keys in any pattern
666+ expect ( TENANT_HEADER ) . not . toBe ( 'undefined' )
667+ expect ( BINDING_HEADER ) . not . toBe ( 'undefined' )
668+ expect ( SEGMENT_HEADER ) . not . toBe ( 'undefined' )
669+ } )
670+ } )
429671 } )
430672} )
0 commit comments