@reblu/site-contracts 1.0.1 → 1.2.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/CHANGELOG.md CHANGED
@@ -1,5 +1,51 @@
1
1
  # @reblu/site-contracts
2
2
 
3
+ ## 1.2.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 34b15c4: Expose the academy verification gate's field list on `AcademyCourseDetail` (REB-83).
8
+
9
+ `AcademyCourseDetail.validationFields` is a new field: an ordered array of
10
+ `AcademyValidationFieldPublic` (`{ key, label, required, maxLength? }`), the
11
+ tenant's OWN configured list of data points its access-validation gate asks
12
+ for (e.g. a colegiado number and a professional college), resolved server-side
13
+ from `AcademyConfig.validationFields` — or derived as a single legacy field
14
+ under the key `'validationField'` when the tenant has not configured a list
15
+ yet, so an already-integrated SITE keeps working unchanged. A SITE renders
16
+ its enrollment form from this array instead of a fixed field.
17
+
18
+ Additive: a new required field on the existing `AcademyCourseDetail` shape
19
+ (populated for every course, empty array when the gate does not apply) and a
20
+ new exported type. The existing `validationFieldLabel` field is unchanged and
21
+ still present for a SITE build that has not migrated to the new array yet.
22
+
23
+ ## 1.1.0
24
+
25
+ ### Minor Changes
26
+
27
+ - 16dfaea: Add the SITE capability manifest types (REB-777).
28
+
29
+ `SiteManifest`, `SiteManifestSurfaceValue`, and `SiteCapabilitySurfaceKey` are
30
+ the SDK-facing types for `/.well-known/reblu-site.json` — the manifest a SITE
31
+ serves (via `@reblu/site-next`'s new `createSiteManifestRoute`) declaring
32
+ which capability surfaces it has implemented (`academy.enrollment`,
33
+ `academy.catalogue`, `auth.login`, `consent.banner`, `legal.cookies`), so
34
+ nexus can warn a tenant OWNER when a sold module has no matching page on
35
+ their SITE yet.
36
+
37
+ This is the one contract group in this package a SITE produces and base-api
38
+ consumes — the opposite direction of every other export here — but the
39
+ package stays exactly as dependency-free as before: these are `export type`
40
+ only, flowing through the same `@reblu/base-api-contracts` type-only alias
41
+ every other export uses. No runtime Zod, no new dependency, no change to any
42
+ existing export.
43
+
44
+ Purely additive. Not REB-744 (canonical route keys for per-route redirect
45
+ generation, separately tracked, still unimplemented) — that is a different,
46
+ coarser vocabulary (whole-module redirect targets) for a different purpose
47
+ (generating a URL, not declaring a capability).
48
+
3
49
  ## 1.0.1
4
50
 
5
51
  ### Patch Changes
package/dist/index.d.cts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export type AcademyCategoryPublic = { id: string; name: string; slug: string; sortOrder: number;}
7
7
 
8
- export type AcademyCourseDetail = { id: string; slug: string; title: string; shortDescription: string | null; coverUrl: string | null; priceCents: number; accessMode: "IMMEDIATE" | "DRIP" | "COHORT"; category: { id: string; name: string; slug: string; sortOrder: number; } | null; description: string | null; modules: { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[]; }[]; instructors: { id: string; firstName: string | null; lastName: string | null; avatarUrl: string | null; }[]; salesEnabled: boolean; requiresValidation: boolean; validationFieldLabel: string | null;}
8
+ export type AcademyCourseDetail = { id: string; slug: string; title: string; shortDescription: string | null; coverUrl: string | null; priceCents: number; accessMode: "IMMEDIATE" | "DRIP" | "COHORT"; category: { id: string; name: string; slug: string; sortOrder: number; } | null; description: string | null; modules: { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[]; }[]; instructors: { id: string; firstName: string | null; lastName: string | null; avatarUrl: string | null; }[]; salesEnabled: boolean; requiresValidation: boolean; validationFieldLabel: string | null; validationFields: { key: string; label: string; required: boolean; maxLength?: number | undefined; }[];}
9
9
 
10
10
  export type AcademyCourseSort = "price_asc" | "price_desc" | "newest"
11
11
 
@@ -17,7 +17,9 @@ export type AcademyLessonPublic = { id: string; slug: string; title: st
17
17
 
18
18
  export type AcademyModulePublic = { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[];}
19
19
 
20
- export type Analytics = { gaId: string | null; clarityId: string | null; recaptchaSiteKey: string | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; metaPixelId: string | null; metaVerificationContent: string | null; googleVerificationContent: string | null;}
20
+ export type AcademyValidationFieldPublic = { key: string; label: string; required: boolean; maxLength?: number | undefined;}
21
+
22
+ export type Analytics = { gaId: string | null; clarityId: string | null; recaptchaSiteKey: string | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; metaPixelId: string | null; metaVerificationContent: string | null; googleVerificationContent: string | null; consentRequired: boolean; cookiePolicyVersion: string | null; cookieBanner: { enabled: boolean; title: string | null; body: string | null; acceptLabel: string | null; rejectLabel: string | null; manageLabel: string | null; policyUrl: string | null; }; cookieInventory: { vendor: string; category: "necessary" | "analytics" | "marketing"; }[];}
21
23
 
22
24
  export type BlogAuthor = { firstName: string | null; lastName: string | null; avatarUrl: string | null;}
23
25
 
@@ -173,6 +175,12 @@ export type ShopTaxonomyTermRef = { taxonomyKey: string; taxonomyLabel: st
173
175
 
174
176
  export type ShopValidateCartInput = { items: { productId: string; quantity: number; variantId?: string | null | undefined; }[];}
175
177
 
178
+ export type SiteCapabilitySurfaceKey = "academy.enrollment" | "academy.catalogue" | "auth.login" | "consent.banner" | "legal.cookies"
179
+
180
+ export type SiteManifest = { manifestVersion: 1; surfaces: Record<string, true | { path?: string | undefined; }>; sdkVersion?: string | undefined;}
181
+
182
+ export type SiteManifestSurfaceValue = true | { path?: string | undefined;}
183
+
176
184
  export type TaxType = "IVA" | "IGIC" | "RETENTION" | "OTHER"
177
185
 
178
186
  export type TrustBadge = { id: string; name: string; logoUrl: string | null; url: string | null; type: "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD"; sortOrder: number;}
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
  export type AcademyCategoryPublic = { id: string; name: string; slug: string; sortOrder: number;}
7
7
 
8
- export type AcademyCourseDetail = { id: string; slug: string; title: string; shortDescription: string | null; coverUrl: string | null; priceCents: number; accessMode: "IMMEDIATE" | "DRIP" | "COHORT"; category: { id: string; name: string; slug: string; sortOrder: number; } | null; description: string | null; modules: { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[]; }[]; instructors: { id: string; firstName: string | null; lastName: string | null; avatarUrl: string | null; }[]; salesEnabled: boolean; requiresValidation: boolean; validationFieldLabel: string | null;}
8
+ export type AcademyCourseDetail = { id: string; slug: string; title: string; shortDescription: string | null; coverUrl: string | null; priceCents: number; accessMode: "IMMEDIATE" | "DRIP" | "COHORT"; category: { id: string; name: string; slug: string; sortOrder: number; } | null; description: string | null; modules: { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[]; }[]; instructors: { id: string; firstName: string | null; lastName: string | null; avatarUrl: string | null; }[]; salesEnabled: boolean; requiresValidation: boolean; validationFieldLabel: string | null; validationFields: { key: string; label: string; required: boolean; maxLength?: number | undefined; }[];}
9
9
 
10
10
  export type AcademyCourseSort = "price_asc" | "price_desc" | "newest"
11
11
 
@@ -17,7 +17,9 @@ export type AcademyLessonPublic = { id: string; slug: string; title: st
17
17
 
18
18
  export type AcademyModulePublic = { id: string; title: string; description: string | null; lessons: { id: string; slug: string; title: string; isFreePreview: boolean; durationSeconds: number | null; hasVideo: boolean; }[];}
19
19
 
20
- export type Analytics = { gaId: string | null; clarityId: string | null; recaptchaSiteKey: string | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; metaPixelId: string | null; metaVerificationContent: string | null; googleVerificationContent: string | null;}
20
+ export type AcademyValidationFieldPublic = { key: string; label: string; required: boolean; maxLength?: number | undefined;}
21
+
22
+ export type Analytics = { gaId: string | null; clarityId: string | null; recaptchaSiteKey: string | null; contactFormMode: "NOT_CONFIGURED" | "DISABLED" | "DB_ONLY" | "WEBHOOK" | "RESEND"; metaPixelId: string | null; metaVerificationContent: string | null; googleVerificationContent: string | null; consentRequired: boolean; cookiePolicyVersion: string | null; cookieBanner: { enabled: boolean; title: string | null; body: string | null; acceptLabel: string | null; rejectLabel: string | null; manageLabel: string | null; policyUrl: string | null; }; cookieInventory: { vendor: string; category: "necessary" | "analytics" | "marketing"; }[];}
21
23
 
22
24
  export type BlogAuthor = { firstName: string | null; lastName: string | null; avatarUrl: string | null;}
23
25
 
@@ -173,6 +175,12 @@ export type ShopTaxonomyTermRef = { taxonomyKey: string; taxonomyLabel: st
173
175
 
174
176
  export type ShopValidateCartInput = { items: { productId: string; quantity: number; variantId?: string | null | undefined; }[];}
175
177
 
178
+ export type SiteCapabilitySurfaceKey = "academy.enrollment" | "academy.catalogue" | "auth.login" | "consent.banner" | "legal.cookies"
179
+
180
+ export type SiteManifest = { manifestVersion: 1; surfaces: Record<string, true | { path?: string | undefined; }>; sdkVersion?: string | undefined;}
181
+
182
+ export type SiteManifestSurfaceValue = true | { path?: string | undefined;}
183
+
176
184
  export type TaxType = "IVA" | "IGIC" | "RETENTION" | "OTHER"
177
185
 
178
186
  export type TrustBadge = { id: string; name: string; logoUrl: string | null; url: string | null; type: "PARTNER" | "INSURANCE" | "SUBVENTION" | "CERTIFICATION" | "AWARD"; sortOrder: number;}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@reblu/site-contracts",
3
- "version": "1.0.1",
3
+ "version": "1.2.0",
4
4
  "private": false,
5
5
  "description": "Public, dependency-free TypeScript types for the Reblu SITE API (types only — no Zod, no Prisma at runtime).",
6
6
  "license": "Apache-2.0",