@treasuryspatial/surface-kit 0.1.0 → 0.1.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
@@ -1,4 +1,4 @@
1
- import type { DeepPartial, UiBrandProfile, UiManifest } from '@treasuryspatial/ui-manifest';
1
+ import type { DeepPartial, UiBrandProfile, UiManifest, UiManifestImage } from '@treasuryspatial/ui-manifest';
2
2
  export type SurfaceKitId = 'composer' | 'transit' | 'courtyard';
3
3
  export type SurfaceSkinId = 'transitguy';
4
4
  export type SurfaceCompatibilityMode = 'direct-tenant' | 'tenant-subtenant-bridge';
@@ -29,6 +29,66 @@ export type SurfaceHostResolverOptions = {
29
29
  marketingSlugs?: string[];
30
30
  hostPresets?: Record<string, SurfaceHostPreset>;
31
31
  };
32
+ export type SurfaceBrandingPayload = {
33
+ slug?: string | null;
34
+ tenant?: {
35
+ displayName?: string | null;
36
+ } | null;
37
+ logos?: {
38
+ primary?: string | null;
39
+ [key: string]: unknown;
40
+ } | null;
41
+ organization?: {
42
+ logoUrl?: string | null;
43
+ } | null;
44
+ subtenant?: {
45
+ slug?: string | null;
46
+ name?: string | null;
47
+ logoUrl?: string | null;
48
+ logo_url?: string | null;
49
+ logos?: {
50
+ primary?: string | null;
51
+ [key: string]: unknown;
52
+ } | null;
53
+ branding?: {
54
+ name?: string | null;
55
+ logos?: {
56
+ primary?: string | null;
57
+ [key: string]: unknown;
58
+ } | null;
59
+ colors?: Record<string, string> | null;
60
+ typography?: Record<string, string> | null;
61
+ theme?: Record<string, string> | null;
62
+ } | null;
63
+ } | null;
64
+ branding?: {
65
+ name?: string | null;
66
+ logos?: {
67
+ primary?: string | null;
68
+ [key: string]: unknown;
69
+ } | null;
70
+ colors?: Record<string, string> | null;
71
+ typography?: Record<string, string> | null;
72
+ theme?: Record<string, string> | null;
73
+ } | null;
74
+ logoUrl?: string | null;
75
+ logo_url?: string | null;
76
+ invalidSubdomain?: boolean;
77
+ isEnvironment?: boolean;
78
+ };
79
+ export type SurfaceBrandingTarget = {
80
+ brandingProfile?: UiBrandProfile;
81
+ title?: string;
82
+ surfaceLabel?: string;
83
+ existingLogoAlt?: string | null;
84
+ existingSubtenantLogoAlt?: string | null;
85
+ };
86
+ export type ResolvedSurfaceBrandingImages = {
87
+ topbarLogo: UiManifestImage | null;
88
+ subtenantLogo: UiManifestImage | null;
89
+ scaffoldPrimaryLogo: UiManifestImage | null;
90
+ };
91
+ export type SurfaceBrandingImageMapper = (src: string) => string | null | undefined;
32
92
  export declare const DEFAULT_MARKETING_SLUGS: string[];
