@levrbet/shared 0.5.70 → 0.5.72

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.
@@ -16,6 +16,10 @@ type EnvUrls = {
16
16
  lambda: string;
17
17
  liquidationEngine: string;
18
18
  leaderboard: string;
19
+ /** client-v1 app base origin (e.g. revalidate target). PROD also serves on levr.bet. */
20
+ client: string;
21
+ /** Public base URL of the promo S3 bucket (deterministic name per stage). */
22
+ promoBucket: string;
19
23
  indexers: IndexersMap;
20
24
  };
21
25
  export declare const allUrls: Record<LevrEnv, EnvUrls>;
@@ -15,6 +15,8 @@ exports.allUrls = {
15
15
  lambda: "https://lambda.dev.levr.bet",
16
16
  liquidationEngine: "https://liquidation-engine.dev.levr.bet",
17
17
  leaderboard: "https://leaderboard.dev.levr.bet",
18
+ client: "http://localhost:3000",
19
+ promoBucket: "https://client-dev-promo-bucket.s3.ap-south-1.amazonaws.com",
18
20
  indexers: {
19
21
  [types_1.LevrChain.MONAD_TESTNET]: [
20
22
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/a07fcc5/v1/graphql" },
@@ -33,6 +35,8 @@ exports.allUrls = {
33
35
  lambda: "https://lambda.dev.levr.bet",
34
36
  liquidationEngine: "https://liquidation-engine.dev.levr.bet",
35
37
  leaderboard: "https://leaderboard.dev.levr.bet",
38
+ client: "https://app.dev.levr.bet",
39
+ promoBucket: "https://client-dev-promo-bucket.s3.ap-south-1.amazonaws.com",
36
40
  indexers: {
37
41
  [types_1.LevrChain.MONAD_TESTNET]: [
38
42
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.dev.hyperindex.xyz/79ae9a8/v1/graphql" },
@@ -51,6 +55,8 @@ exports.allUrls = {
51
55
  lambda: "https://lambda.staging.levr.bet",
52
56
  liquidationEngine: "https://liquidation-engine.staging.levr.bet",
53
57
  leaderboard: "https://leaderboard.staging.levr.bet",
58
+ client: "https://app.staging.levr.bet",
59
+ promoBucket: "https://client-staging-promo-bucket.s3.ap-south-1.amazonaws.com",
54
60
  indexers: {
55
61
  [types_1.LevrChain.MONAD_MAINNET]: [
56
62
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.hyperindex.xyz/afda1ae/v1/graphql" },
@@ -69,6 +75,8 @@ exports.allUrls = {
69
75
  lambda: "https://lambda.api.levr.bet",
70
76
  liquidationEngine: "https://liquidation-engine.api.levr.bet",
71
77
  leaderboard: "https://leaderboard.api.levr.bet",
78
+ client: "https://app.levr.bet",
79
+ promoBucket: "https://client-prod-promo-bucket.s3.ap-south-1.amazonaws.com",
72
80
  indexers: {
73
81
  [types_1.LevrChain.MONAD_MAINNET]: [
74
82
  { type: indexers_types_1.LevrIndexer.ENVIO, url: "https://indexer.hyperindex.xyz/ee081a3/v1/graphql" },
@@ -1 +1 @@
1
- {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/core/config/urls.ts"],"names":[],"mappings":";;;AAAA,oCAA6C;AAC7C,4DAAqD;AAmBxC,QAAA,OAAO,GAA6B;IAC7C,CAAC,eAAO,CAAC,KAAK,CAAC,EAAE;QACb,IAAI,EAAE,+BAA+B;QACrC,SAAS,EAAE,gCAAgC;QAC3C,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+BAA+B;QACxC,SAAS,EAAE,gCAAgC;QAC3C,MAAM,EAAE,6BAA6B;QACrC,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,wDAAwD,EAAE;aAChG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,GAAG,CAAC,EAAE;QACX,IAAI,EAAE,+BAA+B;QACrC,SAAS,EAAE,gCAAgC;QAC3C,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,+CAA+C,EAAE,gCAAgC;QAC1F,SAAS,EAAE,gCAAgC;QAC3C,MAAM,EAAE,6BAA6B;QACrC,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,uDAAuD,EAAE;gBACzF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,+DAA+D,EAAE;aACvG;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,OAAO,CAAC,EAAE;QACf,IAAI,EAAE,mCAAmC;QACzC,SAAS,EAAE,oCAAoC;QAC/C,UAAU,EAAE,sCAAsC;QAClD,eAAe,EAAE,2CAA2C;QAC5D,gBAAgB,EAAE,2CAA2C;QAC7D,OAAO,EAAE,mDAAmD,EAAE,sCAAsC;QACpG,SAAS,EAAE,oCAAoC;QAC/C,MAAM,EAAE,iCAAiC;QACzC,iBAAiB,EAAE,6CAA6C;QAChE,WAAW,EAAE,sCAAsC;QACnD,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,mDAAmD,EAAE;gBACrF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,mEAAmE,EAAE;aAC3G;SACJ;KACJ;IACD,CAAC,eAAO,CAAC,IAAI,CAAC,EAAE;QACZ,IAAI,EAAE,2BAA2B;QACjC,SAAS,EAAE,gCAAgC;QAC3C,UAAU,EAAE,kCAAkC;QAC9C,eAAe,EAAE,uCAAuC;QACxD,gBAAgB,EAAE,uCAAuC;QACzD,OAAO,EAAE,gDAAgD,EAAE,gCAAgC;QAC3F,SAAS,EAAE,gCAAgC;QAC3C,MAAM,EAAE,6BAA6B;QACrC,iBAAiB,EAAE,yCAAyC;QAC5D,WAAW,EAAE,kCAAkC;QAC/C,QAAQ,EAAE;YACN,CAAC,iBAAS,CAAC,aAAa,CAAC,EAAE;gBACvB,EAAE,IAAI,EAAE,4BAAW,CAAC,KAAK,EAAE,GAAG,EAAE,mDAAmD,EAAE;gBACrF,EAAE,IAAI,EAAE,4BAAW,CAAC,QAAQ,EAAE,GAAG,EAAE,gEAAgE,EAAE;aACxG;SACJ;KACJ;CACJ,CAAA"}
1
+ {"version":3,"file":"urls.js","sourceRoot":"","sources":["../../../src/core/config/urls.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export * from "./promo.constants";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./promo.constants"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/constants/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,oDAAiC"}
@@ -0,0 +1,18 @@
1
+ /** Default banner render width in CSS pixels (1x) */
2
+ export declare const PROMO_BANNER_W = 387;
3
+ /** Banner height in CSS pixels */
4
+ export declare const PROMO_BANNER_H = 153;
5
+ /** Minimum recommended upload width (2× / retina) */
6
+ export declare const PROMO_RETINA_W = 774;
7
+ /** Minimum recommended upload height (2× / retina) */
8
+ export declare const PROMO_RETINA_H = 306;
9
+ /** Accent / CTA colour */
10
+ export declare const PROMO_MINT = "#1FE08C";
11
+ /** Lightbox backdrop colour */
12
+ export declare const PROMO_BACKDROP = "rgba(0,0,0,0.7)";
13
+ /** Lightbox modal max-width in CSS pixels */
14
+ export declare const PROMO_LIGHTBOX_MAXW = 750;
15
+ /** Default value for the `width` field when not specified */
16
+ export declare const PROMO_DEFAULT_WIDTH = 387;
17
+ /** Maximum accepted image binary size in bytes (5 MB — admin-gated upload, not user-facing) */
18
+ export declare const PROMO_MAX_IMAGE_BYTES: number;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ // Promo banner visual constants (decision #11 — shared between client-v1 components
3
+ // and the dashboard-v1 native preview so the numbers can never diverge).
4
+ // Plain values only — no React.
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.PROMO_MAX_IMAGE_BYTES = exports.PROMO_DEFAULT_WIDTH = exports.PROMO_LIGHTBOX_MAXW = exports.PROMO_BACKDROP = exports.PROMO_MINT = exports.PROMO_RETINA_H = exports.PROMO_RETINA_W = exports.PROMO_BANNER_H = exports.PROMO_BANNER_W = void 0;
7
+ /** Default banner render width in CSS pixels (1x) */
8
+ exports.PROMO_BANNER_W = 387;
9
+ /** Banner height in CSS pixels */
10
+ exports.PROMO_BANNER_H = 153;
11
+ /** Minimum recommended upload width (2× / retina) */
12
+ exports.PROMO_RETINA_W = 774;
13
+ /** Minimum recommended upload height (2× / retina) */
14
+ exports.PROMO_RETINA_H = 306;
15
+ /** Accent / CTA colour */
16
+ exports.PROMO_MINT = "#1FE08C";
17
+ /** Lightbox backdrop colour */
18
+ exports.PROMO_BACKDROP = "rgba(0,0,0,0.7)";
19
+ /** Lightbox modal max-width in CSS pixels */
20
+ exports.PROMO_LIGHTBOX_MAXW = 750;
21
+ /** Default value for the `width` field when not specified */
22
+ exports.PROMO_DEFAULT_WIDTH = 387;
23
+ /** Maximum accepted image binary size in bytes (5 MB — admin-gated upload, not user-facing) */
24
+ exports.PROMO_MAX_IMAGE_BYTES = 5 * 1024 * 1024;
25
+ //# sourceMappingURL=promo.constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promo.constants.js","sourceRoot":"","sources":["../../../src/core/constants/promo.constants.ts"],"names":[],"mappings":";AAAA,oFAAoF;AACpF,yEAAyE;AACzE,gCAAgC;;;AAEhC,qDAAqD;AACxC,QAAA,cAAc,GAAG,GAAG,CAAA;AAEjC,kCAAkC;AACrB,QAAA,cAAc,GAAG,GAAG,CAAA;AAEjC,qDAAqD;AACxC,QAAA,cAAc,GAAG,GAAG,CAAA;AAEjC,sDAAsD;AACzC,QAAA,cAAc,GAAG,GAAG,CAAA;AAEjC,0BAA0B;AACb,QAAA,UAAU,GAAG,SAAS,CAAA;AAEnC,+BAA+B;AAClB,QAAA,cAAc,GAAG,iBAAiB,CAAA;AAE/C,6CAA6C;AAChC,QAAA,mBAAmB,GAAG,GAAG,CAAA;AAEtC,6DAA6D;AAChD,QAAA,mBAAmB,GAAG,GAAG,CAAA;AAEtC,+FAA+F;AAClF,QAAA,qBAAqB,GAAG,CAAC,GAAG,IAAI,GAAG,IAAI,CAAA"}
@@ -1,5 +1,6 @@
1
1
  export * from "./alerts";
2
2
  export * from "./config";
3
+ export * from "./constants";
3
4
  export * from "./contracts";
4
5
  export * from "./indexers";
5
6
  export * from "./prisma";
@@ -16,6 +16,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./alerts"), exports);
18
18
  __exportStar(require("./config"), exports);
19
+ __exportStar(require("./constants"), exports);
19
20
  __exportStar(require("./contracts"), exports);
20
21
  __exportStar(require("./indexers"), exports);
21
22
  __exportStar(require("./prisma"), exports);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAwB;AACxB,2CAAwB;AACxB,8CAA2B;AAC3B,6CAA0B;AAC1B,2CAAwB;AACxB,0CAAuB;AACvB,8CAA2B;AAC3B,0CAAuB;AACvB,0CAAuB;AACvB,+CAA4B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/core/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,2CAAwB;AACxB,2CAAwB;AACxB,8CAA2B;AAC3B,8CAA2B;AAC3B,6CAA0B;AAC1B,2CAAwB;AACxB,0CAAuB;AACvB,8CAA2B;AAC3B,0CAAuB;AACvB,0CAAuB;AACvB,+CAA4B"}
@@ -1,2 +1,3 @@
1
1
  export * from "./bytes.validators";
2
2
  export * from "./mongo.validators";
3
+ export * from "./promo.validators";
@@ -16,4 +16,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./bytes.validators"), exports);
18
18
  __exportStar(require("./mongo.validators"), exports);
19
+ __exportStar(require("./promo.validators"), exports);
19
20
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/validators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAkC;AAClC,qDAAkC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/validators/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAkC;AAClC,qDAAkC;AAClC,qDAAkC"}
@@ -0,0 +1,188 @@
1
+ import { z } from "zod";
2
+ /**
3
+ * Returns true when `url` is an acceptable promo destination or terms URL.
4
+ *
5
+ * Decision #6 rules (open-redirect guard included):
6
+ * - Internal path: single leading "/" NOT followed by "/" or "\" (blocks //evil.com, /\evil.com)
7
+ * - https URL whose host suffix-matches ".levr.bet" or equals "levr.bet"
8
+ * - https URL whose host suffix-matches ".amplifyapp.com"
9
+ * - localhost / 127.0.0.1 on any port, http OR https
10
+ * - Everything else (including javascript:, data:, other hosts) is rejected.
11
+ */
12
+ export declare function isAllowedPromoUrl(url: string): boolean;
13
+ export declare const promoTermsBlockSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
14
+ type: z.ZodLiteral<"heading">;
15
+ text: z.ZodString;
16
+ }, z.core.$strip>, z.ZodObject<{
17
+ type: z.ZodLiteral<"paragraph">;
18
+ text: z.ZodString;
19
+ }, z.core.$strip>, z.ZodObject<{
20
+ type: z.ZodLiteral<"bullets">;
21
+ items: z.ZodArray<z.ZodString>;
22
+ }, z.core.$strip>, z.ZodObject<{
23
+ type: z.ZodLiteral<"ordered">;
24
+ items: z.ZodArray<z.ZodString>;
25
+ }, z.core.$strip>], "type">;
26
+ export type PromoTermsBlock = z.infer<typeof promoTermsBlockSchema>;
27
+ export declare const promoTermsSchema: z.ZodObject<{
28
+ eyebrow: z.ZodOptional<z.ZodString>;
29
+ title: z.ZodString;
30
+ subtitle: z.ZodOptional<z.ZodString>;
31
+ blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
32
+ type: z.ZodLiteral<"heading">;
33
+ text: z.ZodString;
34
+ }, z.core.$strip>, z.ZodObject<{
35
+ type: z.ZodLiteral<"paragraph">;
36
+ text: z.ZodString;
37
+ }, z.core.$strip>, z.ZodObject<{
38
+ type: z.ZodLiteral<"bullets">;
39
+ items: z.ZodArray<z.ZodString>;
40
+ }, z.core.$strip>, z.ZodObject<{
41
+ type: z.ZodLiteral<"ordered">;
42
+ items: z.ZodArray<z.ZodString>;
43
+ }, z.core.$strip>], "type">>;
44
+ }, z.core.$strip>;
45
+ export type PromoTerms = z.infer<typeof promoTermsSchema>;
46
+ export declare const promoConfigSchema: z.ZodObject<{
47
+ id: z.ZodString;
48
+ slug: z.ZodString;
49
+ imageKey: z.ZodString;
50
+ imageUrl: z.ZodString;
51
+ destinationUrl: z.ZodString;
52
+ termsUrl: z.ZodOptional<z.ZodString>;
53
+ hasTerms: z.ZodBoolean;
54
+ altText: z.ZodString;
55
+ width: z.ZodOptional<z.ZodNumber>;
56
+ activeStart: z.ZodOptional<z.ZodString>;
57
+ activeEnd: z.ZodOptional<z.ZodString>;
58
+ published: z.ZodBoolean;
59
+ sortOrder: z.ZodNumber;
60
+ createdAt: z.ZodString;
61
+ updatedAt: z.ZodString;
62
+ }, z.core.$strip>;
63
+ export type PromoConfig = z.infer<typeof promoConfigSchema>;
64
+ export declare const promoRecordSchema: z.ZodObject<{
65
+ id: z.ZodString;
66
+ slug: z.ZodString;
67
+ imageKey: z.ZodString;
68
+ imageUrl: z.ZodString;
69
+ destinationUrl: z.ZodString;
70
+ termsUrl: z.ZodOptional<z.ZodString>;
71
+ hasTerms: z.ZodBoolean;
72
+ altText: z.ZodString;
73
+ width: z.ZodOptional<z.ZodNumber>;
74
+ activeStart: z.ZodOptional<z.ZodString>;
75
+ activeEnd: z.ZodOptional<z.ZodString>;
76
+ published: z.ZodBoolean;
77
+ sortOrder: z.ZodNumber;
78
+ createdAt: z.ZodString;
79
+ updatedAt: z.ZodString;
80
+ terms: z.ZodOptional<z.ZodObject<{
81
+ eyebrow: z.ZodOptional<z.ZodString>;
82
+ title: z.ZodString;
83
+ subtitle: z.ZodOptional<z.ZodString>;
84
+ blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
85
+ type: z.ZodLiteral<"heading">;
86
+ text: z.ZodString;
87
+ }, z.core.$strip>, z.ZodObject<{
88
+ type: z.ZodLiteral<"paragraph">;
89
+ text: z.ZodString;
90
+ }, z.core.$strip>, z.ZodObject<{
91
+ type: z.ZodLiteral<"bullets">;
92
+ items: z.ZodArray<z.ZodString>;
93
+ }, z.core.$strip>, z.ZodObject<{
94
+ type: z.ZodLiteral<"ordered">;
95
+ items: z.ZodArray<z.ZodString>;
96
+ }, z.core.$strip>], "type">>;
97
+ }, z.core.$strip>>;
98
+ }, z.core.$strip>;
99
+ export type PromoRecord = z.infer<typeof promoRecordSchema>;
100
+ /** Private manifest.json — full records including terms */
101
+ export declare const promoManifestSchema: z.ZodArray<z.ZodObject<{
102
+ id: z.ZodString;
103
+ slug: z.ZodString;
104
+ imageKey: z.ZodString;
105
+ imageUrl: z.ZodString;
106
+ destinationUrl: z.ZodString;
107
+ termsUrl: z.ZodOptional<z.ZodString>;
108
+ hasTerms: z.ZodBoolean;
109
+ altText: z.ZodString;
110
+ width: z.ZodOptional<z.ZodNumber>;
111
+ activeStart: z.ZodOptional<z.ZodString>;
112
+ activeEnd: z.ZodOptional<z.ZodString>;
113
+ published: z.ZodBoolean;
114
+ sortOrder: z.ZodNumber;
115
+ createdAt: z.ZodString;
116
+ updatedAt: z.ZodString;
117
+ terms: z.ZodOptional<z.ZodObject<{
118
+ eyebrow: z.ZodOptional<z.ZodString>;
119
+ title: z.ZodString;
120
+ subtitle: z.ZodOptional<z.ZodString>;
121
+ blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
122
+ type: z.ZodLiteral<"heading">;
123
+ text: z.ZodString;
124
+ }, z.core.$strip>, z.ZodObject<{
125
+ type: z.ZodLiteral<"paragraph">;
126
+ text: z.ZodString;
127
+ }, z.core.$strip>, z.ZodObject<{
128
+ type: z.ZodLiteral<"bullets">;
129
+ items: z.ZodArray<z.ZodString>;
130
+ }, z.core.$strip>, z.ZodObject<{
131
+ type: z.ZodLiteral<"ordered">;
132
+ items: z.ZodArray<z.ZodString>;
133
+ }, z.core.$strip>], "type">>;
134
+ }, z.core.$strip>>;
135
+ }, z.core.$strip>>;
136
+ /** Public public.json — published-only, banner fields only (no terms) */
137
+ export declare const promoPublicListSchema: z.ZodArray<z.ZodObject<{
138
+ id: z.ZodString;
139
+ slug: z.ZodString;
140
+ imageKey: z.ZodString;
141
+ imageUrl: z.ZodString;
142
+ destinationUrl: z.ZodString;
143
+ termsUrl: z.ZodOptional<z.ZodString>;
144
+ hasTerms: z.ZodBoolean;
145
+ altText: z.ZodString;
146
+ width: z.ZodOptional<z.ZodNumber>;
147
+ activeStart: z.ZodOptional<z.ZodString>;
148
+ activeEnd: z.ZodOptional<z.ZodString>;
149
+ published: z.ZodBoolean;
150
+ sortOrder: z.ZodNumber;
151
+ createdAt: z.ZodString;
152
+ updatedAt: z.ZodString;
153
+ }, z.core.$strip>>;
154
+ export declare const promoUploadInputSchema: z.ZodObject<{
155
+ slug: z.ZodString;
156
+ destinationUrl: z.ZodString;
157
+ termsUrl: z.ZodOptional<z.ZodString>;
158
+ altText: z.ZodString;
159
+ width: z.ZodOptional<z.ZodNumber>;
160
+ activeStart: z.ZodOptional<z.ZodString>;
161
+ activeEnd: z.ZodOptional<z.ZodString>;
162
+ published: z.ZodDefault<z.ZodBoolean>;
163
+ sortOrder: z.ZodDefault<z.ZodNumber>;
164
+ imageBase64: z.ZodOptional<z.ZodString>;
165
+ imageContentType: z.ZodOptional<z.ZodEnum<{
166
+ "image/jpeg": "image/jpeg";
167
+ "image/png": "image/png";
168
+ }>>;
169
+ terms: z.ZodOptional<z.ZodObject<{
170
+ eyebrow: z.ZodOptional<z.ZodString>;
171
+ title: z.ZodString;
172
+ subtitle: z.ZodOptional<z.ZodString>;
173
+ blocks: z.ZodArray<z.ZodDiscriminatedUnion<[z.ZodObject<{
174
+ type: z.ZodLiteral<"heading">;
175
+ text: z.ZodString;
176
+ }, z.core.$strip>, z.ZodObject<{
177
+ type: z.ZodLiteral<"paragraph">;
178
+ text: z.ZodString;
179
+ }, z.core.$strip>, z.ZodObject<{
180
+ type: z.ZodLiteral<"bullets">;
181
+ items: z.ZodArray<z.ZodString>;
182
+ }, z.core.$strip>, z.ZodObject<{
183
+ type: z.ZodLiteral<"ordered">;
184
+ items: z.ZodArray<z.ZodString>;
185
+ }, z.core.$strip>], "type">>;
186
+ }, z.core.$strip>>;
187
+ }, z.core.$strip>;
188
+ export type PromoUploadInput = z.infer<typeof promoUploadInputSchema>;
@@ -0,0 +1,137 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.promoUploadInputSchema = exports.promoPublicListSchema = exports.promoManifestSchema = exports.promoRecordSchema = exports.promoConfigSchema = exports.promoTermsSchema = exports.promoTermsBlockSchema = void 0;
4
+ exports.isAllowedPromoUrl = isAllowedPromoUrl;
5
+ const zod_1 = require("zod");
6
+ const promo_constants_1 = require("../constants/promo.constants");
7
+ // ============================================================================
8
+ // Internal helpers
9
+ // ============================================================================
10
+ const slugSchema = zod_1.z
11
+ .string()
12
+ .min(3, "Slug must be at least 3 characters")
13
+ .max(60, "Slug must be at most 60 characters")
14
+ .regex(/^[a-z0-9-]+$/, "Slug must contain only lowercase letters, digits, and hyphens");
15
+ const isoDateSchema = zod_1.z.string().datetime({ message: "Must be a valid ISO 8601 datetime string" });
16
+ /**
17
+ * Returns true when `url` is an acceptable promo destination or terms URL.
18
+ *
19
+ * Decision #6 rules (open-redirect guard included):
20
+ * - Internal path: single leading "/" NOT followed by "/" or "\" (blocks //evil.com, /\evil.com)
21
+ * - https URL whose host suffix-matches ".levr.bet" or equals "levr.bet"
22
+ * - https URL whose host suffix-matches ".amplifyapp.com"
23
+ * - localhost / 127.0.0.1 on any port, http OR https
24
+ * - Everything else (including javascript:, data:, other hosts) is rejected.
25
+ */
26
+ function isAllowedPromoUrl(url) {
27
+ // Internal path: starts with "/" but NOT "//" or "/\"
28
+ if (url.startsWith("/")) {
29
+ if (url.startsWith("//") || url.startsWith("/\\")) {
30
+ return false;
31
+ }
32
+ return true;
33
+ }
34
+ // Must be http or https for everything below
35
+ let parsed;
36
+ try {
37
+ parsed = new URL(url);
38
+ }
39
+ catch {
40
+ return false;
41
+ }
42
+ const { protocol, hostname } = parsed;
43
+ // localhost / 127.0.0.1 — http or https allowed (dev)
44
+ if (protocol === "http:" || protocol === "https:") {
45
+ if (hostname === "localhost" || hostname === "127.0.0.1") {
46
+ return true;
47
+ }
48
+ }
49
+ // Everything else must be https
50
+ if (protocol !== "https:") {
51
+ return false;
52
+ }
53
+ // levr.bet domain (exact match or any subdomain)
54
+ if (hostname === "levr.bet" || hostname.endsWith(".levr.bet")) {
55
+ return true;
56
+ }
57
+ // Amplify preview deploys
58
+ if (hostname.endsWith(".amplifyapp.com")) {
59
+ return true;
60
+ }
61
+ return false;
62
+ }
63
+ const allowedPromoUrlSchema = zod_1.z.string().refine(isAllowedPromoUrl, {
64
+ message: "URL must be an internal path (/...), an https *.levr.bet or levr.bet URL, an https *.amplifyapp.com URL, or localhost/127.0.0.1",
65
+ });
66
+ // ============================================================================
67
+ // Terms shapes
68
+ // ============================================================================
69
+ exports.promoTermsBlockSchema = zod_1.z.discriminatedUnion("type", [
70
+ zod_1.z.object({ type: zod_1.z.literal("heading"), text: zod_1.z.string() }),
71
+ zod_1.z.object({ type: zod_1.z.literal("paragraph"), text: zod_1.z.string() }),
72
+ zod_1.z.object({ type: zod_1.z.literal("bullets"), items: zod_1.z.array(zod_1.z.string()) }),
73
+ zod_1.z.object({ type: zod_1.z.literal("ordered"), items: zod_1.z.array(zod_1.z.string()) }),
74
+ ]);
75
+ exports.promoTermsSchema = zod_1.z.object({
76
+ eyebrow: zod_1.z.string().optional(),
77
+ title: zod_1.z.string(),
78
+ subtitle: zod_1.z.string().optional(),
79
+ blocks: zod_1.z.array(exports.promoTermsBlockSchema),
80
+ });
81
+ // ============================================================================
82
+ // Public banner entry — element of public.json
83
+ // ============================================================================
84
+ exports.promoConfigSchema = zod_1.z.object({
85
+ id: zod_1.z.string(),
86
+ slug: slugSchema,
87
+ imageKey: zod_1.z.string(),
88
+ imageUrl: zod_1.z.string(),
89
+ destinationUrl: allowedPromoUrlSchema,
90
+ termsUrl: allowedPromoUrlSchema.optional(),
91
+ hasTerms: zod_1.z.boolean(),
92
+ altText: zod_1.z.string().min(10, "altText must be at least 10 characters").max(200, "altText must be at most 200 characters"),
93
+ width: zod_1.z.number().int().min(200).max(800).optional(),
94
+ activeStart: isoDateSchema.optional(),
95
+ activeEnd: isoDateSchema.optional(),
96
+ published: zod_1.z.boolean(),
97
+ sortOrder: zod_1.z.number().int().min(0).max(999),
98
+ createdAt: isoDateSchema,
99
+ updatedAt: isoDateSchema,
100
+ });
101
+ // ============================================================================
102
+ // Private manifest entry — PromoConfig + optional inline terms
103
+ // ============================================================================
104
+ exports.promoRecordSchema = exports.promoConfigSchema.extend({
105
+ terms: exports.promoTermsSchema.optional(),
106
+ });
107
+ // ============================================================================
108
+ // Manifest list shapes
109
+ // ============================================================================
110
+ /** Private manifest.json — full records including terms */
111
+ exports.promoManifestSchema = zod_1.z.array(exports.promoRecordSchema);
112
+ /** Public public.json — published-only, banner fields only (no terms) */
113
+ exports.promoPublicListSchema = zod_1.z.array(exports.promoConfigSchema);
114
+ // ============================================================================
115
+ // Upload input — what dashboard POSTs to the Lambda
116
+ // ============================================================================
117
+ const MAX_IMAGE_BYTES = promo_constants_1.PROMO_MAX_IMAGE_BYTES;
118
+ const BASE64_REGEX = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/;
119
+ exports.promoUploadInputSchema = zod_1.z.object({
120
+ slug: slugSchema,
121
+ destinationUrl: allowedPromoUrlSchema,
122
+ termsUrl: allowedPromoUrlSchema.optional(),
123
+ altText: zod_1.z.string().min(10, "altText must be at least 10 characters").max(200, "altText must be at most 200 characters"),
124
+ width: zod_1.z.number().int().min(200).max(800).optional(),
125
+ activeStart: isoDateSchema.optional(),
126
+ activeEnd: isoDateSchema.optional(),
127
+ published: zod_1.z.boolean().default(true),
128
+ sortOrder: zod_1.z.number().int().min(0).max(999).default(0),
129
+ imageBase64: zod_1.z
130
+ .string()
131
+ .refine((data) => BASE64_REGEX.test(data), "imageBase64 must be valid base64")
132
+ .refine((data) => Math.ceil((data.length * 3) / 4) <= MAX_IMAGE_BYTES, `Image must be at most ${MAX_IMAGE_BYTES / (1024 * 1024)}MB`)
133
+ .optional(),
134
+ imageContentType: zod_1.z.enum(["image/png", "image/jpeg"]).optional(),
135
+ terms: exports.promoTermsSchema.optional(),
136
+ });
137
+ //# sourceMappingURL=promo.validators.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promo.validators.js","sourceRoot":"","sources":["../../../src/core/validators/promo.validators.ts"],"names":[],"mappings":"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"}
@@ -9,6 +9,8 @@ export declare const urls: {
9
9
  lambda: string;
10
10
  liquidationEngine: string;
11
11
  leaderboard: string;
12
+ client: string;
13
+ promoBucket: string;
12
14
  indexers: Partial<Record<import("..").LevrChain, {
13
15
  type: import("..").LevrIndexer;
14
16
  url: string;
@@ -18,10 +18,9 @@ const clampPeriodElapsed = (elapsed, totalPeriodDurationInSeconds) => Math.max(0
18
18
  const getElapsedSeconds = (gameClockInSeconds, totalPeriodDurationInSeconds, period, isCumulative, clockCountUp) => {
19
19
  if (clockCountUp) {
20
20
  if (isCumulative) {
21
- //if it's soccer only clamp if the game clock exceeds duration for that specific period
22
- if (gameClockInSeconds > totalPeriodDurationInSeconds * period)
23
- return clampPeriodElapsed(gameClockInSeconds, totalPeriodDurationInSeconds);
24
- return Math.max(0, gameClockInSeconds);
21
+ // Soccer injury time: cap the clock at the end of the current half.
22
+ // P1 cap = 2700s (45 min) 5000 BPS. P2 cap = 5400s (90 min) → 10000 BPS.
23
+ return Math.max(0, Math.min(gameClockInSeconds, totalPeriodDurationInSeconds * period));
25
24
  }
26
25
  return clampPeriodElapsed(gameClockInSeconds, totalPeriodDurationInSeconds);
27
26
  }
@@ -1 +1 @@
1
- {"version":3,"file":"game.utils.js","sourceRoot":"","sources":["../../../../src/server/utils/game_progress/game.utils.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"game.utils.js","sourceRoot":"","sources":["../../../../src/server/utils/game_progress/game.utils.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@levrbet/shared",
3
- "version": "0.5.70",
3
+ "version": "0.5.72",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "exports": {