@bash-app/bash-common 30.381.0 → 30.385.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/__tests__/accessScreening.test.js +39 -1
- package/dist/__tests__/accessScreening.test.js.map +1 -1
- package/dist/__tests__/applicationFunnel.test.d.ts +2 -0
- package/dist/__tests__/applicationFunnel.test.d.ts.map +1 -0
- package/dist/__tests__/applicationFunnel.test.js +126 -0
- package/dist/__tests__/applicationFunnel.test.js.map +1 -0
- package/dist/__tests__/definitionsHelpers.test.js +20 -1
- package/dist/__tests__/definitionsHelpers.test.js.map +1 -1
- package/dist/__tests__/fundingMeter.test.d.ts +2 -0
- package/dist/__tests__/fundingMeter.test.d.ts.map +1 -0
- package/dist/__tests__/fundingMeter.test.js +129 -0
- package/dist/__tests__/fundingMeter.test.js.map +1 -0
- package/dist/__tests__/giveaway.test.d.ts +2 -0
- package/dist/__tests__/giveaway.test.d.ts.map +1 -0
- package/dist/__tests__/giveaway.test.js +65 -0
- package/dist/__tests__/giveaway.test.js.map +1 -0
- package/dist/__tests__/promoterCompetitionUtils.test.d.ts +2 -0
- package/dist/__tests__/promoterCompetitionUtils.test.d.ts.map +1 -0
- package/dist/__tests__/promoterCompetitionUtils.test.js +262 -0
- package/dist/__tests__/promoterCompetitionUtils.test.js.map +1 -0
- package/dist/accessScreening.d.ts +18 -3
- package/dist/accessScreening.d.ts.map +1 -1
- package/dist/accessScreening.js +26 -0
- package/dist/accessScreening.js.map +1 -1
- package/dist/applicationFunnel.d.ts +58 -0
- package/dist/applicationFunnel.d.ts.map +1 -0
- package/dist/applicationFunnel.js +147 -0
- package/dist/applicationFunnel.js.map +1 -0
- package/dist/definitions.d.ts +145 -5
- package/dist/definitions.d.ts.map +1 -1
- package/dist/definitions.js +137 -5
- package/dist/definitions.js.map +1 -1
- package/dist/extendedSchemas.d.ts +166 -1
- package/dist/extendedSchemas.d.ts.map +1 -1
- package/dist/extendedSchemas.js +7 -1
- package/dist/extendedSchemas.js.map +1 -1
- package/dist/fundingMeter.d.ts +66 -0
- package/dist/fundingMeter.d.ts.map +1 -0
- package/dist/fundingMeter.js +99 -0
- package/dist/fundingMeter.js.map +1 -0
- package/dist/giveaway.d.ts +71 -0
- package/dist/giveaway.d.ts.map +1 -0
- package/dist/giveaway.js +117 -0
- package/dist/giveaway.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/utils/__tests__/bashHostIdentity.test.d.ts +2 -0
- package/dist/utils/__tests__/bashHostIdentity.test.d.ts.map +1 -0
- package/dist/utils/__tests__/bashHostIdentity.test.js +39 -0
- package/dist/utils/__tests__/bashHostIdentity.test.js.map +1 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.d.ts +2 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.d.ts.map +1 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.js +104 -0
- package/dist/utils/__tests__/promoterCompetitionUtils.test.js.map +1 -0
- package/dist/utils/__tests__/slugUtils.test.js +29 -2
- package/dist/utils/__tests__/slugUtils.test.js.map +1 -1
- package/dist/utils/bashHostIdentity.d.ts +18 -0
- package/dist/utils/bashHostIdentity.d.ts.map +1 -0
- package/dist/utils/bashHostIdentity.js +17 -0
- package/dist/utils/bashHostIdentity.js.map +1 -0
- package/dist/utils/promoterCompetitionUtils.d.ts +89 -0
- package/dist/utils/promoterCompetitionUtils.d.ts.map +1 -0
- package/dist/utils/promoterCompetitionUtils.js +158 -0
- package/dist/utils/promoterCompetitionUtils.js.map +1 -0
- package/dist/utils/slugUtils.d.ts +2 -0
- package/dist/utils/slugUtils.d.ts.map +1 -1
- package/dist/utils/slugUtils.js +5 -1
- package/dist/utils/slugUtils.js.map +1 -1
- package/package.json +1 -1
- package/prisma/schema.prisma +415 -25
- package/src/__tests__/accessScreening.test.ts +69 -1
- package/src/__tests__/applicationFunnel.test.ts +197 -0
- package/src/__tests__/definitionsHelpers.test.ts +24 -0
- package/src/__tests__/fundingMeter.test.ts +143 -0
- package/src/__tests__/giveaway.test.ts +111 -0
- package/src/__tests__/promoterCompetitionUtils.test.ts +334 -0
- package/src/accessScreening.ts +49 -0
- package/src/applicationFunnel.ts +225 -0
- package/src/definitions.ts +181 -5
- package/src/extendedSchemas.ts +127 -1
- package/src/fundingMeter.ts +188 -0
- package/src/giveaway.ts +182 -0
- package/src/index.ts +14 -0
- package/src/utils/__tests__/bashHostIdentity.test.ts +57 -0
- package/src/utils/__tests__/promoterCompetitionUtils.test.ts +128 -0
- package/src/utils/__tests__/slugUtils.test.ts +44 -0
- package/src/utils/bashHostIdentity.ts +30 -0
- package/src/utils/promoterCompetitionUtils.ts +235 -0
- package/src/utils/slugUtils.ts +11 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashHostIdentity.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/bashHostIdentity.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EACL,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,wBAAwB,CAAC;AAEhC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,EAAE;IACtC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CACJ,sBAAsB,CAAC;YACrB,eAAe,EAAE,EAAE,WAAW,EAAE,cAAc,EAAE;YAChD,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;YACpC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE;SAClD,CAAC,CACH,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gDAAgD,EAAE,GAAG,EAAE;QACxD,MAAM,CACJ,sBAAsB,CAAC;YACrB,YAAY,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE;YACpC,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE;SAClD,CAAC,CACH,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,GAAG,EAAE;QAC5C,MAAM,CACJ,sBAAsB,CAAC;YACrB,OAAO,EAAE,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE;SAClD,CAAC,CACH,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,sBAAsB,EAAE,GAAG,EAAE;IACpC,EAAE,CAAC,iCAAiC,EAAE,GAAG,EAAE;QACzC,MAAM,CACJ,oBAAoB,CAAC;YACnB,eAAe,EAAE,EAAE,UAAU,EAAE,6BAA6B,EAAE;YAC9D,YAAY,EAAE,EAAE,OAAO,EAAE,6BAA6B,EAAE;SACzD,CAAC,CACH,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,kDAAkD,EAAE,GAAG,EAAE;QAC1D,MAAM,CACJ,oBAAoB,CAAC;YACnB,YAAY,EAAE,EAAE,OAAO,EAAE,6BAA6B,EAAE;SACzD,CAAC,CACH,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8DAA8D,EAAE,GAAG,EAAE;QACtE,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC;IAC9C,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoterCompetitionUtils.test.d.ts","sourceRoot":"","sources":["../../../src/utils/__tests__/promoterCompetitionUtils.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import { describe, expect, test } from "@jest/globals";
|
|
2
|
+
import { PromoterRewardMode, PromoterRewardType } from "../../definitions.js";
|
|
3
|
+
import { computePromoterCompetitionEconomics, formatPromoterRewardLabel, suggestPromoterSalesGoal, } from "../promoterCompetitionUtils.js";
|
|
4
|
+
describe("formatPromoterRewardLabel", () => {
|
|
5
|
+
test("formats a cash threshold as sales → dollars", () => {
|
|
6
|
+
expect(formatPromoterRewardLabel({
|
|
7
|
+
threshold: 5,
|
|
8
|
+
rewardType: PromoterRewardType.CASH,
|
|
9
|
+
rewardAmountCents: 1500,
|
|
10
|
+
})).toBe("5 sales → $15");
|
|
11
|
+
});
|
|
12
|
+
test("uses Top promoter for rank 1 and description for non-cash", () => {
|
|
13
|
+
expect(formatPromoterRewardLabel({
|
|
14
|
+
rank: 1,
|
|
15
|
+
rewardType: PromoterRewardType.TICKET,
|
|
16
|
+
rewardDescription: "VIP access",
|
|
17
|
+
})).toBe("Top promoter → VIP access");
|
|
18
|
+
});
|
|
19
|
+
test("uses Top N promoter for rank > 1 and the reward type when there is no description", () => {
|
|
20
|
+
expect(formatPromoterRewardLabel({
|
|
21
|
+
rank: 3,
|
|
22
|
+
rewardType: PromoterRewardType.TABLE,
|
|
23
|
+
})).toBe("Top 3 promoter → TABLE");
|
|
24
|
+
});
|
|
25
|
+
test("uses ? sales when threshold is missing", () => {
|
|
26
|
+
expect(formatPromoterRewardLabel({
|
|
27
|
+
rewardType: PromoterRewardType.CREDIT,
|
|
28
|
+
rewardAmountCents: 2000,
|
|
29
|
+
})).toBe("? sales → $20");
|
|
30
|
+
});
|
|
31
|
+
});
|
|
32
|
+
describe("computePromoterCompetitionEconomics", () => {
|
|
33
|
+
const cash5 = {
|
|
34
|
+
threshold: 5,
|
|
35
|
+
rewardType: PromoterRewardType.CASH,
|
|
36
|
+
rewardAmountCents: 1000,
|
|
37
|
+
};
|
|
38
|
+
const cash10 = {
|
|
39
|
+
threshold: 10,
|
|
40
|
+
rewardType: PromoterRewardType.CASH,
|
|
41
|
+
rewardAmountCents: 4000,
|
|
42
|
+
};
|
|
43
|
+
const rankCash = {
|
|
44
|
+
rank: 1,
|
|
45
|
+
rewardType: PromoterRewardType.CASH,
|
|
46
|
+
rewardAmountCents: 5000,
|
|
47
|
+
};
|
|
48
|
+
const ticket = {
|
|
49
|
+
threshold: 3,
|
|
50
|
+
rewardType: PromoterRewardType.TICKET,
|
|
51
|
+
rewardDescription: "GA ticket",
|
|
52
|
+
};
|
|
53
|
+
test("TOTAL_AT_MILESTONE uses the highest threshold cash plus all rank cash", () => {
|
|
54
|
+
const result = computePromoterCompetitionEconomics({
|
|
55
|
+
ticketPriceCents: 2000,
|
|
56
|
+
salesGoal: 50,
|
|
57
|
+
milestones: [cash5, cash10, rankCash, ticket],
|
|
58
|
+
rewardMode: PromoterRewardMode.TOTAL_AT_MILESTONE,
|
|
59
|
+
});
|
|
60
|
+
expect(result.grossPotentialRevenueCents).toBe(100000);
|
|
61
|
+
expect(result.maxCashRewardExposureCents).toBe(9000);
|
|
62
|
+
expect(result.effectiveAcquisitionCostPct).toBe(9);
|
|
63
|
+
expect(result.estimatedNetRevenueCents).toBe(91000);
|
|
64
|
+
expect(result.rewardBreakdown.map((row) => row.label)).toEqual([
|
|
65
|
+
"3 sales → GA ticket",
|
|
66
|
+
"5 sales → $10",
|
|
67
|
+
"10 sales → $40",
|
|
68
|
+
"Top promoter → $50",
|
|
69
|
+
]);
|
|
70
|
+
});
|
|
71
|
+
test("ADDITIVE stacks every threshold cash and still adds rank cash", () => {
|
|
72
|
+
const result = computePromoterCompetitionEconomics({
|
|
73
|
+
ticketPriceCents: 2000,
|
|
74
|
+
salesGoal: 50,
|
|
75
|
+
milestones: [cash5, cash10, rankCash],
|
|
76
|
+
rewardMode: PromoterRewardMode.ADDITIVE,
|
|
77
|
+
});
|
|
78
|
+
expect(result.maxCashRewardExposureCents).toBe(10000);
|
|
79
|
+
});
|
|
80
|
+
test("returns 0% acquisition cost when there is no gross revenue", () => {
|
|
81
|
+
const result = computePromoterCompetitionEconomics({
|
|
82
|
+
ticketPriceCents: 0,
|
|
83
|
+
salesGoal: 0,
|
|
84
|
+
milestones: [cash5],
|
|
85
|
+
rewardMode: PromoterRewardMode.ADDITIVE,
|
|
86
|
+
});
|
|
87
|
+
expect(result.effectiveAcquisitionCostPct).toBe(0);
|
|
88
|
+
expect(result.maxCashRewardExposureCents).toBe(1000);
|
|
89
|
+
expect(result.estimatedNetRevenueCents).toBe(-1000);
|
|
90
|
+
});
|
|
91
|
+
});
|
|
92
|
+
describe("suggestPromoterSalesGoal", () => {
|
|
93
|
+
test("returns null when capacity is missing, zero, or already sold out", () => {
|
|
94
|
+
expect(suggestPromoterSalesGoal({ capacity: null, ticketsSold: 0 })).toBeNull();
|
|
95
|
+
expect(suggestPromoterSalesGoal({ capacity: 0, ticketsSold: 0 })).toBeNull();
|
|
96
|
+
expect(suggestPromoterSalesGoal({ capacity: 40, ticketsSold: 40 })).toBeNull();
|
|
97
|
+
});
|
|
98
|
+
test("treats null ticketsSold as 0 and snaps 50% remaining to a benchmark", () => {
|
|
99
|
+
expect(suggestPromoterSalesGoal({ capacity: 100, ticketsSold: null })).toBe(50);
|
|
100
|
+
expect(suggestPromoterSalesGoal({ capacity: 40, ticketsSold: 0 })).toBe(25);
|
|
101
|
+
expect(suggestPromoterSalesGoal({ capacity: 400, ticketsSold: 0 })).toBe(200);
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
//# sourceMappingURL=promoterCompetitionUtils.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoterCompetitionUtils.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/promoterCompetitionUtils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from "@jest/globals";
|
|
2
|
-
import { BASH_DETAIL_URL, BASH_EVENT_WIZARD_HOW_MAJOR_STEP, BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT, BASH_EVENT_WIZARD_PATH_PREFIX, } from "../../definitions.js";
|
|
3
|
-
import { generateSlug, generateUniqueSlug, generateBashDetailUrl, getPublicBashDetailPath, getPublicBashMemoriesPath, getBashEventWizardStepPath, getBashEventWizardPayoutStepPath, parseBashUrlParams, validateSlug, } from "../slugUtils.js";
|
|
2
|
+
import { BASH_DETAIL_URL, BASH_EVENT_WIZARD_HOW_MAJOR_STEP, BASH_EVENT_WIZARD_HOW_SUBSTEP, BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT, BASH_EVENT_WIZARD_MAJOR, BASH_EVENT_WIZARD_PATH_PREFIX, BASH_EVENT_WIZARD_TEMPLATES_SUBSTEP, BASH_EVENT_WIZARD_WHAT_SUBSTEP, } from "../../definitions.js";
|
|
3
|
+
import { generateSlug, generateUniqueSlug, generateBashDetailUrl, getPublicBashDetailPath, getPublicBashMemoriesPath, getBashEventWizardStepPath, getBashEventWizardPayoutStepPath, getBashEventWizardStartPath, parseBashUrlParams, validateSlug, } from "../slugUtils.js";
|
|
4
4
|
describe("generateSlug", () => {
|
|
5
5
|
test("lowercases and slugifies a title", () => {
|
|
6
6
|
expect(generateSlug("Summer Bash 2026!")).toBe("summer-bash-2026");
|
|
@@ -67,6 +67,33 @@ describe("getBashEventWizardPayoutStepPath", () => {
|
|
|
67
67
|
test("returns How → Payout step path", () => {
|
|
68
68
|
expect(getBashEventWizardPayoutStepPath("evt-1")).toBe(`${BASH_EVENT_WIZARD_PATH_PREFIX}/evt-1/${BASH_EVENT_WIZARD_HOW_MAJOR_STEP}/${BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT}`);
|
|
69
69
|
});
|
|
70
|
+
test("How substep indices match host-flow order", () => {
|
|
71
|
+
expect(BASH_EVENT_WIZARD_HOW_SUBSTEP.PRICE).toBe(0);
|
|
72
|
+
expect(BASH_EVENT_WIZARD_HOW_SUBSTEP.APPLICATION).toBe(1);
|
|
73
|
+
expect(BASH_EVENT_WIZARD_HOW_SUBSTEP.PROMO_CODES).toBe(2);
|
|
74
|
+
expect(BASH_EVENT_WIZARD_HOW_SUBSTEP.TASKS).toBe(8);
|
|
75
|
+
expect(BASH_EVENT_WIZARD_HOW_SUBSTEP.PAYOUT).toBe(9);
|
|
76
|
+
expect(BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT).toBe(BASH_EVENT_WIZARD_HOW_SUBSTEP.PAYOUT);
|
|
77
|
+
});
|
|
78
|
+
test("major and What substep indices stay pinned", () => {
|
|
79
|
+
expect(BASH_EVENT_WIZARD_MAJOR.TEMPLATES).toBe(0);
|
|
80
|
+
expect(BASH_EVENT_WIZARD_MAJOR.WHO).toBe(2);
|
|
81
|
+
expect(BASH_EVENT_WIZARD_MAJOR.WHAT).toBe(3);
|
|
82
|
+
expect(BASH_EVENT_WIZARD_MAJOR.HOW).toBe(7);
|
|
83
|
+
expect(BASH_EVENT_WIZARD_MAJOR.FINISH).toBe(8);
|
|
84
|
+
expect(BASH_EVENT_WIZARD_WHAT_SUBSTEP.TITLE).toBe(0);
|
|
85
|
+
expect(BASH_EVENT_WIZARD_WHAT_SUBSTEP.TYPE).toBe(BASH_EVENT_WIZARD_WHAT_SUBSTEP.TITLE);
|
|
86
|
+
expect(BASH_EVENT_WIZARD_WHAT_SUBSTEP.VIBE_DRESS).toBe(1);
|
|
87
|
+
expect(BASH_EVENT_WIZARD_WHAT_SUBSTEP.SCHEDULE).toBe(2);
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
describe("getBashEventWizardStartPath", () => {
|
|
91
|
+
test("defaults to the new draft at Templates", () => {
|
|
92
|
+
expect(getBashEventWizardStartPath()).toBe(`${BASH_EVENT_WIZARD_PATH_PREFIX}/new/${BASH_EVENT_WIZARD_MAJOR.TEMPLATES}/${BASH_EVENT_WIZARD_TEMPLATES_SUBSTEP.START}`);
|
|
93
|
+
});
|
|
94
|
+
test("uses an event id when provided", () => {
|
|
95
|
+
expect(getBashEventWizardStartPath("evt-1")).toBe(`${BASH_EVENT_WIZARD_PATH_PREFIX}/evt-1/${BASH_EVENT_WIZARD_MAJOR.TEMPLATES}/${BASH_EVENT_WIZARD_TEMPLATES_SUBSTEP.START}`);
|
|
96
|
+
});
|
|
70
97
|
});
|
|
71
98
|
describe("parseBashUrlParams", () => {
|
|
72
99
|
test("parses id-slug format", () => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slugUtils.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/slugUtils.test.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AACvD,OAAO,EACL,eAAe,EACf,gCAAgC,EAChC,oCAAoC,EACpC,6BAA6B,
|
|
1
|
+
{"version":3,"file":"slugUtils.test.js","sourceRoot":"","sources":["../../../src/utils/__tests__/slugUtils.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { getUserName } from "./apiUtils.js";
|
|
2
|
+
export type BashHostIdentityInput = {
|
|
3
|
+
hostedByService?: {
|
|
4
|
+
serviceName?: string | null;
|
|
5
|
+
coverPhoto?: string | null;
|
|
6
|
+
} | null;
|
|
7
|
+
organization?: {
|
|
8
|
+
name?: string | null;
|
|
9
|
+
logoUrl?: string | null;
|
|
10
|
+
} | null;
|
|
11
|
+
/** `null` is treated the same as `undefined` (no creator info). DB relations are nullable. */
|
|
12
|
+
creator?: Parameters<typeof getUserName>[0] | null;
|
|
13
|
+
};
|
|
14
|
+
/** Public host name: service, then org, then the person. */
|
|
15
|
+
export declare function getBashHostDisplayName(input: BashHostIdentityInput): string;
|
|
16
|
+
/** Service cover or org logo when Host as is not Self. Caller falls back to the person. */
|
|
17
|
+
export declare function getBashHostAvatarUrl(input: BashHostIdentityInput): string | null;
|
|
18
|
+
//# sourceMappingURL=bashHostIdentity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashHostIdentity.d.ts","sourceRoot":"","sources":["../../src/utils/bashHostIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAE5C,MAAM,MAAM,qBAAqB,GAAG;IAClC,eAAe,CAAC,EAAE;QAAE,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACrF,YAAY,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,8FAA8F;IAC9F,OAAO,CAAC,EAAE,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC;CACpD,CAAC;AAOF,4DAA4D;AAC5D,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAM3E;AAED,2FAA2F;AAC3F,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,GAAG,IAAI,CAKhF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { getUserName } from "./apiUtils.js";
|
|
2
|
+
function trimmedOrNull(value) {
|
|
3
|
+
const trimmed = value?.trim();
|
|
4
|
+
return trimmed ? trimmed : null;
|
|
5
|
+
}
|
|
6
|
+
/** Public host name: service, then org, then the person. */
|
|
7
|
+
export function getBashHostDisplayName(input) {
|
|
8
|
+
return (trimmedOrNull(input.hostedByService?.serviceName) ??
|
|
9
|
+
trimmedOrNull(input.organization?.name) ??
|
|
10
|
+
getUserName(input.creator ?? undefined));
|
|
11
|
+
}
|
|
12
|
+
/** Service cover or org logo when Host as is not Self. Caller falls back to the person. */
|
|
13
|
+
export function getBashHostAvatarUrl(input) {
|
|
14
|
+
return (trimmedOrNull(input.hostedByService?.coverPhoto) ??
|
|
15
|
+
trimmedOrNull(input.organization?.logoUrl));
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=bashHostIdentity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bashHostIdentity.js","sourceRoot":"","sources":["../../src/utils/bashHostIdentity.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAS5C,SAAS,aAAa,CAAC,KAAgC;IACrD,MAAM,OAAO,GAAG,KAAK,EAAE,IAAI,EAAE,CAAC;IAC9B,OAAO,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAClC,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,sBAAsB,CAAC,KAA4B;IACjE,OAAO,CACL,aAAa,CAAC,KAAK,CAAC,eAAe,EAAE,WAAW,CAAC;QACjD,aAAa,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC;QACvC,WAAW,CAAC,KAAK,CAAC,OAAO,IAAI,SAAS,CAAC,CACxC,CAAC;AACJ,CAAC;AAED,2FAA2F;AAC3F,MAAM,UAAU,oBAAoB,CAAC,KAA4B;IAC/D,OAAO,CACL,aAAa,CAAC,KAAK,CAAC,eAAe,EAAE,UAAU,CAAC;QAChD,aAAa,CAAC,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,CAC3C,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Promoter Competition — pure utility functions for the Street Team / Promoter
|
|
3
|
+
* Competition workstream.
|
|
4
|
+
*
|
|
5
|
+
* No side effects, no DB imports — safe to import in bash-app (browser) and in api.
|
|
6
|
+
*/
|
|
7
|
+
import { PromoterRewardMode, PromoterRewardType } from '../definitions.js';
|
|
8
|
+
export interface PromoterMilestoneInput {
|
|
9
|
+
threshold?: number | null;
|
|
10
|
+
rank?: number | null;
|
|
11
|
+
rewardType: PromoterRewardType;
|
|
12
|
+
rewardAmountCents?: number | null;
|
|
13
|
+
rewardDescription?: string | null;
|
|
14
|
+
}
|
|
15
|
+
export interface PromoterCompetitionEconomics {
|
|
16
|
+
grossPotentialRevenueCents: number;
|
|
17
|
+
maxCashRewardExposureCents: number;
|
|
18
|
+
/** 0–100 range; maxCashReward / grossRevenue × 100, rounded to 1 decimal. */
|
|
19
|
+
effectiveAcquisitionCostPct: number;
|
|
20
|
+
/** gross − maxCashReward */
|
|
21
|
+
estimatedNetRevenueCents: number;
|
|
22
|
+
rewardBreakdown: Array<{
|
|
23
|
+
/** e.g. "5 sales → $15" or "Top 1 promoter → VIP access" */
|
|
24
|
+
label: string;
|
|
25
|
+
rewardAmountCents: number | null;
|
|
26
|
+
}>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Produces a single human-readable label for a promoter milestone.
|
|
30
|
+
*
|
|
31
|
+
* Examples:
|
|
32
|
+
* - threshold=5, CASH, rewardAmountCents=1500 → "5 sales → $15"
|
|
33
|
+
* - rank=1, TICKET, rewardDescription="VIP access" → "Top 1 promoter → VIP access"
|
|
34
|
+
* - threshold=10, TICKET, no description → "10 sales → TICKET"
|
|
35
|
+
*/
|
|
36
|
+
export declare function formatPromoterRewardLabel(milestone: {
|
|
37
|
+
threshold?: number | null;
|
|
38
|
+
rank?: number | null;
|
|
39
|
+
rewardType: PromoterRewardType;
|
|
40
|
+
rewardAmountCents?: number | null;
|
|
41
|
+
rewardDescription?: string | null;
|
|
42
|
+
}): string;
|
|
43
|
+
/**
|
|
44
|
+
* Pure economics calculator for a PROMOTER competition.
|
|
45
|
+
*
|
|
46
|
+
* Lets hosts sanity-check their milestone structure before publishing:
|
|
47
|
+
* how much revenue could the event generate and what is the max cash
|
|
48
|
+
* payout exposure?
|
|
49
|
+
*
|
|
50
|
+
* Rank-based (rank != null) CASH/CREDIT milestones are always added to the
|
|
51
|
+
* max cash exposure regardless of rewardMode because they represent real
|
|
52
|
+
* monetary obligations (just settled at competition close, not per-sale).
|
|
53
|
+
*/
|
|
54
|
+
export declare function computePromoterCompetitionEconomics(params: {
|
|
55
|
+
ticketPriceCents: number;
|
|
56
|
+
salesGoal: number;
|
|
57
|
+
milestones: PromoterMilestoneInput[];
|
|
58
|
+
rewardMode: PromoterRewardMode;
|
|
59
|
+
}): PromoterCompetitionEconomics;
|
|
60
|
+
/**
|
|
61
|
+
* Suggests a sales goal for the promoter competition wizard.
|
|
62
|
+
*
|
|
63
|
+
* Logic: take 40–60% of remaining capacity (capacity − ticketsSold), then snap
|
|
64
|
+
* to the nearest common benchmark in [25, 50, 75, 100, 150, 200]. Returns null
|
|
65
|
+
* when data is insufficient (null inputs or capacity ≤ 0).
|
|
66
|
+
*/
|
|
67
|
+
export declare function suggestPromoterSalesGoal(params: {
|
|
68
|
+
capacity: number | null;
|
|
69
|
+
ticketsSold: number | null;
|
|
70
|
+
}): number | null;
|
|
71
|
+
/**
|
|
72
|
+
* Produces a human-readable promoter reputation label based on lifetime stats.
|
|
73
|
+
* Returns null if the promoter has no completed events yet.
|
|
74
|
+
*
|
|
75
|
+
* Priority order (first match wins):
|
|
76
|
+
* 1. Competition winner (rank=1 achieved)
|
|
77
|
+
* 2. 100+ lifetime tickets sold
|
|
78
|
+
* 3. Repeat collaborator (worked with 2+ organizers more than once)
|
|
79
|
+
* 4. Experienced promoter (3+ events promoted)
|
|
80
|
+
* 5. Top seller within a competition (any milestone reached)
|
|
81
|
+
*/
|
|
82
|
+
export declare function getPromoterReputationLabel(stats: {
|
|
83
|
+
lifetimeQualifiedTickets: number;
|
|
84
|
+
totalCompetitionsWon: number;
|
|
85
|
+
totalEventsPromoted: number;
|
|
86
|
+
repeatOrganizerCount: number;
|
|
87
|
+
totalMilestonesReached?: number;
|
|
88
|
+
}): string | null;
|
|
89
|
+
//# sourceMappingURL=promoterCompetitionUtils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoterCompetitionUtils.d.ts","sourceRoot":"","sources":["../../src/utils/promoterCompetitionUtils.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAM3E,MAAM,WAAW,sBAAsB;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,4BAA4B;IAC3C,0BAA0B,EAAE,MAAM,CAAC;IACnC,0BAA0B,EAAE,MAAM,CAAC;IACnC,6EAA6E;IAC7E,2BAA2B,EAAE,MAAM,CAAC;IACpC,4BAA4B;IAC5B,wBAAwB,EAAE,MAAM,CAAC;IACjC,eAAe,EAAE,KAAK,CAAC;QACrB,4DAA4D;QAC5D,KAAK,EAAE,MAAM,CAAC;QACd,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;KAClC,CAAC,CAAC;CACJ;AAMD;;;;;;;GAOG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE;IACnD,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,iBAAiB,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACnC,GAAG,MAAM,CAgBT;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,mCAAmC,CAAC,MAAM,EAAE;IAC1D,gBAAgB,EAAE,MAAM,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,sBAAsB,EAAE,CAAC;IACrC,UAAU,EAAE,kBAAkB,CAAC;CAChC,GAAG,4BAA4B,CAqE/B;AAQD;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE;IAC/C,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B,GAAG,MAAM,GAAG,IAAI,CAwBhB;AAMD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CAAC,KAAK,EAAE;IAChD,wBAAwB,EAAE,MAAM,CAAC;IACjC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,oBAAoB,EAAE,MAAM,CAAC;IAC7B,sBAAsB,CAAC,EAAE,MAAM,CAAC;CACjC,GAAG,MAAM,GAAG,IAAI,CAUhB"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Promoter Competition — pure utility functions for the Street Team / Promoter
|
|
3
|
+
* Competition workstream.
|
|
4
|
+
*
|
|
5
|
+
* No side effects, no DB imports — safe to import in bash-app (browser) and in api.
|
|
6
|
+
*/
|
|
7
|
+
import { PromoterRewardMode, PromoterRewardType } from '../definitions.js';
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
// formatPromoterRewardLabel
|
|
10
|
+
// ---------------------------------------------------------------------------
|
|
11
|
+
/**
|
|
12
|
+
* Produces a single human-readable label for a promoter milestone.
|
|
13
|
+
*
|
|
14
|
+
* Examples:
|
|
15
|
+
* - threshold=5, CASH, rewardAmountCents=1500 → "5 sales → $15"
|
|
16
|
+
* - rank=1, TICKET, rewardDescription="VIP access" → "Top 1 promoter → VIP access"
|
|
17
|
+
* - threshold=10, TICKET, no description → "10 sales → TICKET"
|
|
18
|
+
*/
|
|
19
|
+
export function formatPromoterRewardLabel(milestone) {
|
|
20
|
+
const isCashOrCredit = milestone.rewardType === PromoterRewardType.CASH ||
|
|
21
|
+
milestone.rewardType === PromoterRewardType.CREDIT;
|
|
22
|
+
const rewardDisplay = isCashOrCredit && milestone.rewardAmountCents != null
|
|
23
|
+
? `$${(milestone.rewardAmountCents / 100).toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 2 })}`
|
|
24
|
+
: milestone.rewardDescription ?? milestone.rewardType;
|
|
25
|
+
if (milestone.rank != null) {
|
|
26
|
+
const ordinal = milestone.rank === 1 ? 'Top promoter' : `Top ${milestone.rank} promoter`;
|
|
27
|
+
return `${ordinal} → ${rewardDisplay}`;
|
|
28
|
+
}
|
|
29
|
+
const threshold = milestone.threshold ?? '?';
|
|
30
|
+
return `${threshold} sales → ${rewardDisplay}`;
|
|
31
|
+
}
|
|
32
|
+
// ---------------------------------------------------------------------------
|
|
33
|
+
// computePromoterCompetitionEconomics
|
|
34
|
+
// ---------------------------------------------------------------------------
|
|
35
|
+
/**
|
|
36
|
+
* Pure economics calculator for a PROMOTER competition.
|
|
37
|
+
*
|
|
38
|
+
* Lets hosts sanity-check their milestone structure before publishing:
|
|
39
|
+
* how much revenue could the event generate and what is the max cash
|
|
40
|
+
* payout exposure?
|
|
41
|
+
*
|
|
42
|
+
* Rank-based (rank != null) CASH/CREDIT milestones are always added to the
|
|
43
|
+
* max cash exposure regardless of rewardMode because they represent real
|
|
44
|
+
* monetary obligations (just settled at competition close, not per-sale).
|
|
45
|
+
*/
|
|
46
|
+
export function computePromoterCompetitionEconomics(params) {
|
|
47
|
+
const { ticketPriceCents, salesGoal, milestones, rewardMode } = params;
|
|
48
|
+
const grossPotentialRevenueCents = ticketPriceCents * salesGoal;
|
|
49
|
+
// Partition milestones into threshold-based and rank-based.
|
|
50
|
+
const isCash = (m) => m.rewardType === PromoterRewardType.CASH ||
|
|
51
|
+
m.rewardType === PromoterRewardType.CREDIT;
|
|
52
|
+
const thresholdCash = milestones.filter((m) => m.rank == null && m.threshold != null && isCash(m) && m.rewardAmountCents != null);
|
|
53
|
+
const rankCash = milestones.filter((m) => m.rank != null && isCash(m) && m.rewardAmountCents != null);
|
|
54
|
+
let thresholdExposure = 0;
|
|
55
|
+
if (rewardMode === PromoterRewardMode.TOTAL_AT_MILESTONE) {
|
|
56
|
+
// Only the highest single threshold reward is effective at once.
|
|
57
|
+
thresholdExposure = Math.max(0, ...thresholdCash.map((m) => m.rewardAmountCents ?? 0));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
// ADDITIVE — every threshold reward stacks.
|
|
61
|
+
thresholdExposure = thresholdCash.reduce((sum, m) => sum + (m.rewardAmountCents ?? 0), 0);
|
|
62
|
+
}
|
|
63
|
+
// Rank-based cash rewards always add on top (regardless of mode).
|
|
64
|
+
const rankExposure = rankCash.reduce((sum, m) => sum + (m.rewardAmountCents ?? 0), 0);
|
|
65
|
+
const maxCashRewardExposureCents = thresholdExposure + rankExposure;
|
|
66
|
+
const effectiveAcquisitionCostPct = grossPotentialRevenueCents > 0
|
|
67
|
+
? Math.round((maxCashRewardExposureCents / grossPotentialRevenueCents) * 1000) / 10
|
|
68
|
+
: 0;
|
|
69
|
+
const estimatedNetRevenueCents = grossPotentialRevenueCents - maxCashRewardExposureCents;
|
|
70
|
+
// Build rewardBreakdown — threshold milestones sorted ascending, rank milestones last.
|
|
71
|
+
const sortedMilestones = [...milestones].sort((a, b) => {
|
|
72
|
+
const aIsRank = a.rank != null;
|
|
73
|
+
const bIsRank = b.rank != null;
|
|
74
|
+
if (aIsRank && !bIsRank)
|
|
75
|
+
return 1;
|
|
76
|
+
if (!aIsRank && bIsRank)
|
|
77
|
+
return -1;
|
|
78
|
+
if (!aIsRank && !bIsRank) {
|
|
79
|
+
return (a.threshold ?? Infinity) - (b.threshold ?? Infinity);
|
|
80
|
+
}
|
|
81
|
+
// Both rank-based — sort by rank ascending.
|
|
82
|
+
return (a.rank ?? Infinity) - (b.rank ?? Infinity);
|
|
83
|
+
});
|
|
84
|
+
const rewardBreakdown = sortedMilestones.map((m) => ({
|
|
85
|
+
label: formatPromoterRewardLabel(m),
|
|
86
|
+
rewardAmountCents: m.rewardAmountCents ?? null,
|
|
87
|
+
}));
|
|
88
|
+
return {
|
|
89
|
+
grossPotentialRevenueCents,
|
|
90
|
+
maxCashRewardExposureCents,
|
|
91
|
+
effectiveAcquisitionCostPct,
|
|
92
|
+
estimatedNetRevenueCents,
|
|
93
|
+
rewardBreakdown,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// ---------------------------------------------------------------------------
|
|
97
|
+
// suggestPromoterSalesGoal
|
|
98
|
+
// ---------------------------------------------------------------------------
|
|
99
|
+
const SALES_GOAL_SNAP_POINTS = [25, 50, 75, 100, 150, 200];
|
|
100
|
+
/**
|
|
101
|
+
* Suggests a sales goal for the promoter competition wizard.
|
|
102
|
+
*
|
|
103
|
+
* Logic: take 40–60% of remaining capacity (capacity − ticketsSold), then snap
|
|
104
|
+
* to the nearest common benchmark in [25, 50, 75, 100, 150, 200]. Returns null
|
|
105
|
+
* when data is insufficient (null inputs or capacity ≤ 0).
|
|
106
|
+
*/
|
|
107
|
+
export function suggestPromoterSalesGoal(params) {
|
|
108
|
+
const { capacity, ticketsSold } = params;
|
|
109
|
+
if (capacity == null || capacity <= 0)
|
|
110
|
+
return null;
|
|
111
|
+
const sold = ticketsSold ?? 0;
|
|
112
|
+
const remaining = Math.max(0, capacity - sold);
|
|
113
|
+
if (remaining === 0)
|
|
114
|
+
return null;
|
|
115
|
+
// Target the midpoint of 40–60% of remaining.
|
|
116
|
+
const target = remaining * 0.5;
|
|
117
|
+
// Snap to the nearest benchmark.
|
|
118
|
+
let best = SALES_GOAL_SNAP_POINTS[0];
|
|
119
|
+
let bestDist = Math.abs(target - best);
|
|
120
|
+
for (const snap of SALES_GOAL_SNAP_POINTS) {
|
|
121
|
+
const dist = Math.abs(target - snap);
|
|
122
|
+
if (dist < bestDist) {
|
|
123
|
+
bestDist = dist;
|
|
124
|
+
best = snap;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return best;
|
|
128
|
+
}
|
|
129
|
+
// ---------------------------------------------------------------------------
|
|
130
|
+
// getPromoterReputationLabel
|
|
131
|
+
// ---------------------------------------------------------------------------
|
|
132
|
+
/**
|
|
133
|
+
* Produces a human-readable promoter reputation label based on lifetime stats.
|
|
134
|
+
* Returns null if the promoter has no completed events yet.
|
|
135
|
+
*
|
|
136
|
+
* Priority order (first match wins):
|
|
137
|
+
* 1. Competition winner (rank=1 achieved)
|
|
138
|
+
* 2. 100+ lifetime tickets sold
|
|
139
|
+
* 3. Repeat collaborator (worked with 2+ organizers more than once)
|
|
140
|
+
* 4. Experienced promoter (3+ events promoted)
|
|
141
|
+
* 5. Top seller within a competition (any milestone reached)
|
|
142
|
+
*/
|
|
143
|
+
export function getPromoterReputationLabel(stats) {
|
|
144
|
+
if (stats.totalEventsPromoted < 1)
|
|
145
|
+
return null;
|
|
146
|
+
if (stats.totalCompetitionsWon >= 1)
|
|
147
|
+
return 'Competition Winner';
|
|
148
|
+
if (stats.lifetimeQualifiedTickets >= 100)
|
|
149
|
+
return '100+ Tickets Sold';
|
|
150
|
+
if (stats.repeatOrganizerCount >= 2)
|
|
151
|
+
return 'Repeat Collaborator';
|
|
152
|
+
if (stats.totalEventsPromoted >= 3)
|
|
153
|
+
return 'Experienced Promoter';
|
|
154
|
+
if ((stats.totalMilestonesReached ?? 0) >= 1)
|
|
155
|
+
return 'Top Seller';
|
|
156
|
+
return null;
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=promoterCompetitionUtils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"promoterCompetitionUtils.js","sourceRoot":"","sources":["../../src/utils/promoterCompetitionUtils.ts"],"names":[],"mappings":"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"}
|
|
@@ -16,6 +16,8 @@ export declare function getPublicBashMemoriesPath(bashEventId: string, slug: str
|
|
|
16
16
|
export declare function getBashEventWizardStepPath(bashEventId: string, majorStep: number, subStep: number): string;
|
|
17
17
|
/** Host redirect target: "How" → Payout (Stripe Connect / ticket proceeds). */
|
|
18
18
|
export declare function getBashEventWizardPayoutStepPath(bashEventId: string): string;
|
|
19
|
+
/** Create / resume at Getting Started (Templates). Defaults to the `new` draft. */
|
|
20
|
+
export declare function getBashEventWizardStartPath(bashEventId?: string): string;
|
|
19
21
|
export declare function parseBashUrlParams(param: string): {
|
|
20
22
|
id: string;
|
|
21
23
|
slug: string | null;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slugUtils.d.ts","sourceRoot":"","sources":["../../src/utils/slugUtils.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"slugUtils.d.ts","sourceRoot":"","sources":["../../src/utils/slugUtils.ts"],"names":[],"mappings":"AAwCA,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMlD;AAED,wBAAsB,kBAAkB,CACtC,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,EACvE,SAAS,CAAC,EAAE,MAAM,GACjB,OAAO,CAAC,MAAM,CAAC,CAajB;AAED,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAE/E;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,MAAM,CAMR;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,GAC9B,MAAM,CAER;AAED,yFAAyF;AACzF,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED,+EAA+E;AAC/E,wBAAgB,gCAAgC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAM5E;AAED,mFAAmF;AACnF,wBAAgB,2BAA2B,CAAC,WAAW,SAAQ,GAAG,MAAM,CAMvE;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GAAG,IAAI,CAqB5F;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGlD"}
|
package/dist/utils/slugUtils.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as slugifyImport from "slugify";
|
|
2
|
-
import { BASH_DETAIL_URL, BASH_EVENT_WIZARD_HOW_MAJOR_STEP, BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT, BASH_EVENT_WIZARD_PATH_PREFIX, } from '../definitions.js';
|
|
2
|
+
import { BASH_DETAIL_URL, BASH_EVENT_WIZARD_HOW_MAJOR_STEP, BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT, BASH_EVENT_WIZARD_MAJOR, BASH_EVENT_WIZARD_PATH_PREFIX, BASH_EVENT_WIZARD_TEMPLATES_SUBSTEP, } from '../definitions.js';
|
|
3
3
|
function isSlugifyFn(value) {
|
|
4
4
|
return typeof value === "function";
|
|
5
5
|
}
|
|
@@ -67,6 +67,10 @@ export function getBashEventWizardStepPath(bashEventId, majorStep, subStep) {
|
|
|
67
67
|
export function getBashEventWizardPayoutStepPath(bashEventId) {
|
|
68
68
|
return getBashEventWizardStepPath(bashEventId, BASH_EVENT_WIZARD_HOW_MAJOR_STEP, BASH_EVENT_WIZARD_HOW_SUBSTEP_PAYOUT);
|
|
69
69
|
}
|
|
70
|
+
/** Create / resume at Getting Started (Templates). Defaults to the `new` draft. */
|
|
71
|
+
export function getBashEventWizardStartPath(bashEventId = "new") {
|
|
72
|
+
return getBashEventWizardStepPath(bashEventId, BASH_EVENT_WIZARD_MAJOR.TEMPLATES, BASH_EVENT_WIZARD_TEMPLATES_SUBSTEP.START);
|
|
73
|
+
}
|
|
70
74
|
export function parseBashUrlParams(param) {
|
|
71
75
|
// Expected format: "id-slug" where id is first part before first dash
|
|
72
76
|
const dashIndex = param.indexOf('-');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"slugUtils.js","sourceRoot":"","sources":["../../src/utils/slugUtils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,aAAa,MAAM,SAAS,CAAC;AACzC,OAAO,EACL,eAAe,EACf,gCAAgC,EAChC,oCAAoC,EACpC,6BAA6B,
|
|
1
|
+
{"version":3,"file":"slugUtils.js","sourceRoot":"","sources":["../../src/utils/slugUtils.ts"],"names":[],"mappings":"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"}
|