33
93
  export declare const TREASURY_LOGO: {
34
94
  src: string;
@@ -38,6 +98,10 @@ export declare const TRANSITGUY_LOGO: {
38
98
  src: string;
39
99
  alt: string;
40
100
  };
101
+ export declare const normalizeSurfaceBrandingPayload: (raw: unknown) => SurfaceBrandingPayload | null;
102
+ export declare const resolveSurfaceBrandingImages: (target: SurfaceBrandingTarget, payload?: SurfaceBrandingPayload | null) => ResolvedSurfaceBrandingImages;
103
+ export declare const applySurfaceBrandingToManifest: (manifest: UiManifest, payload?: SurfaceBrandingPayload | null) => UiManifest;
104
+ export declare const mapSurfaceBrandingManifestImages: (manifest: UiManifest, mapSrc: SurfaceBrandingImageMapper) => UiManifest;
41
105
  export declare const SURFACE_KITS: Record<SurfaceKitId, SurfaceKitProfile>;
42
106
  export declare const SURFACE_SKINS: Record<string, SurfaceSkinProfile>;
43
107
  export declare const SURFACE_HOST_PRESETS: Record<string, SurfaceHostPreset>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAE5F,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AACzC,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,yBAAyB,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,YAAY,CAAC;IACjB,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,aAAa,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,cAAc,CAAC;IAC7B,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,EAAE,YAAY,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;AAExG,MAAM,MAAM,0BAA0B,GAAG;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,YAAY,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACjD,CAAC;AAEF,eAAO,MAAM,uBAAuB,UAOnC,CAAC;AAEF,eAAO,MAAM,aAAa;;;CAGzB,CAAC;AAEF,eAAO,MAAM,eAAe;;;CAG3B,CAAC;AA6BF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,iBAAiB,CA2FhE,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAmD5D,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAiClE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,WAAW,MAAM,KAAG,iBAAiB,GAAG,IAGhF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,KAAG,kBAAkB,GAAG,IAG/E,CAAC;AAOF,eAAO,MAAM,qBAAqB,GAAI,YAAW,MAAM,EAAO,gBACmC,CAAC;AAElG,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,GAAG,IAAI,EAAE,4BAAwC,YAG7F,CAAC;AAcF,eAAO,MAAM,yBAAyB,GAAI,SAAS,0BAA0B;;6BA8ChD,MAAM,GAAG,IAAI;uCAtCE,MAAM,GAAG,IAAI,KAAG,kBAAkB;uCAwCvC,MAAM,GAAG,IAAI;gDAEJ,MAAM,GAAG,IAAI;CAG5D,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,cAAc,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE7G,MAAM,MAAM,YAAY,GAAG,UAAU,GAAG,SAAS,GAAG,WAAW,CAAC;AAChE,MAAM,MAAM,aAAa,GAAG,YAAY,CAAC;AACzC,MAAM,MAAM,wBAAwB,GAAG,eAAe,GAAG,yBAAyB,CAAC;AAEnF,MAAM,MAAM,iBAAiB,GAAG;IAC9B,EAAE,EAAE,YAAY,CAAC;IACjB,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,EAAE,EAAE,aAAa,GAAG,MAAM,CAAC;IAC3B,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC,CAAC;CACnC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,cAAc,CAAC;IAC7B,iBAAiB,EAAE,wBAAwB,CAAC;IAC5C,eAAe,EAAE,OAAO,CAAC;CAC1B,CAAC;AAEF,MAAM,MAAM,iBAAiB,GAAG,IAAI,CAAC,kBAAkB,EAAE,YAAY,GAAG,UAAU,GAAG,iBAAiB,CAAC,CAAC;AAExG,MAAM,MAAM,0BAA0B,GAAG;IACvC,iBAAiB,EAAE,MAAM,CAAC;IAC1B,gBAAgB,EAAE,YAAY,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAAC;CACjD,CAAC;AAEF,MAAM,MAAM,sBAAsB,GAAG;IACnC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,MAAM,CAAC,EAAE;QACP,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC7B,GAAG,IAAI,CAAC;IACT,KAAK,CAAC,EAAE;QACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,GAAG,IAAI,CAAC;IACT,YAAY,CAAC,EAAE;QACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,GAAG,IAAI,CAAC;IACT,SAAS,CAAC,EAAE;QACV,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACzB,KAAK,CAAC,EAAE;YACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;SACxB,GAAG,IAAI,CAAC;QACT,QAAQ,CAAC,EAAE;YACT,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACrB,KAAK,CAAC,EAAE;gBACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;gBACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;aACxB,GAAG,IAAI,CAAC;YACT,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;YACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;YAC3C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;SACvC,GAAG,IAAI,CAAC;KACV,GAAG,IAAI,CAAC;IACT,QAAQ,CAAC,EAAE;QACT,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QACrB,KAAK,CAAC,EAAE;YACN,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;SACxB,GAAG,IAAI,CAAC;QACT,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QACvC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;QAC3C,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;KACvC,GAAG,IAAI,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1C,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,UAAU,EAAE,eAAe,GAAG,IAAI,CAAC;IACnC,aAAa,EAAE,eAAe,GAAG,IAAI,CAAC;IACtC,mBAAmB,EAAE,eAAe,GAAG,IAAI,CAAC;CAC7C,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;AAiBpF,eAAO,MAAM,uBAAuB,UAOnC,CAAC;AAEF,eAAO,MAAM,aAAa;;;CAGzB,CAAC;AAEF,eAAO,MAAM,eAAe;;;CAG3B,CAAC;AAsDF,eAAO,MAAM,+BAA+B,GAAI,KAAK,OAAO,KAAG,sBAAsB,GAAG,IAkDvF,CAAC;AAiBF,eAAO,MAAM,4BAA4B,GACvC,QAAQ,qBAAqB,EAC7B,UAAU,sBAAsB,GAAG,IAAI,KACtC,6BA2BF,CAAC;AAEF,eAAO,MAAM,8BAA8B,GACzC,UAAU,UAAU,EACpB,UAAU,sBAAsB,GAAG,IAAI,KACtC,UA8CF,CAAC;AAEF,eAAO,MAAM,gCAAgC,GAC3C,UAAU,UAAU,EACpB,QAAQ,0BAA0B,KACjC,UAyCF,CAAC;AA6BF,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,YAAY,EAAE,iBAAiB,CAyFhE,CAAC;AAEF,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAmD5D,CAAC;AAEF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAiClE,CAAC;AAEF,eAAO,MAAM,wBAAwB,GAAI,WAAW,MAAM,KAAG,iBAAiB,GAAG,IAGhF,CAAC;AAEF,eAAO,MAAM,yBAAyB,GAAI,QAAQ,MAAM,KAAG,kBAAkB,GAAG,IAG/E,CAAC;AAOF,eAAO,MAAM,qBAAqB,GAAI,YAAW,MAAM,EAAO,gBACmC,CAAC;AAElG,eAAO,MAAM,eAAe,GAAI,OAAO,MAAM,GAAG,IAAI,EAAE,4BAAwC,YAG7F,CAAC;AAcF,eAAO,MAAM,yBAAyB,GAAI,SAAS,0BAA0B;;6BA8ChD,MAAM,GAAG,IAAI;uCAtCE,MAAM,GAAG,IAAI,KAAG,kBAAkB;uCAwCvC,MAAM,GAAG,IAAI;gDAEJ,MAAM,GAAG,IAAI;CAG5D,CAAC"}
package/dist/index.js CHANGED
@@ -15,6 +15,195 @@ export const TRANSITGUY_LOGO = {
15
15
  src: 'https://images.squarespace-cdn.com/content/v1/60074cff46d4c56a53f5b0f8/c9051ab0-28f7-4840-ae97-4d70737abffe/the%2Btransit%2Bgay%2Blogo%2B%281%29.png',
16
16
  alt: 'The Transit Guy',
17
17
  };
18
+ const buildManifestImage = (src, alt) => {
19
+ if (!src)
20
+ return null;
21
+ return { src, alt };
22
+ };
23
+ const mapManifestImage = (image, mapSrc) => {
24
+ if (!image?.src)
25
+ return undefined;
26
+ const mappedSrc = mapSrc(image.src);
27
+ if (!mappedSrc || mappedSrc === image.src)
28
+ return image;
29
+ return {
30
+ ...image,
31
+ src: mappedSrc,
32
+ };
33
+ };
34
+ const cloneRecord = (value) => {
35
+ if (!value || typeof value !== 'object' || Array.isArray(value))
36
+ return null;
37
+ return { ...value };
38
+ };
39
+ const resolvePrimaryLogo = (...candidates) => {
40
+ for (const candidate of candidates) {
41
+ if (typeof candidate === 'string' && candidate.trim())
42
+ return candidate;
43
+ }
44
+ return null;
45
+ };
46
+ const normalizeBrandingRecord = (branding, fallbackLogos, primaryLogo) => {
47
+ const normalizedBranding = cloneRecord(branding);
48
+ const normalizedLogos = {
49
+ ...(fallbackLogos ?? {}),
50
+ ...(cloneRecord(normalizedBranding?.logos ?? null) ?? {}),
51
+ };
52
+ if (primaryLogo) {
53
+ normalizedLogos.primary = primaryLogo;
54
+ }
55
+ if (!normalizedBranding && Object.keys(normalizedLogos).length === 0) {
56
+ return null;
57
+ }
58
+ return {
59
+ ...(normalizedBranding ?? {}),
60
+ ...(Object.keys(normalizedLogos).length > 0 ? { logos: normalizedLogos } : {}),
61
+ };
62
+ };
63
+ export const normalizeSurfaceBrandingPayload = (raw) => {
64
+ if (!raw || typeof raw !== 'object' || Array.isArray(raw))
65
+ return null;
66
+ const source = raw;
67
+ const payload = source.data && typeof source.data === 'object' && !Array.isArray(source.data)
68
+ ? source.data
69
+ : source;
70
+ const rootLogos = cloneRecord(payload.logos);
71
+ const rootBranding = cloneRecord(payload.branding);
72
+ const primaryLogo = resolvePrimaryLogo(rootBranding?.logos?.primary, rootLogos?.primary, payload.logoUrl, payload.logo_url, payload.organization?.logoUrl);
73
+ const normalizedSubtenant = cloneRecord(payload.subtenant);
74
+ const subtenantLogos = cloneRecord(normalizedSubtenant?.logos);
75
+ const subtenantBranding = cloneRecord(normalizedSubtenant?.branding);
76
+ const subtenantPrimaryLogo = resolvePrimaryLogo(subtenantBranding?.logos?.primary, subtenantLogos?.primary, normalizedSubtenant?.logoUrl, normalizedSubtenant?.logo_url);
77
+ return {
78
+ ...payload,
79
+ branding: normalizeBrandingRecord(rootBranding, rootLogos, primaryLogo),
80
+ logos: rootLogos ? { ...rootLogos, ...(primaryLogo ? { primary: primaryLogo } : {}) } : rootLogos,
81
+ logoUrl: primaryLogo,
82
+ subtenant: normalizedSubtenant
83
+ ? {
84
+ ...normalizedSubtenant,
85
+ branding: normalizeBrandingRecord(subtenantBranding, subtenantLogos, subtenantPrimaryLogo),
86
+ logos: subtenantLogos
87
+ ? { ...subtenantLogos, ...(subtenantPrimaryLogo ? { primary: subtenantPrimaryLogo } : {}) }
88
+ : subtenantLogos,
89
+ logoUrl: subtenantPrimaryLogo,
90
+ }
91
+ : null,
92
+ };
93
+ };
94
+ const resolvePrimaryBrandingLogoSrc = (payload) => payload?.branding?.logos?.primary ||
95
+ payload?.logos?.primary ||
96
+ payload?.logoUrl ||
97
+ payload?.logo_url ||
98
+ payload?.organization?.logoUrl ||
99
+ null;
100
+ const resolveSubtenantBrandingLogoSrc = (payload) => payload?.subtenant?.branding?.logos?.primary ||
101
+ payload?.subtenant?.logos?.primary ||
102
+ payload?.subtenant?.logoUrl ||
103
+ payload?.subtenant?.logo_url ||
104
+ null;
105
+ export const resolveSurfaceBrandingImages = (target, payload) => {
106
+ const normalizedPayload = normalizeSurfaceBrandingPayload(payload);
107
+ const primaryLogoSrc = resolvePrimaryBrandingLogoSrc(normalizedPayload);
108
+ const subtenantLogoSrc = resolveSubtenantBrandingLogoSrc(normalizedPayload);
109
+ const resolvedPrimaryAlt = target.existingLogoAlt ||
110
+ normalizedPayload?.branding?.name ||
111
+ normalizedPayload?.tenant?.displayName ||
112
+ target.title ||
113
+ target.surfaceLabel ||
114
+ 'Logo';
115
+ const resolvedSubtenantAlt = target.existingSubtenantLogoAlt ||
116
+ normalizedPayload?.subtenant?.name ||
117
+ target.surfaceLabel ||
118
+ 'Subtenant';
119
+ const topbarLogo = buildManifestImage(primaryLogoSrc, resolvedPrimaryAlt);
120
+ const subtenantLogo = subtenantLogoSrc && subtenantLogoSrc !== primaryLogoSrc
121
+ ? buildManifestImage(subtenantLogoSrc, resolvedSubtenantAlt)
122
+ : null;
123
+ return {
124
+ topbarLogo,
125
+ subtenantLogo,
126
+ scaffoldPrimaryLogo: topbarLogo,
127
+ };
128
+ };
129
+ export const applySurfaceBrandingToManifest = (manifest, payload) => {
130
+ const images = resolveSurfaceBrandingImages({
131
+ brandingProfile: manifest.branding?.profile,
132
+ title: manifest.topbar.title,
133
+ surfaceLabel: manifest.surface?.label,
134
+ existingLogoAlt: manifest.topbar.logo?.alt ?? null,
135
+ existingSubtenantLogoAlt: manifest.topbar.subtenantLogo?.alt ?? null,
136
+ }, payload);
137
+ const isTreasuryNative = manifest.branding?.profile === 'treasury-native';
138
+ const nextTopbar = { ...manifest.topbar };
139
+ const nextSurface = manifest.surface ? { ...manifest.surface } : manifest.surface;
140
+ const nextScaffoldShell = nextSurface?.scaffoldShell ? { ...nextSurface.scaffoldShell } : undefined;
141
+ if (images.topbarLogo) {
142
+ nextTopbar.logo = images.topbarLogo;
143
+ }
144
+ else if (isTreasuryNative) {
145
+ delete nextTopbar.logo;
146
+ }
147
+ if (images.subtenantLogo) {
148
+ nextTopbar.subtenantLogo = images.subtenantLogo;
149
+ }
150
+ else if (isTreasuryNative) {
151
+ delete nextTopbar.subtenantLogo;
152
+ }
153
+ if (nextScaffoldShell) {
154
+ if (images.scaffoldPrimaryLogo) {
155
+ nextScaffoldShell.primaryLogo = images.scaffoldPrimaryLogo;
156
+ }
157
+ else if (isTreasuryNative) {
158
+ delete nextScaffoldShell.primaryLogo;
159
+ }
160
+ }
161
+ return {
162
+ ...manifest,
163
+ topbar: nextTopbar,
164
+ surface: nextSurface
165
+ ? {
166
+ ...nextSurface,
167
+ scaffoldShell: nextScaffoldShell,
168
+ }
169
+ : nextSurface,
170
+ };
171
+ };
172
+ export const mapSurfaceBrandingManifestImages = (manifest, mapSrc) => {
173
+ const mappedTopbarLogo = mapManifestImage(manifest.topbar.logo, mapSrc);
174
+ const mappedSubtenantLogo = mapManifestImage(manifest.topbar.subtenantLogo, mapSrc);
175
+ const mappedSecondaryLogo = mapManifestImage(manifest.topbar.secondaryLogo, mapSrc);
176
+ const mappedPrimaryShellLogo = mapManifestImage(manifest.surface?.scaffoldShell?.primaryLogo, mapSrc);
177
+ const mappedSecondaryShellLogo = mapManifestImage(manifest.surface?.scaffoldShell?.secondaryLogo, mapSrc);
178
+ if (mappedTopbarLogo === manifest.topbar.logo &&
179
+ mappedSubtenantLogo === manifest.topbar.subtenantLogo &&
180
+ mappedSecondaryLogo === manifest.topbar.secondaryLogo &&
181
+ mappedPrimaryShellLogo === manifest.surface?.scaffoldShell?.primaryLogo &&
182
+ mappedSecondaryShellLogo === manifest.surface?.scaffoldShell?.secondaryLogo) {
183
+ return manifest;
184
+ }
185
+ return {
186
+ ...manifest,
187
+ topbar: {
188
+ ...manifest.topbar,
189
+ logo: mappedTopbarLogo,
190
+ subtenantLogo: mappedSubtenantLogo,
191
+ secondaryLogo: mappedSecondaryLogo,
192
+ },
193
+ surface: manifest.surface
194
+ ? {
195
+ ...manifest.surface,
196
+ scaffoldShell: manifest.surface.scaffoldShell
197
+ ? {
198
+ ...manifest.surface.scaffoldShell,
199
+ primaryLogo: mappedPrimaryShellLogo,
200
+ secondaryLogo: mappedSecondaryShellLogo,
201
+ }
202
+ : manifest.surface.scaffoldShell,
203
+ }
204
+ : manifest.surface,
205
+ };
206
+ };
18
207
  const TRANSIT_MODE_POLICY = mergeSurfaceModePolicy(DEFAULT_COMPOSER_SURFACE_MODE_POLICY, {
19
208
  defaultMode: 'streetmix',
20
209
  modes: {
@@ -70,8 +259,8 @@ export const SURFACE_KITS = {
70
259
  label: 'Transit',
71
260
  promptFamily: 'transit',
72
261
  brandProfile: 'treasury-native',
73
- summary: 'Treasury-native transit surface built on the Composer runtime.',
74
- description: 'Transit is the packaged Treasury surface for corridor visuals, stop environments, and street-section scaffold workflows.',
262
+ summary: 'Transit surface built on the Composer runtime.',
263
+ description: 'Transit is the packaged surface for corridor visuals, stop environments, and street-section scaffold workflows.',
75
264
  standaloneCapable: true,
76
265
  scaffoldShell: {
77
266
  badge: 'Streetmix',
@@ -86,7 +275,6 @@ export const SURFACE_KITS = {
86
275
  },
87
276
  topbar: {
88
277
  title: 'Treasury',
89
- subtitle: 'Treasury-native transit surface',
90
278
  productLabel: 'Transit Composer',
91
279
  links: [
92
280
  { label: 'Treasury', href: 'https://treasury.space/', target: '_blank' },
@@ -121,7 +309,6 @@ export const SURFACE_KITS = {
121
309
  },
122
310
  topbar: {
123
311
  title: 'Treasury',
124
- subtitle: 'Treasury-native courtyard surface',
125
312
  productLabel: 'Courtyard Composer',
126
313
  links: [
127
314
  { label: 'Treasury', href: 'https://treasury.space/', target: '_blank' },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treasuryspatial/surface-kit",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "type": "module",
5
5
  "license": "UNLICENSED",
6
6
  "main": "./dist/index.js",
@@ -19,10 +19,11 @@
19
19
  },
20
20
  "dependencies": {
21
21
  "@treasuryspatial/mode-policy": "^0.1.5",
22
- "@treasuryspatial/ui-manifest": "^0.1.6"
22
+ "@treasuryspatial/ui-manifest": "^0.1.7"
23
23
  },
24
24
  "scripts": {
25
25
  "build": "tsc -b",
26
+ "test": "npm run build && node --test test/*.test.mjs",
26
27
  "typecheck": "tsc -b --pretty false --noEmit"
27
28
  }
28
29
  }