@dbx-tools/shared-generator 0.0.0-stage → 0.9.136

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.
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Browser-safe contracts for generated Databricks demo assets.
3
+ *
4
+ * @module
5
+ */
6
+ import { z } from "zod";
7
+ import { BrandPackageSchema } from "./brand.js";
8
+ import { KpiResearchResultSchema, ResearchedKpiSchema } from "./kpi.js";
9
+ const nonBlankString = z.string().trim().min(1);
10
+ const identifier = z.string().regex(/^[a-z][a-z0-9_]*$/, "Expected a lowercase SQL identifier.");
11
+ /** Presentation created after generated data is validated. */
12
+ export const PresentationModeSchema = z.enum(["dashboard", "genie"]);
13
+ /** Complete input for the governed generator workflow. */
14
+ export const GeneratorRequestSchema = z
15
+ .object({
16
+ company: nonBlankString.max(200).describe("Company or brand represented by the demo."),
17
+ purpose: nonBlankString.max(200).describe("Short purpose used in schema and asset names."),
18
+ queries: z
19
+ .array(nonBlankString.max(500))
20
+ .min(1)
21
+ .max(10)
22
+ .describe("Business questions that shape KPI research and generated data."),
23
+ website: z
24
+ .string()
25
+ .url()
26
+ .optional()
27
+ .describe("Known company website for brand disambiguation."),
28
+ presentation: PresentationModeSchema.default("dashboard").describe("Dashboard with automatic companion Genie, or standalone Genie without a dashboard."),
29
+ rowCount: z
30
+ .number()
31
+ .int()
32
+ .min(1_000)
33
+ .max(100_000)
34
+ .default(50_000)
35
+ .describe("Rows generated in the primary fact table."),
36
+ })
37
+ .strict()
38
+ .describe("Request for a per-user Databricks demo data environment.");
39
+ /** Supported deterministic column generators. */
40
+ export const GeneratedColumnSchema = z.discriminatedUnion("generator", [
41
+ z
42
+ .object({
43
+ name: identifier.describe("Column name."),
44
+ generator: z.literal("id"),
45
+ description: nonBlankString.describe("Column business meaning."),
46
+ })
47
+ .strict(),
48
+ z
49
+ .object({
50
+ name: identifier.describe("Column name."),
51
+ generator: z.literal("date"),
52
+ description: nonBlankString.describe("Column business meaning."),
53
+ days: z.number().int().min(30).max(1_095).describe("Generated history window in days."),
54
+ })
55
+ .strict(),
56
+ z
57
+ .object({
58
+ name: identifier.describe("Column name."),
59
+ generator: z.literal("category"),
60
+ description: nonBlankString.describe("Column business meaning."),
61
+ values: z.array(nonBlankString.max(80)).min(2).max(12).describe("Skewed category values."),
62
+ })
63
+ .strict(),
64
+ z
65
+ .object({
66
+ name: identifier.describe("Column name."),
67
+ generator: z.literal("number"),
68
+ description: nonBlankString.describe("Column business meaning."),
69
+ minimum: z.number().describe("Minimum generated value."),
70
+ maximum: z.number().describe("Maximum generated value."),
71
+ decimals: z.number().int().min(0).max(4).default(2).describe("Decimal precision."),
72
+ })
73
+ .strict(),
74
+ z
75
+ .object({
76
+ name: identifier.describe("Column name."),
77
+ generator: z.literal("boolean"),
78
+ description: nonBlankString.describe("Column business meaning."),
79
+ trueProbability: z.number().min(0.01).max(0.99).describe("Share of true rows."),
80
+ })
81
+ .strict(),
82
+ ]);
83
+ /** KPI binding compiled into validation SQL and dashboard measures. */
84
+ export const GeneratedMetricSchema = ResearchedKpiSchema.extend({
85
+ aggregation: z
86
+ .enum(["count", "sum", "average"])
87
+ .describe("Safe aggregate compiled by the generator."),
88
+ column: identifier.optional().describe("Numeric source column; omitted for count."),
89
+ }).strict();
90
+ /** Structured plan compiled into SQL and presentation assets. */
91
+ export const GeneratorPlanSchema = z
92
+ .object({
93
+ table: identifier.describe("Primary generated Delta table name."),
94
+ rowCount: z.number().int().min(1_000).max(100_000).describe("Rows to generate."),
95
+ columns: z
96
+ .array(GeneratedColumnSchema)
97
+ .min(4)
98
+ .max(16)
99
+ .describe("Typed deterministic column generators."),
100
+ metrics: z.array(GeneratedMetricSchema).min(1).max(6).describe("Dashboard and Genie KPIs."),
101
+ story: nonBlankString.describe("Business anomaly and impact represented in the data."),
102
+ sampleQuestions: z
103
+ .array(nonBlankString.max(300))
104
+ .min(3)
105
+ .max(8)
106
+ .describe("Questions supported by the generated table."),
107
+ })
108
+ .strict()
109
+ .superRefine((value, ctx) => {
110
+ const names = new Set();
111
+ for (const [index, column] of value.columns.entries()) {
112
+ if (names.has(column.name)) {
113
+ ctx.addIssue({
114
+ code: "custom",
115
+ path: ["columns", index, "name"],
116
+ message: "Generated column names must be unique.",
117
+ });
118
+ }
119
+ names.add(column.name);
120
+ }
121
+ if (!value.columns.some(({ generator }) => generator === "id")) {
122
+ ctx.addIssue({ code: "custom", path: ["columns"], message: "An id column is required." });
123
+ }
124
+ if (!value.columns.some(({ generator }) => generator === "date")) {
125
+ ctx.addIssue({ code: "custom", path: ["columns"], message: "A date column is required." });
126
+ }
127
+ if (!value.columns.some(({ generator }) => generator === "category")) {
128
+ ctx.addIssue({
129
+ code: "custom",
130
+ path: ["columns"],
131
+ message: "A category column is required.",
132
+ });
133
+ }
134
+ const numeric = new Set(value.columns.filter(({ generator }) => generator === "number").map(({ name }) => name));
135
+ for (const [index, metric] of value.metrics.entries()) {
136
+ if (metric.aggregation !== "count" && (!metric.column || !numeric.has(metric.column))) {
137
+ ctx.addIssue({
138
+ code: "custom",
139
+ path: ["metrics", index, "column"],
140
+ message: "Sum and average metrics require a generated numeric column.",
141
+ });
142
+ }
143
+ }
144
+ })
145
+ .describe("Validated plan for deterministic synthetic data and analytics assets.");
146
+ /** Input for the standalone structured data-planning tool. */
147
+ export const PlanGeneratorDataRequestSchema = z
148
+ .object({
149
+ request: GeneratorRequestSchema,
150
+ brand: BrandPackageSchema,
151
+ kpiResearch: KpiResearchResultSchema,
152
+ })
153
+ .strict()
154
+ .describe("Inputs needed to build a typed generator plan.");
155
+ /** Location and trusted identity for one generated schema. */
156
+ export const GeneratedSchemaSchema = z
157
+ .object({
158
+ catalog: identifier.describe("Configured Unity Catalog."),
159
+ schema: identifier.describe("Per-user generated schema."),
160
+ fullName: nonBlankString.describe("Quoted-safe catalog.schema display name."),
161
+ principal: nonBlankString.describe("Trusted OBO Databricks user name."),
162
+ })
163
+ .strict()
164
+ .describe("Provisioned per-user Unity Catalog schema.");
165
+ /** Input for per-user schema provisioning. */
166
+ export const ProvisionGeneratorSchemaRequestSchema = z
167
+ .object({
168
+ request: GeneratorRequestSchema.pick({ company: true, purpose: true }),
169
+ })
170
+ .strict()
171
+ .describe("Request to provision the active user's generated schema.");
172
+ /** Input for generated data materialization. */
173
+ export const MaterializeGeneratorDataRequestSchema = z
174
+ .object({
175
+ location: GeneratedSchemaSchema,
176
+ plan: GeneratorPlanSchema,
177
+ })
178
+ .strict()
179
+ .describe("Request to materialize and validate generated Delta data.");
180
+ /** Created tables and KPI validation statements. */
181
+ export const MaterializedGeneratorDataSchema = z
182
+ .object({
183
+ tables: z.array(nonBlankString).min(1).describe("Created fully qualified Delta tables."),
184
+ validationStatements: z
185
+ .record(identifier, nonBlankString)
186
+ .describe("Statement IDs keyed by validated KPI name."),
187
+ })
188
+ .strict()
189
+ .describe("Materialized and validated generated data.");
190
+ /** Input shared by dashboard and standalone Genie creation tools. */
191
+ export const CreateGeneratorPresentationRequestSchema = z
192
+ .object({
193
+ request: GeneratorRequestSchema.pick({
194
+ company: true,
195
+ purpose: true,
196
+ }),
197
+ location: GeneratedSchemaSchema,
198
+ plan: GeneratorPlanSchema,
199
+ brand: BrandPackageSchema,
200
+ })
201
+ .strict()
202
+ .describe("Request to create a presentation asset over generated data.");
203
+ /** Dashboard output with its automatic companion Genie Agent. */
204
+ export const GeneratedDashboardSchema = z
205
+ .object({
206
+ dashboardId: nonBlankString.describe("Created Lakeview dashboard ID."),
207
+ path: nonBlankString.optional().describe("Workspace path, when returned."),
208
+ companionGenie: z.literal("AUTO").describe("Dashboard-published companion Genie mode."),
209
+ })
210
+ .strict();
211
+ /** Standalone Genie output used only when no dashboard is requested. */
212
+ export const GeneratedGenieSpaceSchema = z
213
+ .object({
214
+ spaceId: nonBlankString.describe("Created standalone Genie space ID."),
215
+ title: nonBlankString.describe("Genie space title."),
216
+ })
217
+ .strict();
218
+ /** Terminal workflow output. */
219
+ export const GeneratedAssetsSchema = z
220
+ .object({
221
+ request: GeneratorRequestSchema,
222
+ schema: GeneratedSchemaSchema,
223
+ tables: z.array(nonBlankString).min(1).describe("Created fully qualified Delta tables."),
224
+ brand: BrandPackageSchema,
225
+ kpiResearch: KpiResearchResultSchema,
226
+ plan: GeneratorPlanSchema,
227
+ dashboard: GeneratedDashboardSchema.optional(),
228
+ genie: GeneratedGenieSpaceSchema.optional(),
229
+ })
230
+ .strict()
231
+ .superRefine((value, ctx) => {
232
+ if ((value.dashboard === undefined) === (value.genie === undefined)) {
233
+ ctx.addIssue({
234
+ code: "custom",
235
+ message: "Exactly one dashboard or standalone Genie space is required.",
236
+ });
237
+ }
238
+ })
239
+ .describe("Generated Databricks data and presentation assets.");
240
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid29ya2Zsb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd29ya2Zsb3cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7R0FJRztBQUVILE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxLQUFLLENBQUM7QUFDeEIsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ2hELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxtQkFBbUIsRUFBRSxNQUFNLFVBQVUsQ0FBQztBQUV4RSxNQUFNLGNBQWMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ2hELE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxLQUFLLENBQUMsbUJBQW1CLEVBQUUsc0NBQXNDLENBQUMsQ0FBQztBQUVqRyw4REFBOEQ7QUFDOUQsTUFBTSxDQUFDLE1BQU0sc0JBQXNCLEdBQUcsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBS3JFLDBEQUEwRDtBQUMxRCxNQUFNLENBQUMsTUFBTSxzQkFBc0IsR0FBRyxDQUFDO0tBQ3BDLE1BQU0sQ0FBQztJQUNOLE9BQU8sRUFBRSxjQUFjLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQywyQ0FBMkMsQ0FBQztJQUN0RixPQUFPLEVBQUUsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsK0NBQStDLENBQUM7SUFDMUYsT0FBTyxFQUFFLENBQUM7U0FDUCxLQUFLLENBQUMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztTQUM5QixHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQ04sR0FBRyxDQUFDLEVBQUUsQ0FBQztTQUNQLFFBQVEsQ0FBQyxnRUFBZ0UsQ0FBQztJQUM3RSxP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RTtJQUMxQixJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsS0FBSyxTQUFTLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxLQUFLLEtBQUssU0FBUyxDQUFDLEVBQUUsQ0FBQztRQUNwRSxHQUFHLENBQUMsUUFBUSxDQUFDO1lBQ1gsSUFBSSxFQUFFLFFBQVE7WUFDZCxPQUFPLEVBQUUsOERBQThEO1NBQ3hFLENBQUMsQ0FBQztJQUNMLENBQUM7QUFDSCxDQUFDLENBQUM7S0FDRCxRQUFRLENBQUMsb0RBQW9ELENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQnJvd3Nlci1zYWZlIGNvbnRyYWN0cyBmb3IgZ2VuZXJhdGVkIERhdGFicmlja3MgZGVtbyBhc3NldHMuXG4gKlxuICogQG1vZHVsZVxuICovXG5cbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgeyBCcmFuZFBhY2thZ2VTY2hlbWEgfSBmcm9tIFwiLi9icmFuZC50c1wiO1xuaW1wb3J0IHsgS3BpUmVzZWFyY2hSZXN1bHRTY2hlbWEsIFJlc2VhcmNoZWRLcGlTY2hlbWEgfSBmcm9tIFwiLi9rcGkudHNcIjtcblxuY29uc3Qgbm9uQmxhbmtTdHJpbmcgPSB6LnN0cmluZygpLnRyaW0oKS5taW4oMSk7XG5jb25zdCBpZGVudGlmaWVyID0gei5zdHJpbmcoKS5yZWdleCgvXlthLXpdW2EtejAtOV9dKiQvLCBcIkV4cGVjdGVkIGEgbG93ZXJjYXNlIFNRTCBpZGVudGlmaWVyLlwiKTtcblxuLyoqIFByZXNlbnRhdGlvbiBjcmVhdGVkIGFmdGVyIGdlbmVyYXRlZCBkYXRhIGlzIHZhbGlkYXRlZC4gKi9cbmV4cG9ydCBjb25zdCBQcmVzZW50YXRpb25Nb2RlU2NoZW1hID0gei5lbnVtKFtcImRhc2hib2FyZFwiLCBcImdlbmllXCJdKTtcblxuLyoqIFByZXNlbnRhdGlvbiBtb2RlLiAqL1xuZXhwb3J0IHR5cGUgUHJlc2VudGF0aW9uTW9kZSA9IHouaW5mZXI8dHlwZW9mIFByZXNlbnRhdGlvbk1vZGVTY2hlbWE+O1xuXG4vKiogQ29tcGxldGUgaW5wdXQgZm9yIHRoZSBnb3Zlcm5lZCBnZW5lcmF0b3Igd29ya2Zsb3cuICovXG5leHBvcnQgY29uc3QgR2VuZXJhdG9yUmVxdWVzdFNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgY29tcGFueTogbm9uQmxhbmtTdHJpbmcubWF4KDIwMCkuZGVzY3JpYmUoXCJDb21wYW55IG9yIGJyYW5kIHJlcHJlc2VudGVkIGJ5IHRoZSBkZW1vLlwiKSxcbiAgICBwdXJwb3NlOiBub25CbGFua1N0cmluZy5tYXgoMjAwKS5kZXNjcmliZShcIlNob3J0IHB1cnBvc2UgdXNlZCBpbiBzY2hlbWEgYW5kIGFzc2V0IG5hbWVzLlwiKSxcbiAgICBxdWVyaWVzOiB6XG4gICAgICAuYXJyYXkobm9uQmxhbmtTdHJpbmcubWF4KDUwMCkpXG4gICAgICAubWluKDEpXG4gICAgICAubWF4KDEwKVxuICAgICAgLmRlc2NyaWJlKFwiQnVzaW5lc3MgcXVlc3Rpb25zIHRoYXQgc2hhcGUgS1BJIHJlc2VhcmNoIGFuZCBnZW5lcmF0ZWQgZGF0YS5cIiksXG4gICAgd2Vic2l0ZTogelxuICAgICAgLnN0cmluZygpXG4gICAgICAudXJsKClcbiAgICAgIC5vcHRpb25hbCgpXG4gICAgICAuZGVzY3JpYmUoXCJLbm93biBjb21wYW55IHdlYnNpdGUgZm9yIGJyYW5kIGRpc2FtYmlndWF0aW9uLlwiKSxcbiAgICBwcmVzZW50YXRpb246IFByZXNlbnRhdGlvbk1vZGVTY2hlbWEuZGVmYXVsdChcImRhc2hib2FyZFwiKS5kZXNjcmliZShcbiAgICAgIFwiRGFzaGJvYXJkIHdpdGggYXV0b21hdGljIGNvbXBhbmlvbiBHZW5pZSwgb3Igc3RhbmRhbG9uZSBHZW5pZSB3aXRob3V0IGEgZGFzaGJvYXJkLlwiLFxuICAgICksXG4gICAgcm93Q291bnQ6IHpcbiAgICAgIC5udW1iZXIoKVxuICAgICAgLmludCgpXG4gICAgICAubWluKDFfMDAwKVxuICAgICAgLm1heCgxMDBfMDAwKVxuICAgICAgLmRlZmF1bHQoNTBfMDAwKVxuICAgICAgLmRlc2NyaWJlKFwiUm93cyBnZW5lcmF0ZWQgaW4gdGhlIHByaW1hcnkgZmFjdCB0YWJsZS5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJSZXF1ZXN0IGZvciBhIHBlci11c2VyIERhdGFicmlja3MgZGVtbyBkYXRhIGVudmlyb25tZW50LlwiKTtcblxuLyoqIEdlbmVyYXRvciB3b3JrZmxvdyBpbnB1dCBhZnRlciBkZWZhdWx0cy4gKi9cbmV4cG9ydCB0eXBlIEdlbmVyYXRvclJlcXVlc3QgPSB6Lm91dHB1dDx0eXBlb2YgR2VuZXJhdG9yUmVxdWVzdFNjaGVtYT47XG5cbi8qKiBTdXBwb3J0ZWQgZGV0ZXJtaW5pc3RpYyBjb2x1bW4gZ2VuZXJhdG9ycy4gKi9cbmV4cG9ydCBjb25zdCBHZW5lcmF0ZWRDb2x1bW5TY2hlbWEgPSB6LmRpc2NyaW1pbmF0ZWRVbmlvbihcImdlbmVyYXRvclwiLCBbXG4gIHpcbiAgICAub2JqZWN0KHtcbiAgICAgIG5hbWU6IGlkZW50aWZpZXIuZGVzY3JpYmUoXCJDb2x1bW4gbmFtZS5cIiksXG4gICAgICBnZW5lcmF0b3I6IHoubGl0ZXJhbChcImlkXCIpLFxuICAgICAgZGVzY3JpcHRpb246IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiQ29sdW1uIGJ1c2luZXNzIG1lYW5pbmcuXCIpLFxuICAgIH0pXG4gICAgLnN0cmljdCgpLFxuICB6XG4gICAgLm9iamVjdCh7XG4gICAgICBuYW1lOiBpZGVudGlmaWVyLmRlc2NyaWJlKFwiQ29sdW1uIG5hbWUuXCIpLFxuICAgICAgZ2VuZXJhdG9yOiB6LmxpdGVyYWwoXCJkYXRlXCIpLFxuICAgICAgZGVzY3JpcHRpb246IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiQ29sdW1uIGJ1c2luZXNzIG1lYW5pbmcuXCIpLFxuICAgICAgZGF5czogei5udW1iZXIoKS5pbnQoKS5taW4oMzApLm1heCgxXzA5NSkuZGVzY3JpYmUoXCJHZW5lcmF0ZWQgaGlzdG9yeSB3aW5kb3cgaW4gZGF5cy5cIiksXG4gICAgfSlcbiAgICAuc3RyaWN0KCksXG4gIHpcbiAgICAub2JqZWN0KHtcbiAgICAgIG5hbWU6IGlkZW50aWZpZXIuZGVzY3JpYmUoXCJDb2x1bW4gbmFtZS5cIiksXG4gICAgICBnZW5lcmF0b3I6IHoubGl0ZXJhbChcImNhdGVnb3J5XCIpLFxuICAgICAgZGVzY3JpcHRpb246IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiQ29sdW1uIGJ1c2luZXNzIG1lYW5pbmcuXCIpLFxuICAgICAgdmFsdWVzOiB6LmFycmF5KG5vbkJsYW5rU3RyaW5nLm1heCg4MCkpLm1pbigyKS5tYXgoMTIpLmRlc2NyaWJlKFwiU2tld2VkIGNhdGVnb3J5IHZhbHVlcy5cIiksXG4gICAgfSlcbiAgICAuc3RyaWN0KCksXG4gIHpcbiAgICAub2JqZWN0KHtcbiAgICAgIG5hbWU6IGlkZW50aWZpZXIuZGVzY3JpYmUoXCJDb2x1bW4gbmFtZS5cIiksXG4gICAgICBnZW5lcmF0b3I6IHoubGl0ZXJhbChcIm51bWJlclwiKSxcbiAgICAgIGRlc2NyaXB0aW9uOiBub25CbGFua1N0cmluZy5kZXNjcmliZShcIkNvbHVtbiBidXNpbmVzcyBtZWFuaW5nLlwiKSxcbiAgICAgIG1pbmltdW06IHoubnVtYmVyKCkuZGVzY3JpYmUoXCJNaW5pbXVtIGdlbmVyYXRlZCB2YWx1ZS5cIiksXG4gICAgICBtYXhpbXVtOiB6Lm51bWJlcigpLmRlc2NyaWJlKFwiTWF4aW11bSBnZW5lcmF0ZWQgdmFsdWUuXCIpLFxuICAgICAgZGVjaW1hbHM6IHoubnVtYmVyKCkuaW50KCkubWluKDApLm1heCg0KS5kZWZhdWx0KDIpLmRlc2NyaWJlKFwiRGVjaW1hbCBwcmVjaXNpb24uXCIpLFxuICAgIH0pXG4gICAgLnN0cmljdCgpLFxuICB6XG4gICAgLm9iamVjdCh7XG4gICAgICBuYW1lOiBpZGVudGlmaWVyLmRlc2NyaWJlKFwiQ29sdW1uIG5hbWUuXCIpLFxuICAgICAgZ2VuZXJhdG9yOiB6LmxpdGVyYWwoXCJib29sZWFuXCIpLFxuICAgICAgZGVzY3JpcHRpb246IG5vbkJsYW5rU3RyaW5nLmRlc2NyaWJlKFwiQ29sdW1uIGJ1c2luZXNzIG1lYW5pbmcuXCIpLFxuICAgICAgdHJ1ZVByb2JhYmlsaXR5OiB6Lm51bWJlcigpLm1pbigwLjAxKS5tYXgoMC45OSkuZGVzY3JpYmUoXCJTaGFyZSBvZiB0cnVlIHJvd3MuXCIpLFxuICAgIH0pXG4gICAgLnN0cmljdCgpLFxuXSk7XG5cbi8qKiBEZXRlcm1pbmlzdGljIGdlbmVyYXRlZCBjb2x1bW4gc3BlY2lmaWNhdGlvbi4gKi9cbmV4cG9ydCB0eXBlIEdlbmVyYXRlZENvbHVtbiA9IHouaW5mZXI8dHlwZW9mIEdlbmVyYXRlZENvbHVtblNjaGVtYT47XG5cbi8qKiBLUEkgYmluZGluZyBjb21waWxlZCBpbnRvIHZhbGlkYXRpb24gU1FMIGFuZCBkYXNoYm9hcmQgbWVhc3VyZXMuICovXG5leHBvcnQgY29uc3QgR2VuZXJhdGVkTWV0cmljU2NoZW1hID0gUmVzZWFyY2hlZEtwaVNjaGVtYS5leHRlbmQoe1xuICBhZ2dyZWdhdGlvbjogelxuICAgIC5lbnVtKFtcImNvdW50XCIsIFwic3VtXCIsIFwiYXZlcmFnZVwiXSlcbiAgICAuZGVzY3JpYmUoXCJTYWZlIGFnZ3JlZ2F0ZSBjb21waWxlZCBieSB0aGUgZ2VuZXJhdG9yLlwiKSxcbiAgY29sdW1uOiBpZGVudGlmaWVyLm9wdGlvbmFsKCkuZGVzY3JpYmUoXCJOdW1lcmljIHNvdXJjZSBjb2x1bW47IG9taXR0ZWQgZm9yIGNvdW50LlwiKSxcbn0pLnN0cmljdCgpO1xuXG4vKiogS1BJIGJpbmRpbmcuICovXG5leHBvcnQgdHlwZSBHZW5lcmF0ZWRNZXRyaWMgPSB6LmluZmVyPHR5cGVvZiBHZW5lcmF0ZWRNZXRyaWNTY2hlbWE+O1xuXG4vKiogU3RydWN0dXJlZCBwbGFuIGNvbXBpbGVkIGludG8gU1FMIGFuZCBwcmVzZW50YXRpb24gYXNzZXRzLiAqL1xuZXhwb3J0IGNvbnN0IEdlbmVyYXRvclBsYW5TY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHRhYmxlOiBpZGVudGlmaWVyLmRlc2NyaWJlKFwiUHJpbWFyeSBnZW5lcmF0ZWQgRGVsdGEgdGFibGUgbmFtZS5cIiksXG4gICAgcm93Q291bnQ6IHoubnVtYmVyKCkuaW50KCkubWluKDFfMDAwKS5tYXgoMTAwXzAwMCkuZGVzY3JpYmUoXCJSb3dzIHRvIGdlbmVyYXRlLlwiKSxcbiAgICBjb2x1bW5zOiB6XG4gICAgICAuYXJyYXkoR2VuZXJhdGVkQ29sdW1uU2NoZW1hKVxuICAgICAgLm1pbig0KVxuICAgICAgLm1heCgxNilcbiAgICAgIC5kZXNjcmliZShcIlR5cGVkIGRldGVybWluaXN0aWMgY29sdW1uIGdlbmVyYXRvcnMuXCIpLFxuICAgIG1ldHJpY3M6IHouYXJyYXkoR2VuZXJhdGVkTWV0cmljU2NoZW1hKS5taW4oMSkubWF4KDYpLmRlc2NyaWJlKFwiRGFzaGJvYXJkIGFuZCBHZW5pZSBLUElzLlwiKSxcbiAgICBzdG9yeTogbm9uQmxhbmtTdHJpbmcuZGVzY3JpYmUoXCJCdXNpbmVzcyBhbm9tYWx5IGFuZCBpbXBhY3QgcmVwcmVzZW50ZWQgaW4gdGhlIGRhdGEuXCIpLFxuICAgIHNhbXBsZVF1ZXN0aW9uczogelxuICAgICAgLmFycmF5KG5vbkJsYW5rU3RyaW5nLm1heCgzMDApKVxuICAgICAgLm1pbigzKVxuICAgICAgLm1heCg4KVxuICAgICAgLmRlc2NyaWJlKFwiUXVlc3Rpb25zIHN1cHBvcnRlZCBieSB0aGUgZ2VuZXJhdGVkIHRhYmxlLlwiKSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5zdXBlclJlZmluZSgodmFsdWUsIGN0eCkgPT4ge1xuICAgIGNvbnN0IG5hbWVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gICAgZm9yIChjb25zdCBbaW5kZXgsIGNvbHVtbl0gb2YgdmFsdWUuY29sdW1ucy5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChuYW1lcy5oYXMoY29sdW1uLm5hbWUpKSB7XG4gICAgICAgIGN0eC5hZGRJc3N1ZSh7XG4gICAgICAgICAgY29kZTogXCJjdXN0b21cIixcbiAgICAgICAgICBwYXRoOiBbXCJjb2x1bW5zXCIsIGluZGV4LCBcIm5hbWVcIl0sXG4gICAgICAgICAgbWVzc2FnZTogXCJHZW5lcmF0ZWQgY29sdW1uIG5hbWVzIG11c3QgYmUgdW5pcXVlLlwiLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIG5hbWVzLmFkZChjb2x1bW4ubmFtZSk7XG4gICAgfVxuICAgIGlmICghdmFsdWUuY29sdW1ucy5zb21lKCh7IGdlbmVyYXRvciB9KSA9PiBnZW5lcmF0b3IgPT09IFwiaWRcIikpIHtcbiAgICAgIGN0eC5hZGRJc3N1ZSh7IGNvZGU6IFwiY3VzdG9tXCIsIHBhdGg6IFtcImNvbHVtbnNcIl0sIG1lc3NhZ2U6IFwiQW4gaWQgY29sdW1uIGlzIHJlcXVpcmVkLlwiIH0pO1xuICAgIH1cbiAgICBpZiAoIXZhbHVlLmNvbHVtbnMuc29tZSgoeyBnZW5lcmF0b3IgfSkgPT4gZ2VuZXJhdG9yID09PSBcImRhdGVcIikpIHtcbiAgICAgIGN0eC5hZGRJc3N1ZSh7IGNvZGU6IFwiY3VzdG9tXCIsIHBhdGg6IFtcImNvbHVtbnNcIl0sIG1lc3NhZ2U6IFwiQSBkYXRlIGNvbHVtbiBpcyByZXF1aXJlZC5cIiB9KTtcbiAgICB9XG4gICAgaWYgKCF2YWx1ZS5jb2x1bW5zLnNvbWUoKHsgZ2VuZXJhdG9yIH0pID0+IGdlbmVyYXRvciA9PT0gXCJjYXRlZ29yeVwiKSkge1xuICAgICAgY3R4LmFkZElzc3VlKHtcbiAgICAgICAgY29kZTogXCJjdXN0b21cIixcbiAgICAgICAgcGF0aDogW1wiY29sdW1uc1wiXSxcbiAgICAgICAgbWVzc2FnZTogXCJBIGNhdGVnb3J5IGNvbHVtbiBpcyByZXF1aXJlZC5cIixcbiAgICAgIH0pO1xuICAgIH1cbiAgICBjb25zdCBudW1lcmljID0gbmV3IFNldChcbiAgICAgIHZhbHVlLmNvbHVtbnMuZmlsdGVyKCh7IGdlbmVyYXRvciB9KSA9PiBnZW5lcmF0b3IgPT09IFwibnVtYmVyXCIpLm1hcCgoeyBuYW1lIH0pID0+IG5hbWUpLFxuICAgICk7XG4gICAgZm9yIChjb25zdCBbaW5kZXgsIG1ldHJpY10gb2YgdmFsdWUubWV0cmljcy5lbnRyaWVzKCkpIHtcbiAgICAgIGlmIChtZXRyaWMuYWdncmVnYXRpb24gIT09IFwiY291bnRcIiAmJiAoIW1ldHJpYy5jb2x1bW4gfHwgIW51bWVyaWMuaGFzKG1ldHJpYy5jb2x1bW4pKSkge1xuICAgICAgICBjdHguYWRkSXNzdWUoe1xuICAgICAgICAgIGNvZGU6IFwiY3VzdG9tXCIsXG4gICAgICAgICAgcGF0aDogW1wibWV0cmljc1wiLCBpbmRleCwgXCJjb2x1bW5cIl0sXG4gICAgICAgICAgbWVzc2FnZTogXCJTdW0gYW5kIGF2ZXJhZ2UgbWV0cmljcyByZXF1aXJlIGEgZ2VuZXJhdGVkIG51bWVyaWMgY29sdW1uLlwiLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG4gIH0pXG4gIC5kZXNjcmliZShcIlZhbGlkYXRlZCBwbGFuIGZvciBkZXRlcm1pbmlzdGljIHN5bnRoZXRpYyBkYXRhIGFuZCBhbmFseXRpY3MgYXNzZXRzLlwiKTtcblxuLyoqIFN0cnVjdHVyZWQgZ2VuZXJhdG9yIHBsYW4uICovXG5leHBvcnQgdHlwZSBHZW5lcmF0b3JQbGFuID0gei5pbmZlcjx0eXBlb2YgR2VuZXJhdG9yUGxhblNjaGVtYT47XG5cbi8qKiBJbnB1dCBmb3IgdGhlIHN0YW5kYWxvbmUgc3RydWN0dXJlZCBkYXRhLXBsYW5uaW5nIHRvb2wuICovXG5leHBvcnQgY29uc3QgUGxhbkdlbmVyYXRvckRhdGFSZXF1ZXN0U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICByZXF1ZXN0OiBHZW5lcmF0b3JSZXF1ZXN0U2NoZW1hLFxuICAgIGJyYW5kOiBCcmFuZFBhY2thZ2VTY2hlbWEsXG4gICAga3BpUmVzZWFyY2g6IEtwaVJlc2VhcmNoUmVzdWx0U2NoZW1hLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiSW5wdXRzIG5lZWRlZCB0byBidWlsZCBhIHR5cGVkIGdlbmVyYXRvciBwbGFuLlwiKTtcblxuLyoqIElucHV0IGZvciB0aGUgc3RhbmRhbG9uZSBzdHJ1Y3R1cmVkIGRhdGEtcGxhbm5pbmcgdG9vbC4gKi9cbmV4cG9ydCB0eXBlIFBsYW5HZW5lcmF0b3JEYXRhUmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIFBsYW5HZW5lcmF0b3JEYXRhUmVxdWVzdFNjaGVtYT47XG5cbi8qKiBMb2NhdGlvbiBhbmQgdHJ1c3RlZCBpZGVudGl0eSBmb3Igb25lIGdlbmVyYXRlZCBzY2hlbWEuICovXG5leHBvcnQgY29uc3QgR2VuZXJhdGVkU2NoZW1hU2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBjYXRhbG9nOiBpZGVudGlmaWVyLmRlc2NyaWJlKFwiQ29uZmlndXJlZCBVbml0eSBDYXRhbG9nLlwiKSxcbiAgICBzY2hlbWE6IGlkZW50aWZpZXIuZGVzY3JpYmUoXCJQZXItdXNlciBnZW5lcmF0ZWQgc2NoZW1hLlwiKSxcbiAgICBmdWxsTmFtZTogbm9uQmxhbmtTdHJpbmcuZGVzY3JpYmUoXCJRdW90ZWQtc2FmZSBjYXRhbG9nLnNjaGVtYSBkaXNwbGF5IG5hbWUuXCIpLFxuICAgIHByaW5jaXBhbDogbm9uQmxhbmtTdHJpbmcuZGVzY3JpYmUoXCJUcnVzdGVkIE9CTyBEYXRhYnJpY2tzIHVzZXIgbmFtZS5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJQcm92aXNpb25lZCBwZXItdXNlciBVbml0eSBDYXRhbG9nIHNjaGVtYS5cIik7XG5cbi8qKiBQcm92aXNpb25lZCBnZW5lcmF0ZWQgc2NoZW1hLiAqL1xuZXhwb3J0IHR5cGUgR2VuZXJhdGVkU2NoZW1hID0gei5pbmZlcjx0eXBlb2YgR2VuZXJhdGVkU2NoZW1hU2NoZW1hPjtcblxuLyoqIElucHV0IGZvciBwZXItdXNlciBzY2hlbWEgcHJvdmlzaW9uaW5nLiAqL1xuZXhwb3J0IGNvbnN0IFByb3Zpc2lvbkdlbmVyYXRvclNjaGVtYVJlcXVlc3RTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHJlcXVlc3Q6IEdlbmVyYXRvclJlcXVlc3RTY2hlbWEucGljayh7IGNvbXBhbnk6IHRydWUsIHB1cnBvc2U6IHRydWUgfSksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJSZXF1ZXN0IHRvIHByb3Zpc2lvbiB0aGUgYWN0aXZlIHVzZXIncyBnZW5lcmF0ZWQgc2NoZW1hLlwiKTtcblxuLyoqIElucHV0IGZvciBwZXItdXNlciBzY2hlbWEgcHJvdmlzaW9uaW5nLiAqL1xuZXhwb3J0IHR5cGUgUHJvdmlzaW9uR2VuZXJhdG9yU2NoZW1hUmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIFByb3Zpc2lvbkdlbmVyYXRvclNjaGVtYVJlcXVlc3RTY2hlbWE+O1xuXG4vKiogSW5wdXQgZm9yIGdlbmVyYXRlZCBkYXRhIG1hdGVyaWFsaXphdGlvbi4gKi9cbmV4cG9ydCBjb25zdCBNYXRlcmlhbGl6ZUdlbmVyYXRvckRhdGFSZXF1ZXN0U2NoZW1hID0gelxuICAub2JqZWN0KHtcbiAgICBsb2NhdGlvbjogR2VuZXJhdGVkU2NoZW1hU2NoZW1hLFxuICAgIHBsYW46IEdlbmVyYXRvclBsYW5TY2hlbWEsXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuZGVzY3JpYmUoXCJSZXF1ZXN0IHRvIG1hdGVyaWFsaXplIGFuZCB2YWxpZGF0ZSBnZW5lcmF0ZWQgRGVsdGEgZGF0YS5cIik7XG5cbi8qKiBJbnB1dCBmb3IgZ2VuZXJhdGVkIGRhdGEgbWF0ZXJpYWxpemF0aW9uLiAqL1xuZXhwb3J0IHR5cGUgTWF0ZXJpYWxpemVHZW5lcmF0b3JEYXRhUmVxdWVzdCA9IHouaW5mZXI8dHlwZW9mIE1hdGVyaWFsaXplR2VuZXJhdG9yRGF0YVJlcXVlc3RTY2hlbWE+O1xuXG4vKiogQ3JlYXRlZCB0YWJsZXMgYW5kIEtQSSB2YWxpZGF0aW9uIHN0YXRlbWVudHMuICovXG5leHBvcnQgY29uc3QgTWF0ZXJpYWxpemVkR2VuZXJhdG9yRGF0YVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgdGFibGVzOiB6LmFycmF5KG5vbkJsYW5rU3RyaW5nKS5taW4oMSkuZGVzY3JpYmUoXCJDcmVhdGVkIGZ1bGx5IHF1YWxpZmllZCBEZWx0YSB0YWJsZXMuXCIpLFxuICAgIHZhbGlkYXRpb25TdGF0ZW1lbnRzOiB6XG4gICAgICAucmVjb3JkKGlkZW50aWZpZXIsIG5vbkJsYW5rU3RyaW5nKVxuICAgICAgLmRlc2NyaWJlKFwiU3RhdGVtZW50IElEcyBrZXllZCBieSB2YWxpZGF0ZWQgS1BJIG5hbWUuXCIpLFxuICB9KVxuICAuc3RyaWN0KClcbiAgLmRlc2NyaWJlKFwiTWF0ZXJpYWxpemVkIGFuZCB2YWxpZGF0ZWQgZ2VuZXJhdGVkIGRhdGEuXCIpO1xuXG4vKiogQ3JlYXRlZCB0YWJsZXMgYW5kIEtQSSB2YWxpZGF0aW9uIHN0YXRlbWVudHMuICovXG5leHBvcnQgdHlwZSBNYXRlcmlhbGl6ZWRHZW5lcmF0b3JEYXRhID0gei5pbmZlcjx0eXBlb2YgTWF0ZXJpYWxpemVkR2VuZXJhdG9yRGF0YVNjaGVtYT47XG5cbi8qKiBJbnB1dCBzaGFyZWQgYnkgZGFzaGJvYXJkIGFuZCBzdGFuZGFsb25lIEdlbmllIGNyZWF0aW9uIHRvb2xzLiAqL1xuZXhwb3J0IGNvbnN0IENyZWF0ZUdlbmVyYXRvclByZXNlbnRhdGlvblJlcXVlc3RTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIHJlcXVlc3Q6IEdlbmVyYXRvclJlcXVlc3RTY2hlbWEucGljayh7XG4gICAgICBjb21wYW55OiB0cnVlLFxuICAgICAgcHVycG9zZTogdHJ1ZSxcbiAgICB9KSxcbiAgICBsb2NhdGlvbjogR2VuZXJhdGVkU2NoZW1hU2NoZW1hLFxuICAgIHBsYW46IEdlbmVyYXRvclBsYW5TY2hlbWEsXG4gICAgYnJhbmQ6IEJyYW5kUGFja2FnZVNjaGVtYSxcbiAgfSlcbiAgLnN0cmljdCgpXG4gIC5kZXNjcmliZShcIlJlcXVlc3QgdG8gY3JlYXRlIGEgcHJlc2VudGF0aW9uIGFzc2V0IG92ZXIgZ2VuZXJhdGVkIGRhdGEuXCIpO1xuXG4vKiogSW5wdXQgc2hhcmVkIGJ5IGRhc2hib2FyZCBhbmQgc3RhbmRhbG9uZSBHZW5pZSBjcmVhdGlvbiB0b29scy4gKi9cbmV4cG9ydCB0eXBlIENyZWF0ZUdlbmVyYXRvclByZXNlbnRhdGlvblJlcXVlc3QgPSB6LmluZmVyPFxuICB0eXBlb2YgQ3JlYXRlR2VuZXJhdG9yUHJlc2VudGF0aW9uUmVxdWVzdFNjaGVtYVxuPjtcblxuLyoqIERhc2hib2FyZCBvdXRwdXQgd2l0aCBpdHMgYXV0b21hdGljIGNvbXBhbmlvbiBHZW5pZSBBZ2VudC4gKi9cbmV4cG9ydCBjb25zdCBHZW5lcmF0ZWREYXNoYm9hcmRTY2hlbWEgPSB6XG4gIC5vYmplY3Qoe1xuICAgIGRhc2hib2FyZElkOiBub25CbGFua1N0cmluZy5kZXNjcmliZShcIkNyZWF0ZWQgTGFrZXZpZXcgZGFzaGJvYXJkIElELlwiKSxcbiAgICBwYXRoOiBub25CbGFua1N0cmluZy5vcHRpb25hbCgpLmRlc2NyaWJlKFwiV29ya3NwYWNlIHBhdGgsIHdoZW4gcmV0dXJuZWQuXCIpLFxuICAgIGNvbXBhbmlvbkdlbmllOiB6LmxpdGVyYWwoXCJBVVRPXCIpLmRlc2NyaWJlKFwiRGFzaGJvYXJkLXB1Ymxpc2hlZCBjb21wYW5pb24gR2VuaWUgbW9kZS5cIiksXG4gIH0pXG4gIC5zdHJpY3QoKTtcblxuLyoqIFB1Ymxpc2hlZCBkYXNoYm9hcmQgd2l0aCBhdXRvbWF0aWMgY29tcGFuaW9uIEdlbmllLiAqL1xuZXhwb3J0IHR5cGUgR2VuZXJhdGVkRGFzaGJvYXJkID0gei5pbmZlcjx0eXBlb2YgR2VuZXJhdGVkRGFzaGJvYXJkU2NoZW1hPjtcblxuLyoqIFN0YW5kYWxvbmUgR2VuaWUgb3V0cHV0IHVzZWQgb25seSB3aGVuIG5vIGRhc2hib2FyZCBpcyByZXF1ZXN0ZWQuICovXG5leHBvcnQgY29uc3QgR2VuZXJhdGVkR2VuaWVTcGFjZVNjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgc3BhY2VJZDogbm9uQmxhbmtTdHJpbmcuZGVzY3JpYmUoXCJDcmVhdGVkIHN0YW5kYWxvbmUgR2VuaWUgc3BhY2UgSUQuXCIpLFxuICAgIHRpdGxlOiBub25CbGFua1N0cmluZy5kZXNjcmliZShcIkdlbmllIHNwYWNlIHRpdGxlLlwiKSxcbiAgfSlcbiAgLnN0cmljdCgpO1xuXG4vKiogQ3JlYXRlZCBzdGFuZGFsb25lIEdlbmllIHNwYWNlLiAqL1xuZXhwb3J0IHR5cGUgR2VuZXJhdGVkR2VuaWVTcGFjZSA9IHouaW5mZXI8dHlwZW9mIEdlbmVyYXRlZEdlbmllU3BhY2VTY2hlbWE+O1xuXG4vKiogVGVybWluYWwgd29ya2Zsb3cgb3V0cHV0LiAqL1xuZXhwb3J0IGNvbnN0IEdlbmVyYXRlZEFzc2V0c1NjaGVtYSA9IHpcbiAgLm9iamVjdCh7XG4gICAgcmVxdWVzdDogR2VuZXJhdG9yUmVxdWVzdFNjaGVtYSxcbiAgICBzY2hlbWE6IEdlbmVyYXRlZFNjaGVtYVNjaGVtYSxcbiAgICB0YWJsZXM6IHouYXJyYXkobm9uQmxhbmtTdHJpbmcpLm1pbigxKS5kZXNjcmliZShcIkNyZWF0ZWQgZnVsbHkgcXVhbGlmaWVkIERlbHRhIHRhYmxlcy5cIiksXG4gICAgYnJhbmQ6IEJyYW5kUGFja2FnZVNjaGVtYSxcbiAgICBrcGlSZXNlYXJjaDogS3BpUmVzZWFyY2hSZXN1bHRTY2hlbWEsXG4gICAgcGxhbjogR2VuZXJhdG9yUGxhblNjaGVtYSxcbiAgICBkYXNoYm9hcmQ6IEdlbmVyYXRlZERhc2hib2FyZFNjaGVtYS5vcHRpb25hbCgpLFxuICAgIGdlbmllOiBHZW5lcmF0ZWRHZW5pZVNwYWNlU2NoZW1hLm9wdGlvbmFsKCksXG4gIH0pXG4gIC5zdHJpY3QoKVxuICAuc3VwZXJSZWZpbmUoKHZhbHVlLCBjdHgpID0+IHtcbiAgICBpZiAoKHZhbHVlLmRhc2hib2FyZCA9PT0gdW5kZWZpbmVkKSA9PT0gKHZhbHVlLmdlbmllID09PSB1bmRlZmluZWQpKSB7XG4gICAgICBjdHguYWRkSXNzdWUoe1xuICAgICAgICBjb2RlOiBcImN1c3RvbVwiLFxuICAgICAgICBtZXNzYWdlOiBcIkV4YWN0bHkgb25lIGRhc2hib2FyZCBvciBzdGFuZGFsb25lIEdlbmllIHNwYWNlIGlzIHJlcXVpcmVkLlwiLFxuICAgICAgfSk7XG4gICAgfVxuICB9KVxuICAuZGVzY3JpYmUoXCJHZW5lcmF0ZWQgRGF0YWJyaWNrcyBkYXRhIGFuZCBwcmVzZW50YXRpb24gYXNzZXRzLlwiKTtcblxuLyoqIFRlcm1pbmFsIGdlbmVyYXRvciB3b3JrZmxvdyBvdXRwdXQuICovXG5leHBvcnQgdHlwZSBHZW5lcmF0ZWRBc3NldHMgPSB6LmluZmVyPHR5cGVvZiBHZW5lcmF0ZWRBc3NldHNTY2hlbWE+O1xuIl19
@@ -0,0 +1 @@
1
+ {"root":["../src/brand.ts","../src/kpi.ts","../src/workflow.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,6 +1,95 @@
1
1
  {
2
2
  "name": "@dbx-tools/shared-generator",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "description": "Browser-safe contracts and clients for AppKit generator workflows",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/reggie-db/dbx-tools.git",
7
+ "directory": "packages/js/shared/generator"
8
+ },
9
+ "scripts": {
10
+ "build": "projen build",
11
+ "compile": "projen compile",
12
+ "default": "projen default",
13
+ "package": "projen package",
14
+ "post-compile": "projen post-compile",
15
+ "pre-compile": "projen pre-compile",
16
+ "prepack": "projen prepack",
17
+ "test": "projen test",
18
+ "watch": "projen watch",
19
+ "projen": "projen"
20
+ },
21
+ "devDependencies": {
22
+ "typescript": "^5.9.3"
23
+ },
24
+ "dependencies": {
25
+ "@dbx-tools/shared-core": "^0.9.136",
26
+ "zod": "4.3.6"
27
+ },
28
+ "main": "./lib/index.js",
29
+ "license": "Apache-2.0",
30
+ "publishConfig": {
31
+ "access": "public",
32
+ "main": "./lib/index.js",
33
+ "types": "./lib/index.d.ts",
34
+ "exports": {
35
+ ".": {
36
+ "types": "./lib/index.d.ts",
37
+ "default": "./lib/index.js"
38
+ },
39
+ "./brand": {
40
+ "types": "./lib/src/brand.d.ts",
41
+ "default": "./lib/src/brand.js"
42
+ },
43
+ "./kpi": {
44
+ "types": "./lib/src/kpi.d.ts",
45
+ "default": "./lib/src/kpi.js"
46
+ },
47
+ "./workflow": {
48
+ "types": "./lib/src/workflow.d.ts",
49
+ "default": "./lib/src/workflow.js"
50
+ },
51
+ "./*": {
52
+ "types": "./lib/src/*/index.d.ts",
53
+ "default": "./lib/src/*/index.js"
54
+ },
55
+ "./package.json": "./package.json"
56
+ }
57
+ },
58
+ "version": "0.9.136",
59
+ "types": "./lib/index.d.ts",
60
+ "dbxToolsConfig": {
61
+ "tags": [
62
+ "shared"
63
+ ]
64
+ },
65
+ "type": "module",
66
+ "exports": {
67
+ ".": {
68
+ "types": "./lib/index.d.ts",
69
+ "default": "./lib/index.js"
70
+ },
71
+ "./brand": {
72
+ "types": "./lib/src/brand.d.ts",
73
+ "default": "./lib/src/brand.js"
74
+ },
75
+ "./kpi": {
76
+ "types": "./lib/src/kpi.d.ts",
77
+ "default": "./lib/src/kpi.js"
78
+ },
79
+ "./workflow": {
80
+ "types": "./lib/src/workflow.d.ts",
81
+ "default": "./lib/src/workflow.js"
82
+ },
83
+ "./*": {
84
+ "types": "./lib/src/*/index.d.ts",
85
+ "default": "./lib/src/*/index.js"
86
+ },
87
+ "./package.json": "./package.json"
88
+ },
89
+ "files": [
90
+ "index.ts",
91
+ "src",
92
+ "lib"
93
+ ],
94
+ "//": "~~ Generated by projen. To modify, edit .projenrc.js and run \"bunx projen\"."
95
+ }
package/src/brand.ts ADDED
@@ -0,0 +1,273 @@
1
+ /**
2
+ * Browser-safe contracts and client for AppKit brand generation.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { BrandContextSchema } from "@dbx-tools/shared-core/brand-utils";
8
+ import { z } from "zod";
9
+
10
+ const nonBlankString = z.string().trim().min(1);
11
+
12
+ /** Registered AppKit generator plugin name. */
13
+ export const GENERATOR_PLUGIN_NAME = "generator";
14
+
15
+ /** Default route prefix published by the generator plugin. */
16
+ export const GENERATOR_BASE_PATH = `/api/${GENERATOR_PLUGIN_NAME}`;
17
+
18
+ /** Mount-relative route segments owned by the generator plugin. */
19
+ export const GENERATOR_ROUTES = {
20
+ generateBrand: "/brand/generate",
21
+ } as const;
22
+
23
+ /** Input accepted by brand generation. */
24
+ export const BrandGenerationRequestSchema = z
25
+ .object({
26
+ name: nonBlankString
27
+ .max(200)
28
+ .optional()
29
+ .describe("Known brand, organization, or product name."),
30
+ prompt: nonBlankString
31
+ .max(2_000)
32
+ .optional()
33
+ .describe("Open-ended brand brief used for research and generation."),
34
+ website: z
35
+ .string()
36
+ .url()
37
+ .refine((value) => new URL(value).protocol === "https:", "Expected an HTTPS website URL.")
38
+ .optional()
39
+ .describe("Known official website used to disambiguate the brand."),
40
+ })
41
+ .strict()
42
+ .refine((value) => value.name !== undefined || value.prompt !== undefined, {
43
+ message: "Brand generation requires a name or prompt.",
44
+ })
45
+ .describe("Request to research one brand and generate its portable branding package.");
46
+
47
+ /** Validated brand-generation request. */
48
+ export type BrandGenerationRequest = z.infer<typeof BrandGenerationRequestSchema>;
49
+
50
+ /** A cited source and whether its page content was available to synthesis. */
51
+ export const BrandPackageSourceSchema = z
52
+ .object({
53
+ url: z.string().url().describe("Source URL used during brand research."),
54
+ title: nonBlankString.optional().describe("Source page title, when available."),
55
+ snippet: nonBlankString.optional().describe("Search-result excerpt, when available."),
56
+ fetched: z
57
+ .boolean()
58
+ .describe("True when web_fetch returned page content used during synthesis."),
59
+ })
60
+ .strict()
61
+ .describe("Web source used to research the generated brand.");
62
+
63
+ /** Source provenance included in a generated branding package. */
64
+ export type BrandPackageSource = z.infer<typeof BrandPackageSourceSchema>;
65
+
66
+ /** One fetched mobile-app image used as visual brand research. */
67
+ export const BrandVisualImageSchema = z
68
+ .object({
69
+ url: z.string().url().describe("Original mobile-store image URL."),
70
+ contentType: z.string().optional().describe("Fetched image media type."),
71
+ localPath: z
72
+ .string()
73
+ .optional()
74
+ .describe("Package-relative exported image path, when written by a CLI."),
75
+ })
76
+ .strict()
77
+ .describe("Mobile-store image reference used for brand inspiration.");
78
+
79
+ /** Mobile-store image used as visual brand research. */
80
+ export type BrandVisualImage = z.infer<typeof BrandVisualImageSchema>;
81
+
82
+ /** App Store or Play Store page and its visual references. */
83
+ export const BrandVisualReferenceSchema = z
84
+ .object({
85
+ platform: z.enum(["ios", "android"]).describe("Mobile application platform."),
86
+ appName: nonBlankString.describe("Application name read from the store page."),
87
+ pageUrl: z.string().url().describe("Official application-store page."),
88
+ images: z.array(BrandVisualImageSchema).describe("Fetched app icon or screenshots."),
89
+ })
90
+ .strict()
91
+ .describe("Mobile application visuals consulted during brand research.");
92
+
93
+ /** Mobile-store brand research reference. */
94
+ export type BrandVisualReference = z.infer<typeof BrandVisualReferenceSchema>;
95
+
96
+ /** Portable generated brand context with research provenance. */
97
+ export const BrandPackageSchema = z
98
+ .object({
99
+ brand: BrandContextSchema.describe(
100
+ "Portable brand context ready for @dbx-tools UI and email consumers.",
101
+ ),
102
+ sources: z
103
+ .array(BrandPackageSourceSchema)
104
+ .describe("Deduplicated web sources used to generate this package."),
105
+ visualReferences: z
106
+ .array(BrandVisualReferenceSchema)
107
+ .default([])
108
+ .describe("iOS and Android application visuals used for inspiration."),
109
+ })
110
+ .strict()
111
+ .describe("Generated branding package and its web research provenance.");
112
+
113
+ /** Generated branding package. */
114
+ export type BrandPackage = z.infer<typeof BrandPackageSchema>;
115
+
116
+ /** Observable stages in one brand-generation workflow. */
117
+ export const BrandGenerationStageSchema = z.enum([
118
+ "search",
119
+ "fetch",
120
+ "visuals",
121
+ "assets",
122
+ "synthesize",
123
+ ]);
124
+
125
+ /** Observable brand-generation stage. */
126
+ export type BrandGenerationStage = z.infer<typeof BrandGenerationStageSchema>;
127
+
128
+ /** Progress emitted while the backend researches and synthesizes a brand. */
129
+ export const BrandGenerationProgressEventSchema = z
130
+ .object({
131
+ type: z.literal("progress"),
132
+ stage: BrandGenerationStageSchema.describe("Current workflow stage."),
133
+ message: nonBlankString.describe("Short user-facing progress message."),
134
+ current: z.number().int().nonnegative().optional().describe("Completed items in this stage."),
135
+ total: z.number().int().positive().optional().describe("Total items in this stage."),
136
+ })
137
+ .strict()
138
+ .describe("Progress update from a running brand generation.");
139
+
140
+ /** Progress event emitted during brand generation. */
141
+ export type BrandGenerationProgressEvent = z.infer<typeof BrandGenerationProgressEventSchema>;
142
+
143
+ /** Final successful brand-generation event. */
144
+ export const BrandGenerationResultEventSchema = z
145
+ .object({
146
+ type: z.literal("result"),
147
+ package: BrandPackageSchema.describe("Completed portable branding package."),
148
+ })
149
+ .strict()
150
+ .describe("Successful completion of brand generation.");
151
+
152
+ /** Final successful brand-generation event. */
153
+ export type BrandGenerationResultEvent = z.infer<typeof BrandGenerationResultEventSchema>;
154
+
155
+ /** Final error event from a started brand-generation stream. */
156
+ export const BrandGenerationErrorEventSchema = z
157
+ .object({
158
+ type: z.literal("error"),
159
+ message: nonBlankString.describe("Actionable generation failure message."),
160
+ })
161
+ .strict()
162
+ .describe("Failure emitted after a brand-generation stream started.");
163
+
164
+ /** Final error event from a started brand-generation stream. */
165
+ export type BrandGenerationErrorEvent = z.infer<typeof BrandGenerationErrorEventSchema>;
166
+
167
+ /** Every server-sent event emitted by brand generation. */
168
+ export const BrandGenerationEventSchema = z.discriminatedUnion("type", [
169
+ BrandGenerationProgressEventSchema,
170
+ BrandGenerationResultEventSchema,
171
+ BrandGenerationErrorEventSchema,
172
+ ]);
173
+
174
+ /** Server-sent event emitted by brand generation. */
175
+ export type BrandGenerationEvent = z.infer<typeof BrandGenerationEventSchema>;
176
+
177
+ /** Browser-safe route configuration published by the AppKit generator plugin. */
178
+ export const GeneratorClientConfigSchema = z
179
+ .object({
180
+ basePath: nonBlankString.describe("Mounted API route prefix for the generator plugin."),
181
+ })
182
+ .strict()
183
+ .describe("Browser configuration published by the AppKit generator plugin.");
184
+
185
+ /** Browser-safe generator plugin route configuration. */
186
+ export type GeneratorClientConfig = z.infer<typeof GeneratorClientConfigSchema>;
187
+
188
+ /** Options for one browser brand-generation stream. */
189
+ export interface BrandGenerationStreamOptions {
190
+ /** Cancels the request and response stream. */
191
+ signal?: AbortSignal;
192
+ /** Fetch implementation. Defaults to the browser global. */
193
+ fetch?: typeof globalThis.fetch;
194
+ }
195
+
196
+ /** Build the brand endpoint from the generator plugin's published base path. */
197
+ export function brandGenerateUrl(basePath: string = GENERATOR_BASE_PATH): string {
198
+ return `${basePath.replace(/\/+$/, "")}${GENERATOR_ROUTES.generateBrand}`;
199
+ }
200
+
201
+ /** Parse one complete SSE frame into its validated brand event. */
202
+ function parseEventFrame(frame: string): BrandGenerationEvent | undefined {
203
+ const data = frame
204
+ .split("\n")
205
+ .filter((line) => line.startsWith("data:"))
206
+ .map((line) => line.slice(5).trimStart())
207
+ .join("\n");
208
+ if (!data) return undefined;
209
+ const value: unknown = JSON.parse(data);
210
+ return BrandGenerationEventSchema.parse(value);
211
+ }
212
+
213
+ /** Read a failed HTTP response without trusting its payload shape. */
214
+ async function responseError(response: Response): Promise<string> {
215
+ const value: unknown = await response
216
+ .clone()
217
+ .json()
218
+ .catch(() => undefined);
219
+ if (typeof value === "object" && value !== null && "error" in value) {
220
+ const message = value.error;
221
+ if (typeof message === "string" && message.trim()) return message.trim();
222
+ }
223
+ const text = await response.text().catch(() => "");
224
+ return text.trim() || `Brand generation failed (${response.status}).`;
225
+ }
226
+
227
+ /** Browser client for the generator plugin's streamed routes. */
228
+ export class GeneratorPluginClient {
229
+ private readonly config: GeneratorClientConfig;
230
+
231
+ /** Create a client from the plugin's published `clientConfig()` payload. */
232
+ constructor(config: GeneratorClientConfig) {
233
+ this.config = GeneratorClientConfigSchema.parse(config);
234
+ }
235
+
236
+ /** Generate a brand while yielding validated progress and terminal events. */
237
+ async *generate(
238
+ input: BrandGenerationRequest,
239
+ options: BrandGenerationStreamOptions = {},
240
+ ): AsyncGenerator<BrandGenerationEvent> {
241
+ const request = BrandGenerationRequestSchema.parse(input);
242
+ const fetcher = options.fetch ?? globalThis.fetch.bind(globalThis);
243
+ const response = await fetcher(brandGenerateUrl(this.config.basePath), {
244
+ method: "POST",
245
+ headers: {
246
+ Accept: "text/event-stream",
247
+ "Content-Type": "application/json",
248
+ },
249
+ body: JSON.stringify(request),
250
+ ...(options.signal ? { signal: options.signal } : {}),
251
+ });
252
+ if (!response.ok) throw new Error(await responseError(response));
253
+ if (!response.body) throw new Error("Brand generation returned no event stream.");
254
+
255
+ const reader = response.body.getReader();
256
+ const decoder = new TextDecoder();
257
+ let buffer = "";
258
+ for (;;) {
259
+ const { done, value } = await reader.read();
260
+ buffer += decoder.decode(value, { stream: !done }).replaceAll("\r\n", "\n");
261
+ let boundary = buffer.indexOf("\n\n");
262
+ while (boundary >= 0) {
263
+ const event = parseEventFrame(buffer.slice(0, boundary));
264
+ if (event) yield event;
265
+ buffer = buffer.slice(boundary + 2);
266
+ boundary = buffer.indexOf("\n\n");
267
+ }
268
+ if (done) break;
269
+ }
270
+ const event = parseEventFrame(buffer.trim());
271
+ if (event) yield event;
272
+ }
273
+ }