stagebook 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/schemas/treatment.ts","../src/schemas/resolved.ts","../src/utils/reference.ts","../src/templates/fillTemplates.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-argument */\nimport { z } from \"zod\";\nimport type { ZodIssue } from \"zod\";\n\n// TODO: used by regex validation in conditionMatchesSchema — wire up or remove\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nfunction isValidRegex(pattern: string): boolean {\n try {\n new RegExp(pattern);\n return true;\n } catch (e) {\n if (e instanceof SyntaxError) {\n return false;\n }\n throw e;\n }\n}\n\n// ------------------ Names, descriptions, and files ------------------ //\n\n// Field placeholder pattern: only alphanumeric + underscore.\n// Must match FIELD_PLACEHOLDER_REGEX in templates/fillTemplates.ts\nconst fieldPlaceholderSchema = z.string().regex(/\\$\\{[a-zA-Z0-9_]+\\}/, {\n message:\n \"Field placeholder must be in the format `${fieldKey}` (alphanumeric and underscores only)\",\n});\n\n// Names should have properties:\n// max length: 64 characters\n// min length: 1 character\n// allowed characters: a-z, A-Z, 0-9, -, _, and space\n// Todo: allow template fields in a name\nexport const nameSchema = z\n .string()\n .min(1, \"Name is required\")\n .max(64)\n .regex(/^(?:[a-zA-Z0-9 _-]|\\$\\{[a-zA-Z0-9_]+\\})+$/, {\n message:\n \"Name must be alphanumeric, cannot have special characters, with optional template fields in the format ${fieldname}\",\n });\nexport type NameType = z.infer<typeof nameSchema>;\n\nexport const descriptionSchema = z.string();\nexport type DescriptionType = z.infer<typeof descriptionSchema>;\n\n// TODO: check that file exists\nexport const fileSchema = z.string().optional();\n\nexport const promptFilePathSchema = z\n .string()\n .refine((s) => s.endsWith(\".prompt.md\"), {\n message:\n 'Prompt files must use the .prompt.md extension (e.g., \"myPrompt.prompt.md\")',\n });\n\nexport type FileType = z.infer<typeof fileSchema>;\n\nexport const urlSchema = z\n .string()\n .url()\n .refine(\n (url) => {\n try {\n const parsed = new URL(url);\n return [\"http:\", \"https:\"].includes(parsed.protocol);\n } catch {\n return false;\n }\n },\n { message: \"URL must use http or https protocol\" },\n );\nexport type UrlType = z.infer<typeof urlSchema>;\n\n// stage duration:\nexport const durationSchema = z.number().int().positive(); // min: 1 second\nexport type DurationType = z.infer<typeof durationSchema>;\n\nexport const displayTimeSchema = z.number().int().nonnegative();\nexport type DisplayTimeType = z.infer<typeof displayTimeSchema>;\n\nexport const hideTimeSchema = z.number().int().positive();\nexport type HideTimeType = z.infer<typeof hideTimeSchema>;\n\nexport const positionSchema = z.number().int().nonnegative();\nexport type PositionType = z.infer<typeof positionSchema>;\n\nexport const positionSelectorSchema = z\n .enum([\"shared\", \"player\", \"all\", \"any\"])\n .or(positionSchema)\n .default(\"player\");\nexport type PositionSelectorType = z.infer<typeof positionSelectorSchema>;\n\nexport const showToPositionsSchema = z\n .array(positionSchema, {\n required_error:\n \"Expected an array for `showToPositions`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `showToPositions`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(); // TODO: check for unique values (or coerce to unique values)\nexport type ShowToPositionsType = z.infer<typeof showToPositionsSchema>;\n\nexport const hideFromPositionsSchema = z\n .array(positionSchema, {\n required_error:\n \"Expected an array for `hideFromPositions`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `hideFromPositions`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(); // TODO: check for unique values (or coerce to unique values)\nexport type HideFromPositionsType = z.infer<typeof hideFromPositionsSchema>;\n\nconst displayRegionRangeSchema = z\n .object({\n first: z.number().int().nonnegative(),\n last: z.number().int().nonnegative(),\n })\n .strict()\n .superRefine((value, ctx) => {\n if (value.last < value.first) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"`last` must be greater than or equal to `first`.\",\n });\n }\n });\n\nconst displayRegionAxisSchema = z.union([\n z.number().int().nonnegative(),\n displayRegionRangeSchema,\n]);\n\nexport const displayRegionSchema = z\n .object({\n rows: displayRegionAxisSchema,\n cols: displayRegionAxisSchema,\n })\n .strict();\nexport type DisplayRegionType = z.infer<typeof displayRegionSchema>;\n\nconst feedMediaSchema = z\n .object({\n audio: z.boolean().optional(),\n video: z.boolean().optional(),\n screen: z.boolean().optional(),\n })\n .strict();\n\nconst participantSourceSchema = z\n .object({\n type: z.literal(\"participant\"),\n position: positionSchema,\n })\n .strict();\n\nconst selfSourceSchema = z\n .object({\n type: z.literal(\"self\"),\n })\n .strict();\n\nconst otherSourceSchema = z\n .object({\n type: z\n .string()\n .min(1)\n .refine(\n (value) => value !== \"participant\" && value !== \"self\",\n \"Provide additional data using a different source type.\",\n ),\n position: z.union([positionSchema, z.string()]).optional(),\n })\n .strict();\n\nconst feedSourceSchema = z.union([\n participantSourceSchema,\n selfSourceSchema,\n otherSourceSchema,\n]);\n\nconst renderHintSchema = z.union([\n z.literal(\"auto\"),\n z.literal(\"tile\"),\n z.literal(\"audioOnlyBadge\"),\n z.literal(\"hidden\"),\n z.string().min(1),\n]);\n\nconst feedOptionsSchema = z.record(z.string(), z.unknown());\n\nconst layoutFeedSchema = z\n .object({\n source: feedSourceSchema,\n media: feedMediaSchema.optional(),\n displayRegion: displayRegionSchema,\n zOrder: z.number().int().optional(),\n render: renderHintSchema.optional(),\n label: z.string().optional(),\n options: feedOptionsSchema.optional(),\n })\n .strict();\n\nconst layoutFeedDefaultsSchema = z\n .object({\n media: feedMediaSchema.optional(),\n zOrder: z.number().int().optional(),\n render: renderHintSchema.optional(),\n label: z.string().optional(),\n options: feedOptionsSchema.optional(),\n })\n .strict();\n\nconst layoutGridOptionsSchema = z\n .object({\n gap: z.number().nonnegative().optional(),\n background: z.string().optional(),\n })\n .strict();\n\nconst layoutGridSchema = z\n .object({\n rows: z.number().int().positive(),\n cols: z.number().int().positive(),\n options: layoutGridOptionsSchema.optional(),\n })\n .strict();\n\nconst layoutDefinitionSchema = z\n .object({\n grid: layoutGridSchema,\n feeds: z.array(layoutFeedSchema).nonempty(),\n defaults: layoutFeedDefaultsSchema.optional(),\n })\n .strict()\n .superRefine((value, ctx) => {\n const gridRows = value.grid.rows;\n const gridCols = value.grid.cols;\n\n value.feeds.forEach((feed, feedIndex) => {\n const rows =\n typeof feed.displayRegion.rows === \"number\"\n ? { first: feed.displayRegion.rows, last: feed.displayRegion.rows }\n : feed.displayRegion.rows;\n const cols =\n typeof feed.displayRegion.cols === \"number\"\n ? { first: feed.displayRegion.cols, last: feed.displayRegion.cols }\n : feed.displayRegion.cols;\n\n if (rows.first >= gridRows || rows.last >= gridRows) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"feeds\", feedIndex, \"displayRegion\", \"rows\"],\n message: \"`rows` indices must be within the grid bounds.\",\n });\n }\n\n if (cols.first >= gridCols || cols.last >= gridCols) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"feeds\", feedIndex, \"displayRegion\", \"cols\"],\n message: \"`cols` indices must be within the grid bounds.\",\n });\n }\n });\n });\n\nconst layoutBySeatSchema = z\n .record(z.string(), layoutDefinitionSchema)\n .superRefine((value, ctx) => {\n Object.keys(value).forEach((key) => {\n const seat = Number(key);\n if (!Number.isInteger(seat) || seat < 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [key],\n message: \"Layout keys must be zero-based nonnegative integers.\",\n });\n }\n });\n });\n\nconst discussionRoomSchema = z\n .object({\n includePositions: z\n .array(positionSchema, {\n required_error:\n \"Expected an array for `includePositions`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `includePositions`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n })\n .strict();\n\nexport const discussionSchema = z\n .object({\n chatType: z.enum([\"text\", \"audio\", \"video\"]),\n showNickname: z.boolean(),\n showTitle: z.boolean(),\n showSelfView: z.boolean().optional().default(true),\n showReportMissing: z.boolean().optional().default(true),\n showAudioMute: z.boolean().optional().default(true),\n showVideoMute: z.boolean().optional().default(true),\n reactionEmojisAvailable: z.array(z.string()).optional(),\n reactToSelf: z.boolean().optional(),\n numReactionsPerMessage: z.number().int().nonnegative().optional(),\n layout: layoutBySeatSchema.optional(),\n rooms: z.array(discussionRoomSchema).nonempty().optional(),\n // New: allow discussion-level position-based visibility controls\n showToPositions: showToPositionsSchema.optional(),\n hideFromPositions: hideFromPositionsSchema.optional(),\n conditions: z.lazy(() => conditionsSchema).optional(),\n })\n .strict()\n .superRefine((data, ctx) => {\n // Emoji reaction parameters should only be used with text chat\n if (data.chatType !== \"text\") {\n if (data.reactionEmojisAvailable !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"reactionEmojisAvailable\"],\n message:\n \"reactionEmojisAvailable can only be used with chatType 'text'\",\n });\n }\n if (data.reactToSelf !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"reactToSelf\"],\n message: \"reactToSelf can only be used with chatType 'text'\",\n });\n }\n if (data.numReactionsPerMessage !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"numReactionsPerMessage\"],\n message:\n \"numReactionsPerMessage can only be used with chatType 'text'\",\n });\n }\n }\n\n if (data.layout !== undefined && data.chatType !== \"video\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"layout\"],\n message: \"layout can only be used with chatType 'video'\",\n });\n }\n\n if (data.rooms !== undefined && data.chatType !== \"video\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"rooms\"],\n message: \"rooms can only be used with chatType 'video'\",\n });\n }\n });\nexport type DiscussionType = z.infer<typeof discussionSchema>;\n\n// ------------------ Template contexts ------------------ //\nconst templateFieldKeysSchema = z\n .string()\n .regex(/^(?!d[0-9]+$)([a-zA-Z0-9_]+|\\$\\{[a-zA-Z0-9_]+\\})$/, {\n message:\n \"Field key must be alphanumeric with underscores only (no hyphens or spaces), or a placeholder `${fieldKey}`. Cannot conflict with reserved keys (d0, d1, etc.).\",\n })\n .min(1)\n .superRefine((val, ctx) => {\n //we do not want all template content data to default to template broadcast axis values schema,\n //so we add this conditon to have the closest match be elementSchema in templateContentSchema if field 'type' is used\n if (val == \"type\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"Field key cannot be 'type', as it is reserved for element types.\",\n });\n }\n });\n\nconst templateFieldsSchema = z.record(templateFieldKeysSchema, z.any());\n\nconst templateBroadcastAxisNameSchema = z.string().regex(/^d\\d+$/, {\n message: \"String must start with 'd' followed by a nonnegative integer\",\n});\n\nconst templateBroadcastAxisValuesSchema: z.ZodType = z.lazy(() =>\n z\n .array(templateFieldsSchema)\n .nonempty()\n .or(templateContextSchema)\n .or(templateFieldKeysSchema),\n);\n\nexport const templateContextSchema = z\n .object({\n template: nameSchema,\n fields: templateFieldsSchema.optional(),\n broadcast: z\n .record(\n templateBroadcastAxisNameSchema,\n templateBroadcastAxisValuesSchema,\n )\n .optional(),\n })\n .strict();\nexport type TemplateContextType = z.infer<typeof templateContextSchema>;\n\n// helper function to extend a schema with template context, and\nfunction altTemplateContext<T extends z.ZodTypeAny>(baseSchema: T) {\n return z.any().superRefine((data, ctx) => {\n if (data === undefined) {\n // throw new Error(\"data is undefined, this should not happen. This is a bug in the schema.\");\n // console.log(\n // \"data is undefined, this should not happen. This is a bug in the schema.\"\n // );\n // return ctx.addIssue({\n // code: z.ZodIssueCode.custom,\n // message: \"Data is undefined\",\n // });\n return;\n }\n // Determine schema based on presence of `template` field\n\n const schemaToUse =\n data !== null && typeof data === \"object\" && \"template\" in data\n ? templateContextSchema\n : baseSchema;\n // console.log(\"data\", data, \"schemaToUse\", 'template' in data ? \"template\" : \"base\");\n const result = schemaToUse.safeParse(data);\n\n if (!result.success) {\n result.error.issues.forEach((issue) =>\n ctx.addIssue({\n ...issue,\n path: [...issue.path],\n }),\n );\n }\n });\n}\n\n// ------------------ References ------------------ //\n\nexport const referenceSchema = z\n .string()\n .transform((str) => str.split(\".\"))\n .superRefine((arr, ctx) => {\n const [givenType] = arr; // destructure first element\n let name;\n let path;\n switch (givenType) {\n case \"survey\":\n case \"submitButton\":\n case \"qualtrics\":\n [, name, ...path] = arr;\n if (path.length < 1) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `A path must be provided, e.g. '${givenType}.${name}.object.selectors.here'`,\n path: [],\n });\n }\n if (name === undefined || name.length < 1) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `A name must be provided, e.g. '${givenType}.elementName.object.selectors.here'`,\n path: [],\n });\n }\n break;\n case \"discussion\":\n case \"participantInfo\":\n case \"prompt\":\n case \"trackedLink\":\n [, name] = arr;\n if (name === undefined || name.length < 1) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `A name must be provided, e.g. '${givenType}.elementName'`,\n path: [],\n });\n }\n break;\n case \"urlParams\":\n case \"connectionInfo\":\n case \"browserInfo\":\n [, ...path] = arr;\n if (path.length < 1) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `A path must be provided, e.g. '${givenType}.object.selectors.here.`,\n path: [],\n });\n }\n break;\n default:\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: `Invalid reference type \"${givenType}\", need to be in form of a valid reference type such as 'survey', 'submitButton', 'qualtrics', 'discussion', 'participantInfo', 'prompt', 'urlParams', 'connectionInfo', or 'browserInfo' followed by a . and name or path.`,\n path: [],\n });\n }\n });\n\nexport type ReferenceType = z.infer<typeof referenceSchema>;\n\n// --------------- Conditions --------------- //\n\nconst baseConditionSchema = z\n .object({\n reference: referenceSchema,\n position: z // todo: superrefine this somewhere so that it only exists in game stages, not in intro or exit steps\n .enum([\"shared\", \"player\", \"all\", \"any\", \"percentAgreement\"])\n .or(z.number().nonnegative().int())\n .optional(),\n })\n .strict();\n\nconst conditionExistsSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"exists\"),\n value: z.undefined(),\n })\n .strict();\n\nconst conditionDoesNotExistSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"doesNotExist\"),\n value: z.undefined(),\n })\n .strict();\n\nconst conditionEqualsSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"equals\"),\n value: z.string().or(z.number()).or(z.boolean()).or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionDoesNotEqualSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"doesNotEqual\"),\n value: z.string().or(z.number()).or(z.boolean()).or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIsAboveSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"isAbove\"),\n value: z.number().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIsBelowSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"isBelow\"),\n value: z.number().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIsAtLeastSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"isAtLeast\"),\n value: z.number().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIsAtMostSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"isAtMost\"),\n value: z.number().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionHasLengthAtLeastSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"hasLengthAtLeast\"),\n value: z.number().nonnegative().int().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionHasLengthAtMostSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"hasLengthAtMost\"),\n value: z.number().nonnegative().int().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIncludesSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"includes\"),\n value: z.string().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionDoesNotIncludeSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"doesNotInclude\"),\n value: z.string().or(fieldPlaceholderSchema),\n })\n .strict();\n\n// todo: extend this to include regex validation\nconst conditionMatchesSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"matches\"),\n value: z.string().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionDoesNotMatchSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"doesNotMatch\"),\n value: z.string().or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIsOneOfSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"isOneOf\"),\n value: z\n .array(z.string().or(z.number()))\n .nonempty()\n .or(fieldPlaceholderSchema),\n })\n .strict();\n\nconst conditionIsNotOneOfSchema = baseConditionSchema\n .extend({\n comparator: z.literal(\"isNotOneOf\"),\n value: z\n .array(z.string().or(z.number()))\n .nonempty()\n .or(fieldPlaceholderSchema),\n })\n .strict();\n\nexport const conditionSchema = altTemplateContext(\n z.discriminatedUnion(\"comparator\", [\n conditionExistsSchema,\n conditionDoesNotExistSchema,\n conditionEqualsSchema,\n conditionDoesNotEqualSchema,\n conditionIsAboveSchema,\n conditionIsBelowSchema,\n conditionIsAtLeastSchema,\n conditionIsAtMostSchema,\n conditionHasLengthAtLeastSchema,\n conditionHasLengthAtMostSchema,\n conditionIncludesSchema,\n conditionDoesNotIncludeSchema,\n conditionMatchesSchema,\n conditionDoesNotMatchSchema,\n conditionIsOneOfSchema,\n conditionIsNotOneOfSchema,\n ]),\n);\n\nexport const conditionsSchema = altTemplateContext(\n z\n .array(conditionSchema, {\n required_error:\n \"Expected an array for `conditions`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `conditions`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n);\nexport type ConditionType = z.infer<typeof conditionSchema>;\n\n// ------------------ Players ------------------ //\n\nexport const playerSchema = z\n .object({\n desc: descriptionSchema.optional(),\n position: positionSchema,\n title: z.string().max(25).optional(),\n conditions: z\n .array(conditionSchema, {\n invalid_type_error:\n \"Expected an array for `conditions`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .optional(),\n })\n .strict();\nexport type PlayerType = z.infer<typeof playerSchema>;\n\n// ------------------ Elements ------------------ //\n\nconst elementBaseSchema = z\n .object({\n name: nameSchema.optional(),\n desc: descriptionSchema.optional(),\n file: fileSchema.or(fieldPlaceholderSchema).optional(),\n displayTime: displayTimeSchema.or(fieldPlaceholderSchema).optional(),\n hideTime: hideTimeSchema.or(fieldPlaceholderSchema).optional(),\n showToPositions: showToPositionsSchema\n .or(fieldPlaceholderSchema)\n .optional(),\n hideFromPositions: hideFromPositionsSchema\n .or(fieldPlaceholderSchema)\n .optional(),\n conditions: conditionsSchema.optional(),\n tags: z\n .array(z.string(), {\n invalid_type_error:\n \"Expected an array for `tags`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .optional(),\n })\n .strict();\n\nconst audioSchema = elementBaseSchema\n .extend({\n type: z.literal(\"audio\"),\n file: fileSchema,\n // Todo: check that file exists\n })\n .strict();\n\nconst imageSchema = elementBaseSchema\n .extend({\n type: z.literal(\"image\"),\n file: fileSchema,\n // Todo: check that file exists\n })\n .strict();\n\nconst displaySchema = elementBaseSchema\n .extend({\n type: z.literal(\"display\"),\n reference: referenceSchema,\n position: positionSelectorSchema,\n })\n .strict();\n\nexport const promptSchema = elementBaseSchema\n .extend({\n type: z.literal(\"prompt\"),\n file: promptFilePathSchema,\n shared: z.boolean().optional(),\n })\n .strict();\n\nconst promptShorthandSchema = promptFilePathSchema.transform((str) => {\n const newElement = {\n type: \"prompt\",\n file: str,\n name: str,\n };\n return newElement;\n});\n\nconst separatorSchema = elementBaseSchema\n .extend({\n type: z.literal(\"separator\"),\n style: z.enum([\"thin\", \"thick\", \"regular\"]).optional(),\n })\n .strict();\n\nconst sharedNotepadSchema = elementBaseSchema\n .extend({\n type: z.literal(\"sharedNotepad\"),\n })\n .strict();\n\nconst submitButtonSchema = elementBaseSchema\n .extend({\n type: z.literal(\"submitButton\"),\n buttonText: z.string().max(50).optional(),\n })\n .strict();\n\nconst surveySchema = elementBaseSchema\n .extend({\n type: z.literal(\"survey\"),\n surveyName: z.string(),\n // Todo: check that surveyName is a valid survey name\n })\n .strict();\n\nconst talkMeterSchema = elementBaseSchema\n .extend({\n type: z.literal(\"talkMeter\"),\n })\n .strict();\n\nconst timerSchema = elementBaseSchema\n .extend({\n type: z.literal(\"timer\"),\n startTime: z.number().gt(0).optional(),\n endTime: z.number().gt(0).optional(),\n warnTimeRemaining: z.number().gt(0).optional(),\n // Todo: check that startTime < endTime\n // Todo: check that warnTimeRemaining < endTime - startTime\n })\n .strict();\n\nconst mediaPlayerControlsSchema = z\n .object({\n playPause: z.boolean().optional(),\n seek: z.boolean().optional(),\n step: z.boolean().optional(),\n speed: z.boolean().optional(),\n })\n .strict()\n .optional();\n\nexport const mediaPlayerSchema = elementBaseSchema\n .extend({\n type: z.literal(\"mediaPlayer\"),\n url: z.string(),\n playVideo: z.boolean().optional(),\n playAudio: z.boolean().optional(),\n captionsFile: z.string().optional(),\n startAt: z.number().nonnegative().optional(),\n stopAt: z.number().positive().optional(),\n allowScrubOutsideBounds: z.boolean().optional(),\n stepDuration: z.number().positive().optional(),\n syncToStageTime: z.boolean().optional(),\n submitOnComplete: z.boolean().optional(),\n controls: mediaPlayerControlsSchema,\n })\n .strict();\n\nexport type MediaPlayerType = z.infer<typeof mediaPlayerSchema>;\n\nexport const timelineSchema = elementBaseSchema\n .extend({\n type: z.literal(\"timeline\"),\n source: nameSchema,\n name: nameSchema,\n selectionType: z.enum([\"range\", \"point\"]),\n selectionScope: z.enum([\"track\", \"all\"]).optional(),\n multiSelect: z.boolean().optional(),\n showWaveform: z.boolean().optional(),\n trackLabels: z\n .array(z.string(), {\n invalid_type_error:\n \"Expected an array for `trackLabels`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .optional(),\n })\n .strict();\n\nexport type TimelineType = z.infer<typeof timelineSchema>;\n\nconst trackedLinkParamSchema = z\n .object({\n key: z.string().min(1),\n value: z\n .union([z.string(), z.number(), z.boolean(), fieldPlaceholderSchema])\n .optional(),\n reference: referenceSchema.optional(),\n position: positionSelectorSchema.optional(),\n })\n .strict()\n .superRefine((data, ctx) => {\n if (data.value !== undefined && data.reference !== undefined) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Provide either `value` or `reference`, not both.\",\n path: [\"value\"],\n });\n }\n });\n\nconst qualtricsSchema = elementBaseSchema\n .extend({\n type: z.literal(\"qualtrics\"),\n url: urlSchema,\n urlParams: z\n .array(trackedLinkParamSchema, {\n invalid_type_error:\n \"Expected an array for `urlParams`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .optional(),\n })\n .strict();\n\n// Element for instrumented external links (see client/src/elements/TrackedLink.jsx).\n// We validate the static fields plus the structured urlParams array so that Typos get caught at preflight.\nconst trackedLinkSchema = elementBaseSchema\n .extend({\n type: z.literal(\"trackedLink\"),\n name: nameSchema,\n url: urlSchema,\n displayText: z.string().min(1),\n helperText: z.string().optional(),\n urlParams: z\n .array(trackedLinkParamSchema, {\n invalid_type_error:\n \"Expected an array for `urlParams`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .optional(),\n })\n .strict();\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst validElementTypes = [\n \"audio\",\n \"display\",\n \"image\",\n \"prompt\",\n \"qualtrics\",\n \"separator\",\n \"sharedNotepad\",\n \"submitButton\",\n \"survey\",\n \"talkMeter\",\n \"timer\",\n \"mediaPlayer\",\n \"timeline\",\n \"trackedLink\",\n];\n\nexport const elementSchema = altTemplateContext(\n z.any().superRefine((data, ctx) => {\n const isObject = typeof data === \"object\" && data !== null;\n const hasTypeKey = isObject && \"type\" in data;\n\n const schemaToUse = hasTypeKey\n ? z.discriminatedUnion(\"type\", [\n audioSchema,\n displaySchema,\n imageSchema,\n promptSchema,\n qualtricsSchema,\n separatorSchema,\n sharedNotepadSchema,\n submitButtonSchema,\n surveySchema,\n talkMeterSchema,\n timerSchema,\n mediaPlayerSchema,\n timelineSchema,\n trackedLinkSchema,\n ])\n : promptShorthandSchema;\n\n const result = schemaToUse.safeParse(data);\n\n if (!result.success) {\n //promptShorthandSchema is a special case where we expect a string\n //But there are 0 key mismatches as a result of this for whatever object\n //is input, messes up matching logic in templateContentSchema\n if (!hasTypeKey && isObject && schemaToUse === promptShorthandSchema) {\n // If we expected a string (promptShorthand) but got an object instead\n // Add one error per key\n ctx.addIssue({\n code: \"invalid_type\",\n expected: \"string\",\n received: \"object\",\n message: `promptShorthandSchema expects a string, but received object.`,\n });\n for (const key of Object.keys(data)) {\n ctx.addIssue({\n code: \"unrecognized_keys\",\n keys: [key],\n });\n }\n } else {\n // Forward errors from schemaToUse\n result.error.issues.forEach((issue) =>\n ctx.addIssue({\n ...issue,\n path: [...issue.path],\n }),\n );\n }\n }\n\n // Cross-field validation for mediaPlayer\n if (\n isObject &&\n (data as { type?: unknown }).type === \"mediaPlayer\" &&\n result.success\n ) {\n const mp = data as { startAt?: number; stopAt?: number };\n if (\n mp.startAt !== undefined &&\n mp.stopAt !== undefined &&\n mp.stopAt <= mp.startAt\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"stopAt must be greater than startAt\",\n path: [\"stopAt\"],\n });\n }\n const mpSync = data as {\n syncToStageTime?: boolean;\n controls?: Record<string, boolean>;\n };\n if (mpSync.syncToStageTime && mpSync.controls) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"controls cannot be specified when syncToStageTime is true (playback is locked to stage time)\",\n path: [\"controls\"],\n });\n }\n }\n }),\n);\n\nexport type ElementType = z.infer<typeof elementSchema>;\n\nexport const elementsSchema = altTemplateContext(\n z\n .array(elementSchema, {\n required_error:\n \"Expected an array for `elements`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `elements`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n);\n\nexport type ElementsType = z.infer<typeof elementsSchema>;\n\n// ------------------ Stages ------------------ //\n\nexport const stageSchema = altTemplateContext(\n z\n .object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n discussion: discussionSchema.optional(),\n duration: durationSchema.or(fieldPlaceholderSchema),\n elements: elementsSchema,\n })\n .strict()\n .superRefine((data, ctx) => {\n //For some reason, above conditions are bypassing the strict check\n // so we add a superRefine to check that elements field exists\n if (!data.elements) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"Stage must have elements field (check elementsSchema).\",\n });\n }\n\n // Validate element time bounds against stage duration\n const duration = data.duration;\n if (typeof duration !== \"number\" || !Array.isArray(data.elements)) return;\n\n data.elements.forEach(\n (element: Record<string, unknown>, elementIndex: number) => {\n if (!element || typeof element !== \"object\") return;\n\n const timeFields = [\n \"displayTime\",\n \"hideTime\",\n \"startTime\",\n \"endTime\",\n ] as const;\n for (const field of timeFields) {\n const value = element[field];\n if (typeof value === \"number\" && value > duration) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"elements\", elementIndex, field],\n message: `${field} (${value}) exceeds stage duration (${duration}) for element \"${String(element.name || element.type)}\"`,\n });\n }\n }\n },\n );\n }),\n);\nexport type StageType = z.infer<typeof stageSchema>;\n\nconst stagesSchema = altTemplateContext(\n z\n .array(stageSchema, {\n required_error:\n \"Expected an array for `stages`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `stages`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n);\n\nexport const introExitStepSchema = altTemplateContext(\n z\n .object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n elements: elementsSchema,\n })\n .strict(),\n);\n// Todo: add a superrefine that checks that no conditions have position values\n// and that no elements have showToPositions or hideFromPositions\nexport type IntroExitStepType = z.infer<typeof introExitStepSchema>;\n\nexport const introExitStepsBaseSchema = altTemplateContext(\n z\n .array(introExitStepSchema, {\n required_error:\n \"Expected an array for `introSteps`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `introSteps`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n);\n\n// Backwards compatibility export for downstream packages still referencing the legacy name.\nexport const introExitStepsSchema = introExitStepsBaseSchema;\n\n// Returns true if the element satisfies the advancement requirement for an\n// intro/exit step: submitButton (explicit), survey/qualtrics (auto-submit on\n// completion), or mediaPlayer with submitOnComplete: true (auto-submits when\n// playback ends).\nfunction isAdvancementElement(element: ElementType): boolean {\n if (!element || typeof element !== \"object\") return false;\n const el = element as Record<string, unknown>;\n if (el.type === \"submitButton\") return true;\n if (el.type === \"survey\") return true;\n if (el.type === \"qualtrics\") return true;\n if (el.type === \"mediaPlayer\" && el.submitOnComplete === true) return true;\n return false;\n}\n\nexport const introStepsSchema = introExitStepsBaseSchema.superRefine(\n (data, ctx) => {\n data?.forEach((step: IntroExitStepType, stepIdx: number) => {\n if (Array.isArray(step.elements)) {\n step.elements.forEach((element: ElementType, elementIdx: number) => {\n if (\n element &&\n typeof element === \"object\" &&\n \"shared\" in element &&\n element.shared\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\", elementIdx, \"shared\"],\n message: `Prompt element in intro/exit steps cannot be shared.`,\n });\n }\n if (element && typeof element === \"object\" && \"position\" in element) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\", elementIdx, \"position\"],\n message: `Elements in intro steps cannot have a 'position' field.`,\n });\n }\n if (\n element &&\n typeof element === \"object\" &&\n \"showToPositions\" in element\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\", elementIdx],\n message: `Elements in intro steps cannot have a 'showToPositions' field.`,\n });\n }\n if (\n element &&\n typeof element === \"object\" &&\n \"hideFromPositions\" in element\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\", elementIdx],\n message: `Elements in intro steps cannot have a 'hideFromPositions' field.`,\n });\n }\n });\n\n if (!step.elements.some(isAdvancementElement)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\"],\n message:\n \"Intro/exit step must include at least one advancement element: submitButton, survey, qualtrics, or mediaPlayer with submitOnComplete: true.\",\n });\n }\n }\n });\n },\n);\n\nexport const exitStepsSchema = introExitStepsBaseSchema.superRefine(\n (data, ctx) => {\n data?.forEach((step: IntroExitStepType, stepIdx: number) => {\n if (Array.isArray(step.elements)) {\n step.elements.forEach((element: ElementType, elementIdx: number) => {\n if (\n element &&\n typeof element === \"object\" &&\n \"shared\" in element &&\n element.shared\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\", elementIdx, \"shared\"],\n message: `Prompt element in intro/exit steps cannot be shared.`,\n });\n }\n });\n\n if (!step.elements.some(isAdvancementElement)) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [stepIdx, \"elements\"],\n message:\n \"Intro/exit step must include at least one advancement element: submitButton, survey, qualtrics, or mediaPlayer with submitOnComplete: true.\",\n });\n }\n }\n });\n },\n);\n\n// ------------------ Intro Sequences and Treatments ------------------ //\nexport const introSequenceSchema = altTemplateContext(\n z\n .object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n introSteps: introStepsSchema,\n })\n .strict(),\n);\nexport type IntroSequenceType = z.infer<typeof introSequenceSchema>;\n\nexport const introSequencesSchema = altTemplateContext(\n z\n .array(introSequenceSchema, {\n required_error:\n \"Expected an array for `introSequence`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `introSequence`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n);\n\nexport const baseTreatmentSchema = z\n .object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n playerCount: z.number(),\n groupComposition: z\n .array(playerSchema, {\n invalid_type_error:\n \"Expected an array for `groupComposition`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .optional(),\n gameStages: stagesSchema,\n exitSequence: exitStepsSchema.optional(),\n })\n .strict();\n\nexport const treatmentSchema = altTemplateContext(\n baseTreatmentSchema\n //works currently for the case where playerSchema always occurs within a treatmentSchema\n //However if a playerSchema is used outside of a treatmentSchema, this will not work, as playerCount will not be defined in its scope\n //With the current structure of templateSchema, this is hypothetically possible, but unlikely\n .superRefine((treatment, ctx) => {\n const baseResult = baseTreatmentSchema.safeParse(treatment);\n if (!baseResult.success) {\n return;\n }\n const { playerCount, groupComposition, gameStages } = treatment;\n groupComposition?.forEach((player, index) => {\n if (\n typeof player.position === \"number\" &&\n player.position >= playerCount\n ) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"groupComposition\", index, \"position\"],\n message: `Player position index ${player.position} in groupComposition exceeds playerCount of ${playerCount}.`,\n });\n }\n });\n if (groupComposition) {\n const positions = groupComposition\n .map((player) => player.position)\n .filter((pos) => typeof pos === \"number\");\n const uniquePositions = new Set(positions);\n if (uniquePositions.size !== positions.length) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"groupComposition\"],\n message: `Player positions in groupComposition must be unique.`,\n });\n }\n const expectedPositions = Array.from(\n { length: playerCount },\n (_, i) => i,\n );\n const missingPositions = expectedPositions.filter(\n (pos) => !uniquePositions.has(pos),\n );\n if (missingPositions.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"groupComposition\"],\n message: `Player positions in groupComposition must include all nonnegative integers below playerCount (${playerCount}). Missing: ${missingPositions.join(\", \")}.`,\n });\n }\n }\n gameStages?.forEach(\n (\n stage: {\n elements?: Record<string, unknown>[];\n name?: string;\n discussion?: Record<string, unknown>;\n },\n stageIndex: number,\n ) => {\n stage?.elements?.forEach(\n (element: Record<string, unknown>, elementIndex: number) => {\n [\"showToPositions\", \"hideFromPositions\"].forEach((key) => {\n const positions = element[key];\n if (Array.isArray(positions)) {\n positions?.forEach((pos, posIndex) => {\n if (typeof pos === \"number\" && pos >= playerCount) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"gameStages\",\n stageIndex,\n \"elements\",\n elementIndex,\n key,\n posIndex,\n ],\n message: `${key} index ${pos} in stage \"${stage.name}\" exceeds playerCount of ${playerCount}.`,\n });\n }\n });\n }\n });\n },\n );\n\n const discussion = stage?.discussion;\n if (discussion) {\n [\"showToPositions\", \"hideFromPositions\"].forEach((key) => {\n const positions = discussion?.[key];\n if (Array.isArray(positions)) {\n positions.forEach((pos, posIndex) => {\n if (typeof pos === \"number\" && pos >= playerCount) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"gameStages\",\n stageIndex,\n \"discussion\",\n key,\n posIndex,\n ],\n message: `${key} index ${pos} in discussion of stage \"${stage.name}\" exceeds playerCount of ${playerCount}.`,\n });\n }\n });\n }\n });\n\n const { rooms, showToPositions, hideFromPositions } =\n discussion || {};\n if (Array.isArray(rooms) && rooms.length > 0) {\n const allPositions: number[] = Array.from(\n { length: playerCount },\n (_, i) => i,\n );\n let candidatePositions = allPositions;\n if (\n Array.isArray(showToPositions) &&\n showToPositions.length > 0\n ) {\n candidatePositions = candidatePositions.filter((p) =>\n showToPositions.includes(p),\n );\n }\n if (\n Array.isArray(hideFromPositions) &&\n hideFromPositions.length > 0\n ) {\n candidatePositions = candidatePositions.filter(\n (p) => !hideFromPositions.includes(p),\n );\n }\n\n const assigned = new Set<number>();\n rooms.forEach(\n (room: Record<string, unknown>, roomIndex: number) => {\n const inc = room?.includePositions;\n if (Array.isArray(inc)) {\n inc.forEach((pos: unknown, posIndex: number) => {\n if (typeof pos === \"number\") {\n assigned.add(pos);\n if (pos >= playerCount) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\n \"gameStages\",\n stageIndex,\n \"discussion\",\n \"rooms\",\n roomIndex,\n \"includePositions\",\n posIndex,\n ],\n message: `includePositions index ${pos} in discussion room exceeds playerCount of ${playerCount}.`,\n });\n }\n }\n });\n }\n },\n );\n\n const missing = candidatePositions.filter(\n (p) => !assigned.has(p),\n );\n if (missing.length > 0) {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n path: [\"gameStages\", stageIndex, \"discussion\", \"rooms\"],\n message: `Rooms defined but the following visible player positions are not assigned to any room: ${missing.join(\n \", \",\n )}. Each visible position (respecting showToPositions/hideFromPositions) must appear in one includePositions array.`,\n });\n }\n }\n }\n },\n );\n }),\n);\n\nexport type TreatmentType = z.infer<typeof treatmentSchema>;\n\nexport const treatmentsSchema = altTemplateContext(\n z\n .array(treatmentSchema, {\n required_error:\n \"Expected an array for `treatments`. Make sure each item starts with a dash (`-`) in YAML.\",\n invalid_type_error:\n \"Expected an array for `treatments`. Make sure each item starts with a dash (`-`) in YAML.\",\n })\n .nonempty(),\n);\n\n// ------------------ Template Schemas ------------------ //\nexport const templateContentSchema = z.any().superRefine((data, ctx) => {\n const schemas = [\n { schema: introSequenceSchema, name: \"Intro Sequence\" },\n { schema: introSequencesSchema, name: \"Intro Sequences\" },\n { schema: elementsSchema, name: \"Elements\" },\n { schema: elementSchema, name: \"Element\" },\n { schema: stageSchema, name: \"Stage\" },\n { schema: stagesSchema, name: \"Stages\" },\n { schema: treatmentSchema, name: \"Treatment\" },\n { schema: treatmentsSchema, name: \"Treatments\" },\n { schema: referenceSchema, name: \"Reference\" },\n { schema: conditionSchema, name: \"Condition\" },\n { schema: playerSchema, name: \"Player\" },\n // specify intro step or exit step, not both\n { schema: introExitStepSchema, name: \"Intro Exit Step\" },\n { schema: exitStepsSchema, name: \"Exit Steps\" },\n //commented out for now, matches too many schemas\n {\n schema: templateBroadcastAxisValuesSchema,\n name: \"Template Broadcast Axis Values\",\n },\n ];\n\n let bestSchemaResult = null;\n let fewestUnmatchedKeys = Infinity;\n\n // console.log(\"\\n\\n------------------\\n\\n\");\n\n interface Issue {\n code: string;\n path: (string | number)[];\n keys?: string[];\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface ValidationResult {\n error: {\n issues: Issue[];\n };\n }\n\n for (const { schema, name } of schemas) {\n const result = schema.safeParse(data);\n\n if (result.success) {\n console.log(`Schema \"${name}\" matched successfully.`);\n return;\n } else {\n // console.log(`Schema \"${name}\" failed with errors:`, result.error.issues);\n\n // Check if the root type was valid by looking for type-related issues.\n const rootTypeError = result.error.issues.find(\n (issue: Issue) =>\n issue.code === \"invalid_type\" && issue.path.length === 0,\n );\n if (rootTypeError) {\n // console.log(`Schema \"${name}\" skipped due to invalid root type.`);\n continue; // Skip schemas with invalid root types.\n }\n\n // Check if the errors indicate a missing or invalid discriminator key\n const discriminatorIssue = result.error.issues.find(\n (issue: Issue) =>\n issue.code === \"invalid_union_discriminator\" &&\n issue.path.length === 1,\n );\n\n const promptShorthandIssue = result.error.issues.find(\n (issue: ZodIssue) =>\n issue.code === \"invalid_type\" &&\n issue.expected === \"string\" &&\n issue.received === \"object\" &&\n issue.message ===\n \"promptShorthandSchema expects a string, but received object.\",\n );\n\n if (discriminatorIssue !== undefined) {\n // console.log(`Schema \"${name}\" skipped due to missing or invalid union discriminator.`);\n continue;\n }\n\n // Count the total number of unrecognized keys\n const unmatchedKeysCount = result.error.issues\n .filter((issue: Issue) => issue.code === \"unrecognized_keys\")\n .reduce(\n (sum: number, issue: Issue) =>\n sum + (issue.keys ? issue.keys.length : 0),\n 0,\n );\n\n if (unmatchedKeysCount < fewestUnmatchedKeys) {\n if (promptShorthandIssue) {\n continue;\n }\n fewestUnmatchedKeys = unmatchedKeysCount;\n bestSchemaResult = { result, name };\n }\n }\n }\n\n if (bestSchemaResult) {\n console.log(\n `Best schema match is \"${bestSchemaResult.name}\" with ${fewestUnmatchedKeys} unmatched keys.`,\n );\n bestSchemaResult.result.error.issues.forEach((issue: ZodIssue) => {\n ctx.addIssue({\n ...issue,\n path: issue.path,\n message: `Closest schema match: ${bestSchemaResult.name}. ${issue.message}`,\n });\n });\n } else {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message: \"No schema matched the provided data.\",\n });\n }\n});\n\n//update templateSchema so that content types are defined as a field for easier matching of\n//templateContent data to their respective schemas\n//contentType is optional for now, but will be required in the future\nexport const templateSchema = z\n .object({\n templateName: nameSchema,\n contentType: z\n .enum([\n \"introSequence\",\n \"introSequences\",\n \"elements\",\n \"element\",\n \"stage\",\n \"stages\",\n \"treatment\",\n \"treatments\",\n \"reference\",\n \"condition\",\n \"player\",\n \"introExitStep\",\n \"exitSteps\",\n \"other\",\n ])\n .optional(),\n templateDesc: descriptionSchema.optional(),\n templateContent: z.any(),\n })\n .strict()\n .superRefine((data, ctx) => {\n if (!data.contentType) {\n const res = templateContentSchema.safeParse(data.templateContent);\n if (!res.success) {\n res.error.issues.forEach((issue) =>\n ctx.addIssue({\n ...issue,\n path: [\"templateContent\", ...issue.path],\n }),\n );\n }\n\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"contentType field is required. Please specify a valid content type. Valid content types are 'introSequence', 'introSequences', 'elements', 'element', 'stage', 'stages', 'treatment', 'treatments', 'reference', 'condition', 'player', 'introExitStep', or 'exitSteps'.\",\n });\n\n return;\n } else if (data.contentType === \"other\") {\n ctx.addIssue({\n code: z.ZodIssueCode.custom,\n message:\n \"contentType 'other' cannot be validated. Only use when custom content is required that does not match any of the other defined content types. Please use at your own discretion.\",\n });\n return;\n }\n\n const result = matchContentType(data.contentType).safeParse(\n data.templateContent,\n );\n if (!result.success) {\n result.error.issues.forEach((issue) =>\n ctx.addIssue({\n ...issue,\n path: [\"templateContent\", ...issue.path],\n message: `Invalid template content for content type '${data.contentType}': ${issue.message}`,\n }),\n );\n }\n });\n\nexport function matchContentType(contentType: string) {\n switch (contentType) {\n case \"introSequence\":\n return introSequenceSchema;\n case \"introSequences\":\n return introSequencesSchema;\n case \"elements\":\n return elementsSchema;\n case \"element\":\n return elementSchema;\n case \"stage\":\n return stageSchema;\n case \"stages\":\n return stagesSchema;\n case \"treatment\":\n return treatmentSchema;\n case \"treatments\":\n return treatmentsSchema;\n case \"reference\":\n return referenceSchema;\n case \"condition\":\n return conditionSchema;\n case \"player\":\n return playerSchema;\n case \"introExitStep\":\n return introExitStepSchema;\n case \"exitSteps\":\n return exitStepsSchema;\n default:\n throw new Error(`Unknown content type: ${contentType}`);\n }\n}\n\nexport type TemplateType = z.infer<typeof templateSchema>;\n\n// ------------------ Treatment File ------------------ //\nexport const treatmentFileSchema = z.object({\n templates: z\n .array(templateSchema)\n .min(1, \"Templates cannot be empty\")\n .optional(),\n introSequences: introSequencesSchema,\n treatments: treatmentsSchema,\n});\nexport type TreatmentFileType = z.infer<typeof treatmentFileSchema>;\n","/**\n * Resolved (post-hydration) schemas for component consumption.\n *\n * These schemas describe what treatment data looks like AFTER template\n * expansion — no template contexts, no ${field} placeholders. They provide\n * proper TypeScript types for Stage, Element, and other component props.\n *\n * The full schemas in treatment.ts (with altTemplateContext wrappers) are\n * used for validating raw treatment files. These resolved schemas are used\n * by rendering components that only see hydrated data.\n */\nimport { z } from \"zod\";\nimport {\n nameSchema,\n descriptionSchema,\n durationSchema,\n displayTimeSchema,\n hideTimeSchema,\n positionSchema,\n positionSelectorSchema,\n showToPositionsSchema,\n hideFromPositionsSchema,\n discussionSchema,\n referenceSchema,\n} from \"./treatment.js\";\n\n// ----------------------------------------------------------------\n// Resolved condition — no template placeholders in values\n// ----------------------------------------------------------------\n\nconst resolvedConditionSchema = z\n .object({\n reference: referenceSchema,\n position: z\n .enum([\"shared\", \"player\", \"all\", \"any\", \"percentAgreement\"])\n .or(z.number().nonnegative().int())\n .optional(),\n comparator: z.enum([\n \"exists\",\n \"doesNotExist\",\n \"equals\",\n \"doesNotEqual\",\n \"isAbove\",\n \"isBelow\",\n \"isAtLeast\",\n \"isAtMost\",\n \"hasLengthAtLeast\",\n \"hasLengthAtMost\",\n \"includes\",\n \"doesNotInclude\",\n \"matches\",\n \"doesNotMatch\",\n \"isOneOf\",\n \"isNotOneOf\",\n ]),\n value: z\n .union([\n z.string(),\n z.number(),\n z.boolean(),\n z.array(z.string().or(z.number())),\n ])\n .optional(),\n })\n .strict();\n\nconst resolvedConditionsSchema = z.array(resolvedConditionSchema).optional();\n\n// ----------------------------------------------------------------\n// Resolved element — concrete type union, no placeholders\n// ----------------------------------------------------------------\n\nconst resolvedElementBaseSchema = z.object({\n type: z.string(),\n name: nameSchema.optional(),\n desc: descriptionSchema.optional(),\n file: z.string().optional(),\n displayTime: displayTimeSchema.optional(),\n hideTime: hideTimeSchema.optional(),\n showToPositions: showToPositionsSchema.optional(),\n hideFromPositions: hideFromPositionsSchema.optional(),\n conditions: resolvedConditionsSchema,\n tags: z.array(z.string()).optional(),\n // Allow additional fields for specific element types\n shared: z.boolean().optional(),\n buttonText: z.string().optional(),\n url: z.string().optional(),\n displayText: z.string().optional(),\n helperText: z.string().optional(),\n reference: z.string().optional(),\n position: positionSelectorSchema.optional(),\n surveyName: z.string().optional(),\n startTime: z.number().optional(),\n endTime: z.number().optional(),\n warnTimeRemaining: z.number().optional(),\n style: z.enum([\"thin\", \"regular\", \"thick\", \"\"]).optional(),\n width: z.number().optional(),\n urlParams: z\n .array(\n z.object({\n key: z.string(),\n value: z.union([z.string(), z.number(), z.boolean()]).optional(),\n reference: z.string().optional(),\n position: positionSelectorSchema.optional(),\n }),\n )\n .optional(),\n // mediaPlayer fields\n syncToStageTime: z.boolean().optional(),\n submitOnComplete: z.boolean().optional(),\n playVideo: z.boolean().optional(),\n playAudio: z.boolean().optional(),\n captionsFile: z.string().optional(),\n startAt: z.number().optional(),\n stopAt: z.number().optional(),\n allowScrubOutsideBounds: z.boolean().optional(),\n stepDuration: z.number().optional(),\n controls: z\n .object({\n playPause: z.boolean().optional(),\n seek: z.boolean().optional(),\n step: z.boolean().optional(),\n speed: z.boolean().optional(),\n })\n .optional(),\n});\n\nexport const resolvedElementSchema = resolvedElementBaseSchema;\nexport type ResolvedElementType = z.infer<typeof resolvedElementSchema>;\n\n// ----------------------------------------------------------------\n// Resolved stage — concrete duration, resolved elements\n// ----------------------------------------------------------------\n\nexport const resolvedStageSchema = z.object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n discussion: discussionSchema.optional(),\n duration: durationSchema,\n elements: z.array(resolvedElementSchema).nonempty(),\n});\nexport type ResolvedStageType = z.infer<typeof resolvedStageSchema>;\n\n// ----------------------------------------------------------------\n// Resolved intro/exit step — no duration, no position visibility\n// ----------------------------------------------------------------\n\nexport const resolvedIntroExitStepSchema = z.object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n elements: z.array(resolvedElementSchema).nonempty(),\n});\nexport type ResolvedIntroExitStepType = z.infer<\n typeof resolvedIntroExitStepSchema\n>;\n\n// ----------------------------------------------------------------\n// Resolved treatment — concrete playerCount, resolved stages\n// ----------------------------------------------------------------\n\nexport const resolvedTreatmentSchema = z.object({\n name: nameSchema,\n desc: descriptionSchema.optional(),\n playerCount: z.number(),\n groupComposition: z\n .array(\n z.object({\n desc: descriptionSchema.optional(),\n position: positionSchema,\n title: z.string().max(25).optional(),\n conditions: resolvedConditionsSchema,\n }),\n )\n .optional(),\n gameStages: z.array(resolvedStageSchema).nonempty(),\n exitSequence: z.array(resolvedIntroExitStepSchema).optional(),\n});\nexport type ResolvedTreatmentType = z.infer<typeof resolvedTreatmentSchema>;\n\n// ----------------------------------------------------------------\n// Re-export resolved condition type\n// ----------------------------------------------------------------\n\nexport { resolvedConditionSchema, resolvedConditionsSchema };\nexport type ResolvedConditionType = z.infer<typeof resolvedConditionSchema>;\n","export function getNestedValueByPath(\n obj: unknown,\n path: string[] = [],\n): unknown {\n return path.reduce(\n (acc: unknown, key: string) =>\n acc !== null && acc !== undefined\n ? (acc as Record<string, unknown>)[key]\n : undefined,\n obj,\n );\n}\n\nexport interface ReferenceKeyAndPath {\n referenceKey: string;\n path: string[];\n}\n\nexport function getReferenceKeyAndPath(reference: string): ReferenceKeyAndPath {\n const segments = reference.split(\".\");\n const [type, ...rest] = segments;\n let name: string | undefined;\n let path: string[] = [];\n let referenceKey: string | undefined;\n\n if ([\"survey\", \"submitButton\", \"qualtrics\"].includes(type)) {\n [name, ...path] = rest;\n referenceKey = `${type}_${name}`;\n } else if (type === \"prompt\") {\n [name] = rest;\n referenceKey = `${type}_${name}`;\n path = [\"value\"];\n } else if (type === \"trackedLink\") {\n [name, ...path] = rest;\n referenceKey = `trackedLink_${name}`;\n } else if ([\"urlParams\", \"connectionInfo\", \"browserInfo\"].includes(type)) {\n path = rest;\n referenceKey = type;\n } else if ([\"participantInfo\", \"discussion\"].includes(type)) {\n [name, ...path] = rest;\n referenceKey = name;\n } else {\n throw new Error(`Invalid reference type: ${type}`);\n }\n\n if (\n !referenceKey ||\n (!name &&\n [\n \"survey\",\n \"submitButton\",\n \"qualtrics\",\n \"prompt\",\n \"trackedLink\",\n \"participantInfo\",\n \"discussion\",\n ].includes(type))\n ) {\n throw new Error(`Reference ${reference} is missing a name segment.`);\n }\n\n return { referenceKey, path };\n}\n","/* eslint-disable @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-explicit-any */\n\nimport { templateContextSchema } from \"../schemas/treatment.js\";\n\nfunction escapeRegExp(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n// Matches ${...} placeholders. Only alphanumeric + underscore allowed in field names.\n// Shared pattern — must match fieldPlaceholderRegex in schemas/treatment.ts\nconst FIELD_PLACEHOLDER_REGEX = /\\$\\{([a-zA-Z0-9_]+)\\}/g;\n\nexport function substituteFields({\n templateContent,\n fields,\n}: {\n templateContent: any;\n fields: Record<string, any>;\n}): any {\n let expandedTemplate = JSON.parse(JSON.stringify(templateContent));\n\n for (const [key, value] of Object.entries(fields)) {\n // Skip undefined values — they can't be JSON-serialized and would\n // produce invalid JSON if substituted. Null is valid JSON.\n if (value === undefined) continue;\n\n let stringifiedTemplate = JSON.stringify(expandedTemplate);\n const stringifiedValue = JSON.stringify(value);\n\n // replace all instances of `\"${key}\"` with serialized value\n // this handles objects and arrays, etc.\n const escapedKey = escapeRegExp(key);\n const objectReplacementRegex = new RegExp(`\"\\\\$\\\\{${escapedKey}\\\\}\"`, \"g\");\n stringifiedTemplate = stringifiedTemplate.replace(\n objectReplacementRegex,\n stringifiedValue,\n );\n\n // if the value is just a string or number, we can also replace instances of ${key} within other strings\n if (typeof value === \"string\") {\n const stringReplacementRegex = new RegExp(`\\\\$\\\\{${escapedKey}\\\\}`, \"g\");\n stringifiedTemplate = stringifiedTemplate.replace(\n stringReplacementRegex,\n value,\n );\n }\n\n expandedTemplate = JSON.parse(stringifiedTemplate);\n }\n return expandedTemplate;\n}\n\nexport function expandTemplate({\n templates,\n context,\n}: {\n templates: any[];\n context: any;\n}): any {\n // Step 1: Fill in any templates within the context itself\n const newContext = JSON.parse(JSON.stringify(context));\n if (newContext.fields) {\n newContext.fields = recursivelyFillTemplates({\n obj: newContext.fields,\n templates,\n });\n }\n if (newContext.broadcast) {\n newContext.broadcast = recursivelyFillTemplates({\n obj: newContext.broadcast,\n templates,\n });\n }\n\n // Find the matching template\n const template = templates.find(\n (t: any) => t.templateName === newContext.template,\n );\n if (!template) {\n throw new Error(`Template \"${newContext.template}\" not found`);\n }\n\n let expandedTemplate = JSON.parse(JSON.stringify(template.templateContent));\n\n // Step 3: Apply given fields if any\n if (newContext.fields) {\n expandedTemplate = substituteFields({\n templateContent: expandedTemplate,\n fields: newContext.fields,\n });\n }\n\n // Step 4: Handle broadcast fields if any\n function flattenBroadcast(\n dimensions: Record<string, any[]>,\n ): Record<string, any>[] {\n const dimensionIndices = Object.keys(dimensions);\n const dimensionNumbers = dimensionIndices.map((i) => parseInt(i.slice(1)));\n const lowestDimension = Math.min(...dimensionNumbers);\n\n const currentDimension = dimensions[`d${lowestDimension}`];\n const remainingDimensions = JSON.parse(JSON.stringify(dimensions));\n delete remainingDimensions[`d${lowestDimension}`];\n\n let partialFields: Record<string, any>[] = [{}];\n if (Object.keys(remainingDimensions).length > 0) {\n partialFields = flattenBroadcast(remainingDimensions);\n }\n\n const flatFields: Record<string, any>[] = [];\n for (const [index, entry] of currentDimension.entries()) {\n for (const partialField of partialFields) {\n const newField = { ...entry, ...partialField };\n newField[`d${lowestDimension}`] = `${index}`;\n flatFields.push(newField);\n }\n }\n return flatFields;\n }\n\n if (newContext.broadcast) {\n const broadcastFieldsArray = flattenBroadcast(newContext.broadcast);\n const returnObjects: any[] = [];\n for (const broadcastFields of broadcastFieldsArray) {\n const newObj = substituteFields({\n templateContent: expandedTemplate,\n fields: broadcastFields,\n });\n if (Array.isArray(newObj)) {\n returnObjects.push(...newObj);\n } else if (typeof newObj === \"object\") {\n returnObjects.push(newObj);\n } else {\n throw new Error(\"Unexpected type in broadcast fields\");\n }\n }\n return returnObjects;\n }\n\n return expandedTemplate;\n}\n\nconst MAX_TEMPLATE_DEPTH = 100;\n\nexport function recursivelyFillTemplates({\n obj,\n templates,\n depth = 0,\n templateChain = [],\n}: {\n obj: any;\n templates: any[];\n depth?: number;\n templateChain?: string[];\n}): any {\n if (depth > MAX_TEMPLATE_DEPTH) {\n const chain =\n templateChain.length > 0\n ? ` Template chain: ${templateChain.slice(-10).join(\" → \")}`\n : \"\";\n throw new Error(\n `Maximum template nesting depth (${MAX_TEMPLATE_DEPTH}) exceeded.${chain} Check for circular template references in your treatment file.`,\n );\n }\n let newObj: any;\n try {\n newObj = JSON.parse(JSON.stringify(obj));\n } catch (e) {\n console.log(\"Error parsing\", obj);\n throw e;\n }\n\n if (!Array.isArray(newObj) && typeof newObj === \"object\") {\n if (newObj && newObj.template) {\n const templateName = newObj.template as string;\n const context = templateContextSchema.parse(newObj);\n newObj = expandTemplate({ templates, context });\n newObj = recursivelyFillTemplates({\n obj: newObj,\n templates,\n depth: depth + 1,\n templateChain: [...templateChain, templateName],\n });\n } else {\n for (const key in newObj) {\n if (newObj[key] == null) {\n console.log(`key ${key} is undefined in`, newObj);\n }\n newObj[key] = recursivelyFillTemplates({\n obj: newObj[key],\n templates,\n depth: depth + 1,\n templateChain,\n });\n }\n }\n } else if (Array.isArray(newObj)) {\n for (const [index, item] of newObj.entries()) {\n if (item.template) {\n const context = templateContextSchema.parse(item);\n const expandedItem = expandTemplate({ templates, context });\n if (Array.isArray(expandedItem)) {\n newObj.splice(index, 1, ...expandedItem);\n } else if (typeof expandedItem === \"object\") {\n newObj[index] = expandedItem;\n } else {\n throw new Error(\"Unexpected type in expanded item\");\n }\n } else {\n newObj[index] = recursivelyFillTemplates({\n obj: item,\n templates,\n depth: depth + 1,\n templateChain,\n });\n }\n }\n }\n\n return newObj;\n}\n\n/**\n * Expand all template references and substitute field placeholders.\n *\n * Returns `{ result, unresolvedFields }`:\n * - `result` — the expanded object with all resolvable templates and fields substituted\n * - `unresolvedFields` — names of any `${...}` placeholders that remain after expansion\n *\n * By default, throws if any placeholders remain unresolved. Set `allowUnresolved: true`\n * to get the partially-expanded result instead — useful for two-pass expansion where\n * platform-provided fields are filled in a second call.\n *\n * @example\n * // One-pass: expand everything, throw if anything is missing\n * const { result } = fillTemplates({ obj, templates });\n *\n * @example\n * // Two-pass: expand researcher templates first, fill platform fields second\n * const { result: expanded, unresolvedFields } = fillTemplates({\n * obj: rawTreatmentFile,\n * templates: rawTreatmentFile.templates ?? [],\n * allowUnresolved: true,\n * });\n * // unresolvedFields = [\"clipUrl\", \"clipStartAt\", \"clipStopAt\"]\n *\n * const { result: resolved } = fillTemplates({\n * obj: expanded,\n * templates: [],\n * additionalFields: { clipUrl: \"clip1.mp4\", clipStartAt: 12.5, clipStopAt: 45.0 },\n * });\n */\nexport function fillTemplates({\n obj,\n templates,\n additionalFields,\n allowUnresolved = false,\n}: {\n obj: any;\n templates: any[];\n additionalFields?: Record<string, any>;\n allowUnresolved?: boolean;\n}): { result: any; unresolvedFields: string[] } {\n let newObj = recursivelyFillTemplates({ obj, templates });\n\n // Check that there are no remaining templates\n const templatesRemainingRegex = /\"template\":/g;\n let templatesRemaining = JSON.stringify(newObj).match(\n templatesRemainingRegex,\n );\n while (templatesRemaining) {\n newObj = recursivelyFillTemplates({ obj: newObj, templates });\n templatesRemaining = JSON.stringify(newObj).match(templatesRemainingRegex);\n }\n\n // Apply platform-provided fields after template expansion\n if (additionalFields && Object.keys(additionalFields).length > 0) {\n newObj = substituteFields({\n templateContent: newObj,\n fields: additionalFields,\n });\n }\n\n // Collect any remaining unresolved field names\n const matches = JSON.stringify(newObj).matchAll(\n new RegExp(FIELD_PLACEHOLDER_REGEX.source, \"g\"),\n );\n const unresolvedSet = new Set<string>();\n for (const match of matches) {\n unresolvedSet.add(match[1]);\n }\n const unresolvedFields = [...unresolvedSet];\n\n if (!allowUnresolved && unresolvedFields.length > 0) {\n throw new Error(\n `Missing fields: ${unresolvedFields.map((f) => `\\${${f}}`).join(\", \")}`,\n );\n }\n\n return { result: newObj, unresolvedFields };\n}\n\n/**\n * Expand researcher-defined templates and return the set of placeholder\n * names that remain unresolved. Useful for platforms to discover which\n * additionalFields a treatment file expects.\n *\n * Does NOT throw on unresolved fields — that's the point.\n *\n * @deprecated Use `fillTemplates({ ..., allowUnresolved: true })` instead,\n * which returns both the expanded result and unresolved field names.\n */\nexport function getUnresolvedFields({\n obj,\n templates,\n}: {\n obj: any;\n templates: any[];\n}): string[] {\n const { unresolvedFields } = fillTemplates({\n obj,\n templates,\n allowUnresolved: true,\n });\n return unresolvedFields;\n}\n"],"mappings":"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","names":["z","z"]}
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "stagebook",
3
+ "version": "0.1.0",
4
+ "description": "Schemas, validators, utilities, and components for interactive social science experiments",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "import": {
12
+ "types": "./dist/index.d.ts",
13
+ "default": "./dist/index.js"
14
+ },
15
+ "require": {
16
+ "types": "./dist/index.d.cts",
17
+ "default": "./dist/index.cjs"
18
+ }
19
+ },
20
+ "./styles": "./src/styles.css",
21
+ "./components": {
22
+ "import": {
23
+ "types": "./dist/components/index.d.ts",
24
+ "default": "./dist/components/index.js"
25
+ },
26
+ "require": {
27
+ "types": "./dist/components/index.d.cts",
28
+ "default": "./dist/components/index.cjs"
29
+ }
30
+ }
31
+ },
32
+ "files": [
33
+ "dist",
34
+ "src/styles.css"
35
+ ],
36
+ "scripts": {
37
+ "build": "tsup",
38
+ "build:watch": "tsup --watch",
39
+ "test": "vitest run",
40
+ "test:watch": "vitest",
41
+ "test:ct": "playwright test --config playwright-ct.config.ts",
42
+ "lint": "eslint src/",
43
+ "format": "prettier --write \"src/**/*.{ts,tsx}\"",
44
+ "format:check": "prettier --check \"src/**/*.{ts,tsx}\"",
45
+ "prepublishOnly": "npm run lint && npm run test && npm run build"
46
+ },
47
+ "dependencies": {
48
+ "@hello-pangea/dnd": "^18.0.1",
49
+ "react-markdown": "^10.1.0",
50
+ "remark-gfm": "^4.0.1"
51
+ },
52
+ "peerDependencies": {
53
+ "js-yaml": ">=4",
54
+ "react": ">=18",
55
+ "react-dom": ">=18",
56
+ "zod": ">=3.23"
57
+ },
58
+ "peerDependenciesMeta": {
59
+ "react": {
60
+ "optional": true
61
+ },
62
+ "react-dom": {
63
+ "optional": true
64
+ }
65
+ },
66
+ "devDependencies": {
67
+ "@hello-pangea/dnd": "^18.0.1",
68
+ "@playwright/experimental-ct-react": "^1.58.2",
69
+ "@tailwindcss/vite": "^4.2.2",
70
+ "@types/js-yaml": "^4.0.9",
71
+ "@types/react": "^19.2.14",
72
+ "@types/react-dom": "^19.2.3",
73
+ "eslint": "^9.0.0",
74
+ "js-yaml": "^4.1.0",
75
+ "jsdom": "^29.0.1",
76
+ "playwright": "^1.58.2",
77
+ "prettier": "^3.0.0",
78
+ "react": "^19.2.4",
79
+ "react-dom": "^19.2.4",
80
+ "react-markdown": "^10.1.0",
81
+ "remark-gfm": "^4.0.1",
82
+ "tailwindcss": "^4.2.2",
83
+ "tsup": "^8.0.0",
84
+ "typescript": "^5.5.0",
85
+ "typescript-eslint": "^8.0.0",
86
+ "vitest": "^2.0.0",
87
+ "zod": "^3.23.0"
88
+ },
89
+ "repository": {
90
+ "type": "git",
91
+ "url": "https://github.com/deliberation-lab/stagebook.git"
92
+ },
93
+ "license": "MIT"
94
+ }
package/src/styles.css ADDED
@@ -0,0 +1,275 @@
1
+ /*
2
+ * stagebook default styles
3
+ *
4
+ * Import this in your app entry point if you want Stagebook's CSS-variable
5
+ * defaults and the Inter font to be available globally:
6
+ * import "stagebook/styles";
7
+ *
8
+ * This file is OPTIONAL. Stagebook components ship visual styling as inline
9
+ * styles backed by CSS custom properties with sensible fallbacks, so the
10
+ * components render correctly on hosts that never import this stylesheet.
11
+ * The purpose of importing this file is convenience: the variable defaults
12
+ * become available at :root for the host to override in one place, and
13
+ * the Inter webfont is registered.
14
+ *
15
+ * Provides:
16
+ * - Tailwind CSS utilities
17
+ * - Inter font
18
+ * - Stagebook CSS custom properties at :root (default values)
19
+ * - Form input resets
20
+ * - GFM table styles (out of scope for inline styling — see issue #33)
21
+ *
22
+ * Customizing typography / colors: override the --stagebook-* variables on
23
+ * any parent element (or :root). For example, to scale headings down on
24
+ * a particular platform:
25
+ *
26
+ * :root {
27
+ * --stagebook-prompt-h1-size: 1.5rem;
28
+ * --stagebook-prompt-h2-size: 1.25rem;
29
+ * --stagebook-prompt-line-height: 1.6;
30
+ * --stagebook-link: #1e40af;
31
+ * }
32
+ *
33
+ * No selector-based CSS, no specificity battles.
34
+ */
35
+
36
+ @import "tailwindcss";
37
+
38
+ /* ------------------------------------------------------------------ */
39
+ /* Font */
40
+ /* ------------------------------------------------------------------ */
41
+
42
+ @font-face {
43
+ font-family: "Inter";
44
+ font-style: normal;
45
+ font-weight: 100 900;
46
+ font-display: swap;
47
+ src: url("https://rsms.me/inter/font-files/InterVariable.woff2")
48
+ format("woff2");
49
+ }
50
+
51
+ @theme {
52
+ --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif;
53
+
54
+ /* Stagebook color palette — replaces Empirica's brand colors */
55
+ --color-stagebook-50: #eff6ff;
56
+ --color-stagebook-100: #dbeafe;
57
+ --color-stagebook-200: #bfdbfe;
58
+ --color-stagebook-300: #93c5fd;
59
+ --color-stagebook-400: #60a5fa;
60
+ --color-stagebook-500: #3b82f6;
61
+ --color-stagebook-600: #2563eb;
62
+ --color-stagebook-700: #1d4ed8;
63
+ --color-stagebook-800: #1e40af;
64
+ --color-stagebook-900: #1e3a8a;
65
+ }
66
+
67
+ /* ------------------------------------------------------------------ */
68
+ /* Component theme — CSS custom properties for themeable values */
69
+ /* Override these on a parent element to customize Stagebook's appearance. */
70
+ /* Layout (padding, flex, positioning) is inline and not overridable. */
71
+ /* ------------------------------------------------------------------ */
72
+
73
+ :root {
74
+ /* Primary action color (buttons, slider thumb, focus rings) */
75
+ --stagebook-primary: #3b82f6;
76
+ --stagebook-primary-hover: #2563eb;
77
+
78
+ /* Status colors */
79
+ --stagebook-success: #16a34a;
80
+ --stagebook-danger: #ef4444;
81
+ --stagebook-warning: #dc2626;
82
+
83
+ /* Timer */
84
+ --stagebook-timer-fill: #60a5fa;
85
+ --stagebook-timer-warn: #ef4444;
86
+ --stagebook-timer-track: #e5e7eb;
87
+
88
+ /* Text */
89
+ --stagebook-text: #1f2937;
90
+ --stagebook-text-secondary: #374151;
91
+ --stagebook-text-muted: #6b7280;
92
+ --stagebook-text-faint: #9ca3af;
93
+
94
+ /* Borders and backgrounds */
95
+ --stagebook-border: #d1d5db;
96
+ --stagebook-bg-muted: #f9fafb;
97
+ --stagebook-bg-track: #e5e7eb;
98
+
99
+ /* Loading spinner */
100
+ --stagebook-spinner-track: #e5e7eb;
101
+ --stagebook-spinner-arc: #9ca3af;
102
+
103
+ /* Markdown / prompt typography (used by the Markdown component) */
104
+ --stagebook-prompt-max-width: 36rem;
105
+ --stagebook-prompt-text-size: 1rem;
106
+ --stagebook-prompt-line-height: 1.5;
107
+ --stagebook-prompt-h1-size: 1.875rem;
108
+ --stagebook-prompt-h2-size: 1.5rem;
109
+ --stagebook-prompt-h3-size: 1.25rem;
110
+ --stagebook-prompt-h4-size: 1.125rem;
111
+ --stagebook-prompt-h1-weight: 700;
112
+ --stagebook-prompt-h2-weight: 600;
113
+ --stagebook-prompt-h3-weight: 600;
114
+ --stagebook-prompt-h4-weight: 600;
115
+ --stagebook-link: #2563eb;
116
+ --stagebook-code-bg: rgba(0, 0, 0, 0.06);
117
+ --stagebook-code-font: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
118
+ monospace;
119
+
120
+ /* Blockquote (used by Display element and markdown blockquotes) */
121
+ --stagebook-blockquote-border: #d1d5db;
122
+ --stagebook-blockquote-bg: #f9fafb;
123
+ }
124
+
125
+ /* ------------------------------------------------------------------ */
126
+ /* Base layer */
127
+ /* */
128
+ /* NOTE: heading / list / blockquote / link styling for Markdown- */
129
+ /* rendered prompt content does NOT live here. It lives as inline */
130
+ /* styles in src/components/form/Markdown.tsx (and Display.tsx for */
131
+ /* blockquotes), backed by the CSS custom properties declared in */
132
+ /* :root above. */
133
+ /* */
134
+ /* Why inline styles instead of @layer base rules: */
135
+ /* */
136
+ /* Stagebook is consumed as a library from node_modules. Author CSS shipped */
137
+ /* from a dependency loses specificity battles against host CSS resets */
138
+ /* (Tailwind preflight, normalize.css, Bootstrap reboot, etc.) — those */
139
+ /* resets often collapse all heading levels to body text size, which */
140
+ /* destroys the visual hierarchy of researcher-authored markdown. The */
141
+ /* same study would render differently on every host. Inline styles */
142
+ /* win against everything except !important, so prompt content renders */
143
+ /* with the intended hierarchy regardless of what the host ships. */
144
+ /* */
145
+ /* The styles remain customizable: hosts override the --stagebook-prompt-* */
146
+ /* variables on a parent element (or :root) to retune the type scale */
147
+ /* without writing any selector-based CSS. See issue #33. */
148
+ /* ------------------------------------------------------------------ */
149
+
150
+ @layer base {
151
+ body {
152
+ font-family: "Inter", ui-sans-serif, system-ui, sans-serif;
153
+ -webkit-font-smoothing: antialiased;
154
+ -moz-osx-font-smoothing: grayscale;
155
+ }
156
+
157
+ /* ---------------------------------------------------------------- */
158
+ /* Form resets */
159
+ /* ---------------------------------------------------------------- */
160
+
161
+ input[type="text"],
162
+ input[type="email"],
163
+ input[type="url"],
164
+ input[type="password"],
165
+ input[type="number"],
166
+ input[type="search"],
167
+ input[type="tel"],
168
+ textarea,
169
+ select {
170
+ appearance: none;
171
+ border: 1px solid #d1d5db;
172
+ border-radius: 0.375rem;
173
+ padding: 0.5rem 0.75rem;
174
+ font-size: 0.875rem;
175
+ line-height: 1.25rem;
176
+ color: #1f2937;
177
+ background-color: #fff;
178
+ }
179
+
180
+ input[type="text"]:focus,
181
+ input[type="email"]:focus,
182
+ input[type="url"]:focus,
183
+ input[type="password"]:focus,
184
+ input[type="number"]:focus,
185
+ input[type="search"]:focus,
186
+ input[type="tel"]:focus,
187
+ textarea:focus,
188
+ select:focus {
189
+ outline: none;
190
+ border-color: #3b82f6;
191
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.25);
192
+ }
193
+
194
+ input[type="checkbox"],
195
+ input[type="radio"] {
196
+ appearance: none;
197
+ width: 1rem;
198
+ height: 1rem;
199
+ border: 1px solid #d1d5db;
200
+ border-radius: 0.125rem;
201
+ background-color: #fff;
202
+ vertical-align: middle;
203
+ cursor: pointer;
204
+ }
205
+
206
+ input[type="radio"] {
207
+ border-radius: 9999px;
208
+ }
209
+
210
+ input[type="checkbox"]:checked,
211
+ input[type="radio"]:checked {
212
+ background-color: #3b82f6;
213
+ border-color: #3b82f6;
214
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3cpath d='M12.207 4.793a1 1 0 010 1.414l-5 5a1 1 0 01-1.414 0l-2-2a1 1 0 011.414-1.414L6.5 9.086l4.293-4.293a1 1 0 011.414 0z'/%3e%3c/svg%3e");
215
+ background-size: 100% 100%;
216
+ background-position: center;
217
+ background-repeat: no-repeat;
218
+ }
219
+
220
+ input[type="radio"]:checked {
221
+ background-image: url("data:image/svg+xml,%3csvg viewBox='0 0 16 16' fill='white' xmlns='http://www.w3.org/2000/svg'%3e%3ccircle cx='8' cy='8' r='3'/%3e%3c/svg%3e");
222
+ }
223
+
224
+ input[type="checkbox"]:focus,
225
+ input[type="radio"]:focus {
226
+ outline: none;
227
+ box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.25);
228
+ }
229
+
230
+ /* Remove number input spinners */
231
+ input[type="number"]::-webkit-outer-spin-button,
232
+ input[type="number"]::-webkit-inner-spin-button {
233
+ -webkit-appearance: none;
234
+ margin: 0;
235
+ }
236
+
237
+ input[type="number"] {
238
+ -moz-appearance: textfield;
239
+ }
240
+
241
+ /*
242
+ * GFM tables (rendered by react-markdown).
243
+ *
244
+ * Intentionally NOT inlined into Markdown.tsx like headings/lists/etc.
245
+ * The table style surface is large (table + th + td + collapse behavior
246
+ * + cell borders) and inlining would roughly double Markdown.tsx. As a
247
+ * result: hosts that import this stylesheet get nice tables; hosts that
248
+ * don't get browser-default unstyled tables (functional but ugly).
249
+ *
250
+ * If a researcher needs portable table styling on a non-stylesheet host,
251
+ * follow the pattern in Markdown.tsx and add table/thead/tbody/tr/th/td
252
+ * entries to the components map. See issue #33.
253
+ */
254
+ table {
255
+ border-collapse: collapse;
256
+ margin: 1rem 0;
257
+ width: 100%;
258
+ max-width: 36rem;
259
+ }
260
+
261
+ th,
262
+ td {
263
+ border: 1px solid #d1d5db;
264
+ padding: 0.5rem 0.75rem;
265
+ text-align: left;
266
+ font-size: 0.875rem;
267
+ color: #4a5568;
268
+ }
269
+
270
+ th {
271
+ background-color: #f9fafb;
272
+ font-weight: 500;
273
+ color: #1a202c;
274
+ }
275
+ }