@growth-labs/cms 0.5.5 → 0.5.6

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.
Files changed (113) hide show
  1. package/README.md +36 -0
  2. package/dist/index.d.ts +2 -0
  3. package/dist/index.d.ts.map +1 -1
  4. package/dist/index.js +2 -0
  5. package/dist/index.js.map +1 -1
  6. package/dist/integration/index.d.ts.map +1 -1
  7. package/dist/integration/index.js +9 -0
  8. package/dist/integration/index.js.map +1 -1
  9. package/dist/integration/options.d.ts +19 -0
  10. package/dist/integration/options.d.ts.map +1 -1
  11. package/dist/integration/options.js +7 -0
  12. package/dist/integration/options.js.map +1 -1
  13. package/dist/providers/null.d.ts +2 -1
  14. package/dist/providers/null.d.ts.map +1 -1
  15. package/dist/providers/null.js +9 -0
  16. package/dist/providers/null.js.map +1 -1
  17. package/dist/providers/types.d.ts +10 -0
  18. package/dist/providers/types.d.ts.map +1 -1
  19. package/dist/providers/types.js.map +1 -1
  20. package/dist/routes/authz-matrix.d.ts.map +1 -1
  21. package/dist/routes/authz-matrix.js +2 -0
  22. package/dist/routes/authz-matrix.js.map +1 -1
  23. package/dist/routes/context.d.ts +1 -1
  24. package/dist/routes/context.d.ts.map +1 -1
  25. package/dist/routes/context.js.map +1 -1
  26. package/dist/routes/index.d.ts +1 -0
  27. package/dist/routes/index.d.ts.map +1 -1
  28. package/dist/routes/index.js +2 -0
  29. package/dist/routes/index.js.map +1 -1
  30. package/dist/routes/surveys.d.ts +12 -0
  31. package/dist/routes/surveys.d.ts.map +1 -0
  32. package/dist/routes/surveys.js +109 -0
  33. package/dist/routes/surveys.js.map +1 -0
  34. package/dist/schema/insights-ingest.d.ts +46 -46
  35. package/dist/surveys/access.d.ts +4 -0
  36. package/dist/surveys/access.d.ts.map +1 -0
  37. package/dist/surveys/access.js +9 -0
  38. package/dist/surveys/access.js.map +1 -0
  39. package/dist/surveys/errors.d.ts +43 -0
  40. package/dist/surveys/errors.d.ts.map +1 -0
  41. package/dist/surveys/errors.js +42 -0
  42. package/dist/surveys/errors.js.map +1 -0
  43. package/dist/surveys/schema.d.ts +939 -0
  44. package/dist/surveys/schema.d.ts.map +1 -0
  45. package/dist/surveys/schema.js +385 -0
  46. package/dist/surveys/schema.js.map +1 -0
  47. package/dist/ui/api/surveys/[surveyId]/responses.csv.d.ts +3 -0
  48. package/dist/ui/api/surveys/[surveyId]/responses.csv.d.ts.map +1 -0
  49. package/dist/ui/api/surveys/[surveyId]/responses.csv.js +17 -0
  50. package/dist/ui/api/surveys/[surveyId]/responses.csv.js.map +1 -0
  51. package/dist/ui/api/surveys/[surveyId].d.ts +3 -0
  52. package/dist/ui/api/surveys/[surveyId].d.ts.map +1 -0
  53. package/dist/ui/api/surveys/[surveyId].js +17 -0
  54. package/dist/ui/api/surveys/[surveyId].js.map +1 -0
  55. package/dist/ui/client/mount.d.ts.map +1 -1
  56. package/dist/ui/client/mount.js +1 -0
  57. package/dist/ui/client/mount.js.map +1 -1
  58. package/dist/ui/commands.d.ts +5 -1
  59. package/dist/ui/commands.d.ts.map +1 -1
  60. package/dist/ui/commands.js +7 -0
  61. package/dist/ui/commands.js.map +1 -1
  62. package/dist/ui/components/CmsApp.d.ts +2 -0
  63. package/dist/ui/components/CmsApp.d.ts.map +1 -1
  64. package/dist/ui/components/CmsApp.js +14 -3
  65. package/dist/ui/components/CmsApp.js.map +1 -1
  66. package/dist/ui/components/CommandPalette.d.ts +2 -0
  67. package/dist/ui/components/CommandPalette.d.ts.map +1 -1
  68. package/dist/ui/components/CommandPalette.js +1 -1
  69. package/dist/ui/components/CommandPalette.js.map +1 -1
  70. package/dist/ui/components/Sidebar.d.ts +1 -0
  71. package/dist/ui/components/Sidebar.d.ts.map +1 -1
  72. package/dist/ui/components/Sidebar.js +1 -1
  73. package/dist/ui/components/Sidebar.js.map +1 -1
  74. package/dist/ui/hash-router.d.ts +1 -1
  75. package/dist/ui/hash-router.d.ts.map +1 -1
  76. package/dist/ui/hash-router.js +1 -0
  77. package/dist/ui/hash-router.js.map +1 -1
  78. package/dist/ui/nav.d.ts +5 -1
  79. package/dist/ui/nav.d.ts.map +1 -1
  80. package/dist/ui/nav.js +10 -2
  81. package/dist/ui/nav.js.map +1 -1
  82. package/dist/ui/screens/SurveyResponsesScreen.d.ts +28 -0
  83. package/dist/ui/screens/SurveyResponsesScreen.d.ts.map +1 -0
  84. package/dist/ui/screens/SurveyResponsesScreen.js +110 -0
  85. package/dist/ui/screens/SurveyResponsesScreen.js.map +1 -0
  86. package/dist/ui/screens/registry.d.ts +2 -1
  87. package/dist/ui/screens/registry.d.ts.map +1 -1
  88. package/dist/ui/screens/registry.js +5 -1
  89. package/dist/ui/screens/registry.js.map +1 -1
  90. package/package.json +1 -1
  91. package/src/index.ts +2 -2
  92. package/src/integration/index.ts +9 -0
  93. package/src/integration/options.ts +8 -0
  94. package/src/providers/null.ts +19 -0
  95. package/src/providers/types.ts +7 -0
  96. package/src/routes/authz-matrix.ts +2 -0
  97. package/src/routes/context.ts +2 -0
  98. package/src/routes/index.ts +6 -0
  99. package/src/routes/surveys.ts +130 -0
  100. package/src/surveys/access.ts +11 -0
  101. package/src/surveys/errors.ts +51 -0
  102. package/src/surveys/schema.ts +435 -0
  103. package/src/ui/api/surveys/[surveyId]/responses.csv.ts +23 -0
  104. package/src/ui/api/surveys/[surveyId].ts +23 -0
  105. package/src/ui/client/mount.tsx +1 -0
  106. package/src/ui/commands.ts +14 -1
  107. package/src/ui/components/CmsApp.tsx +25 -3
  108. package/src/ui/components/CommandPalette.tsx +2 -1
  109. package/src/ui/components/Sidebar.tsx +10 -2
  110. package/src/ui/hash-router.ts +1 -0
  111. package/src/ui/nav.ts +15 -2
  112. package/src/ui/screens/SurveyResponsesScreen.tsx +271 -0
  113. package/src/ui/screens/registry.tsx +6 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/surveys/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,eAAO,MAAM,oBAAoB,MAAM,CAAA;AAgBvC,eAAO,MAAM,cAAc,aAIA,CAAA;AAC3B,eAAO,MAAM,sBAAsB,aAAiB,CAAA;AAcpD,eAAO,MAAM,oBAAoB,4CAA0C,CAAA;AAC3E,eAAO,MAAM,6BAA6B,gDAA8C,CAAA;AAwFxF,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0D9B,CAAA;AAEH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAqH7B,CAAA;AAEH,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;EAuC/B,CAAA;AAwFH,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,oBAAoB,CAAC,CAAA;AACjE,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAA;AAC/D,MAAM,MAAM,eAAe,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAA"}
@@ -0,0 +1,385 @@
1
+ import { z } from 'zod';
2
+ export const SURVEY_ID_MAX_LENGTH = 200;
3
+ const MAX_TITLE_LENGTH = 300;
4
+ const MAX_PROMPT_LENGTH = 1_000;
5
+ const MAX_QUESTIONS = 100;
6
+ const MAX_RESPONSES = 500;
7
+ const MAX_FREE_TEXT_ENTRIES = 500;
8
+ const MAX_FREE_TEXT_LENGTH = 20_000;
9
+ const MAX_CHOICE_OPTIONS = 100;
10
+ const MAX_OPTION_LENGTH = 256;
11
+ const MAX_SCALE_POINTS = 100;
12
+ const MAX_COUNT = 1_000_000_000;
13
+ const MAX_CSV_FILENAME_LENGTH = 200;
14
+ const MAX_CSV_CONTENT_LENGTH = 10_000_000;
15
+ const MAX_CSV_COLUMNS = 256;
16
+ const MAX_CSV_HEADER_LENGTH = 256;
17
+ export const SurveyIdSchema = z
18
+ .string()
19
+ .min(1)
20
+ .max(SURVEY_ID_MAX_LENGTH)
21
+ .regex(/^[A-Za-z0-9_-]+$/);
22
+ export const SurveyQuestionIdSchema = SurveyIdSchema;
23
+ const BoundedRecordIdSchema = z
24
+ .string()
25
+ .min(1)
26
+ .max(SURVEY_ID_MAX_LENGTH)
27
+ .regex(/^[A-Za-z0-9][A-Za-z0-9._:-]*$/);
28
+ const IsoTimestampSchema = z.string().datetime({ offset: true });
29
+ const CountSchema = z.number().int().nonnegative().max(MAX_COUNT);
30
+ const NonemptyBoundedStringSchema = z
31
+ .string()
32
+ .min(1)
33
+ .max(MAX_OPTION_LENGTH)
34
+ .refine((value) => value.trim().length > 0);
35
+ export const SurveyAudienceSchema = z.enum(['all', 'member', 'non_member']);
36
+ export const SurveyRespondentSegmentSchema = z.enum(['member', 'non_member', 'unknown']);
37
+ const ChoiceOptionsSchema = z
38
+ .array(NonemptyBoundedStringSchema)
39
+ .min(1)
40
+ .max(MAX_CHOICE_OPTIONS)
41
+ .refine((options) => new Set(options).size === options.length);
42
+ const CountsSchema = z
43
+ .record(CountSchema)
44
+ .refine((counts) => Object.keys(counts).length <= MAX_CHOICE_OPTIONS);
45
+ const QuestionBase = {
46
+ id: SurveyQuestionIdSchema,
47
+ position: z
48
+ .number()
49
+ .int()
50
+ .nonnegative()
51
+ .max(MAX_QUESTIONS - 1),
52
+ prompt: z
53
+ .string()
54
+ .min(1)
55
+ .max(MAX_PROMPT_LENGTH)
56
+ .refine((value) => value.trim().length > 0),
57
+ audience: SurveyAudienceSchema,
58
+ answerCount: CountSchema,
59
+ };
60
+ const SingleChoiceQuestionSchema = z
61
+ .object({
62
+ ...QuestionBase,
63
+ kind: z.literal('single_choice'),
64
+ options: ChoiceOptionsSchema,
65
+ counts: CountsSchema,
66
+ average: z.null(),
67
+ distribution: z.null(),
68
+ responseCount: z.null(),
69
+ })
70
+ .strict();
71
+ const MultiChoiceQuestionSchema = z
72
+ .object({
73
+ ...QuestionBase,
74
+ kind: z.literal('multi_choice'),
75
+ options: ChoiceOptionsSchema,
76
+ counts: CountsSchema,
77
+ average: z.null(),
78
+ distribution: z.null(),
79
+ responseCount: z.null(),
80
+ })
81
+ .strict();
82
+ const ScaleOptionsSchema = z
83
+ .object({
84
+ min: z.number().int(),
85
+ max: z.number().int(),
86
+ })
87
+ .strict()
88
+ .refine((options) => options.max >= options.min && options.max - options.min + 1 <= MAX_SCALE_POINTS);
89
+ const ScaleQuestionSchema = z
90
+ .object({
91
+ ...QuestionBase,
92
+ kind: z.literal('scale'),
93
+ options: ScaleOptionsSchema,
94
+ counts: z.null(),
95
+ average: z.number().finite().nullable(),
96
+ distribution: z.record(CountSchema),
97
+ responseCount: z.null(),
98
+ })
99
+ .strict();
100
+ const TextQuestionSchema = z
101
+ .object({
102
+ ...QuestionBase,
103
+ kind: z.literal('text'),
104
+ options: z
105
+ .object({ max_length: z.number().int().positive().max(MAX_FREE_TEXT_LENGTH) })
106
+ .strict(),
107
+ counts: z.null(),
108
+ average: z.null(),
109
+ distribution: z.null(),
110
+ responseCount: CountSchema,
111
+ })
112
+ .strict();
113
+ export const SurveyQuestionSchema = z
114
+ .discriminatedUnion('kind', [
115
+ SingleChoiceQuestionSchema,
116
+ MultiChoiceQuestionSchema,
117
+ ScaleQuestionSchema,
118
+ TextQuestionSchema,
119
+ ])
120
+ .superRefine((question, ctx) => {
121
+ if (question.kind === 'single_choice' || question.kind === 'multi_choice') {
122
+ if (!hasExactKeys(question.counts, question.options)) {
123
+ ctx.addIssue({
124
+ code: z.ZodIssueCode.custom,
125
+ message: 'Counts must match configured options',
126
+ });
127
+ }
128
+ const total = Object.values(question.counts).reduce((sum, count) => sum + count, 0);
129
+ if (question.kind === 'single_choice' && total !== question.answerCount) {
130
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Choice total is incoherent' });
131
+ }
132
+ if (question.kind === 'multi_choice' &&
133
+ Object.values(question.counts).some((count) => count > question.answerCount)) {
134
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Multi-choice total is incoherent' });
135
+ }
136
+ return;
137
+ }
138
+ if (question.kind === 'scale') {
139
+ const keys = Array.from({ length: question.options.max - question.options.min + 1 }, (_, index) => String(question.options.min + index));
140
+ if (!hasExactKeys(question.distribution, keys)) {
141
+ ctx.addIssue({
142
+ code: z.ZodIssueCode.custom,
143
+ message: 'Scale distribution must include every configured value',
144
+ });
145
+ }
146
+ const total = Object.values(question.distribution).reduce((sum, count) => sum + count, 0);
147
+ if (total !== question.answerCount) {
148
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Scale total is incoherent' });
149
+ }
150
+ if ((question.answerCount === 0 && question.average !== null) ||
151
+ (question.answerCount > 0 &&
152
+ (question.average === null ||
153
+ question.average < question.options.min ||
154
+ question.average > question.options.max))) {
155
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Scale average is incoherent' });
156
+ }
157
+ return;
158
+ }
159
+ if (question.responseCount !== question.answerCount) {
160
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Text response total is incoherent' });
161
+ }
162
+ });
163
+ export const SurveyResultsSchema = z
164
+ .object({
165
+ survey: z
166
+ .object({
167
+ id: SurveyIdSchema,
168
+ title: z
169
+ .string()
170
+ .min(1)
171
+ .max(MAX_TITLE_LENGTH)
172
+ .refine((value) => value.trim().length > 0),
173
+ status: z.enum(['draft', 'active', 'closed']),
174
+ responseCount: CountSchema,
175
+ })
176
+ .strict(),
177
+ questions: z.array(SurveyQuestionSchema).max(MAX_QUESTIONS),
178
+ responses: z
179
+ .array(z
180
+ .object({
181
+ id: BoundedRecordIdSchema,
182
+ channel: z.enum(['email', 'site', 'direct']),
183
+ submittedAt: IsoTimestampSchema,
184
+ respondentSegment: SurveyRespondentSegmentSchema,
185
+ anonymous: z.boolean(),
186
+ })
187
+ .strict())
188
+ .max(MAX_RESPONSES),
189
+ freeText: z
190
+ .array(z
191
+ .object({
192
+ questionId: SurveyQuestionIdSchema,
193
+ responseId: BoundedRecordIdSchema,
194
+ submittedAt: IsoTimestampSchema,
195
+ value: z.string().min(1).max(MAX_FREE_TEXT_LENGTH),
196
+ })
197
+ .strict())
198
+ .max(MAX_FREE_TEXT_ENTRIES),
199
+ })
200
+ .strict()
201
+ .superRefine((results, ctx) => {
202
+ const questionIds = new Set();
203
+ for (const [index, question] of results.questions.entries()) {
204
+ if (question.position !== index) {
205
+ ctx.addIssue({
206
+ code: z.ZodIssueCode.custom,
207
+ path: ['questions', index, 'position'],
208
+ message: 'Question positions must be ordered',
209
+ });
210
+ }
211
+ if (questionIds.has(question.id)) {
212
+ ctx.addIssue({
213
+ code: z.ZodIssueCode.custom,
214
+ path: ['questions', index, 'id'],
215
+ message: 'Question IDs must be unique',
216
+ });
217
+ }
218
+ questionIds.add(question.id);
219
+ if (question.answerCount > results.survey.responseCount) {
220
+ ctx.addIssue({
221
+ code: z.ZodIssueCode.custom,
222
+ path: ['questions', index, 'answerCount'],
223
+ message: 'Question total exceeds survey total',
224
+ });
225
+ }
226
+ }
227
+ if (results.responses.length > results.survey.responseCount) {
228
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Response rows exceed survey total' });
229
+ }
230
+ const responses = new Map();
231
+ for (const [index, response] of results.responses.entries()) {
232
+ if (responses.has(response.id)) {
233
+ ctx.addIssue({
234
+ code: z.ZodIssueCode.custom,
235
+ path: ['responses', index, 'id'],
236
+ message: 'Response IDs must be unique',
237
+ });
238
+ }
239
+ responses.set(response.id, response);
240
+ }
241
+ const textQuestions = new Map(results.questions
242
+ .filter((question) => question.kind === 'text')
243
+ .map((question) => [question.id, question]));
244
+ const freeTextCounts = new Map();
245
+ for (const [index, entry] of results.freeText.entries()) {
246
+ const question = textQuestions.get(entry.questionId);
247
+ const response = responses.get(entry.responseId);
248
+ if (!question || (response && response.submittedAt !== entry.submittedAt)) {
249
+ ctx.addIssue({
250
+ code: z.ZodIssueCode.custom,
251
+ path: ['freeText', index],
252
+ message: 'Free-text references must be coherent',
253
+ });
254
+ continue;
255
+ }
256
+ if (entry.value.length > question.options.max_length) {
257
+ ctx.addIssue({
258
+ code: z.ZodIssueCode.custom,
259
+ path: ['freeText', index, 'value'],
260
+ message: 'Free-text value exceeds its question limit',
261
+ });
262
+ }
263
+ freeTextCounts.set(entry.questionId, (freeTextCounts.get(entry.questionId) ?? 0) + 1);
264
+ }
265
+ for (const question of textQuestions.values()) {
266
+ if ((freeTextCounts.get(question.id) ?? 0) > question.responseCount) {
267
+ ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Free-text entries exceed total' });
268
+ }
269
+ }
270
+ });
271
+ export const SurveyCsvResultSchema = z
272
+ .object({
273
+ filename: z.string().min(1).max(MAX_CSV_FILENAME_LENGTH),
274
+ content: z.string().min(1).max(MAX_CSV_CONTENT_LENGTH),
275
+ })
276
+ .strict()
277
+ .superRefine((result, ctx) => {
278
+ const header = parseCsvHeader(result.content);
279
+ if (!header) {
280
+ ctx.addIssue({
281
+ code: z.ZodIssueCode.custom,
282
+ path: ['content'],
283
+ message: 'Invalid CSV header',
284
+ });
285
+ return;
286
+ }
287
+ if (header.length > MAX_CSV_COLUMNS ||
288
+ header.some((column) => column.length === 0 ||
289
+ column.length > MAX_CSV_HEADER_LENGTH ||
290
+ column.trim().length === 0)) {
291
+ ctx.addIssue({
292
+ code: z.ZodIssueCode.custom,
293
+ path: ['content'],
294
+ message: 'CSV header is too large',
295
+ });
296
+ return;
297
+ }
298
+ if (header.some((column) => !isSafeCsvColumn(column))) {
299
+ ctx.addIssue({
300
+ code: z.ZodIssueCode.custom,
301
+ path: ['content'],
302
+ message: 'CSV header contains a non-allowlisted column',
303
+ });
304
+ }
305
+ });
306
+ const SafeCsvMetadataColumns = new Set([
307
+ 'response_id',
308
+ 'submitted_at',
309
+ 'channel',
310
+ 'respondent_segment',
311
+ 'anonymous',
312
+ ]);
313
+ function isSafeCsvColumn(value) {
314
+ if (SafeCsvMetadataColumns.has(value))
315
+ return true;
316
+ const prefix = 'answer:';
317
+ return (value.startsWith(prefix) && SurveyQuestionIdSchema.safeParse(value.slice(prefix.length)).success);
318
+ }
319
+ function parseCsvHeader(content) {
320
+ const fields = [];
321
+ let field = '';
322
+ let inQuotes = false;
323
+ let closedQuote = false;
324
+ let atFieldStart = true;
325
+ const source = content.startsWith('\uFEFF') ? content.slice(1) : content;
326
+ for (let index = 0; index < source.length; index += 1) {
327
+ const char = source[index];
328
+ if (inQuotes) {
329
+ if (char !== '"') {
330
+ field += char;
331
+ continue;
332
+ }
333
+ if (source[index + 1] === '"') {
334
+ field += '"';
335
+ index += 1;
336
+ continue;
337
+ }
338
+ inQuotes = false;
339
+ closedQuote = true;
340
+ continue;
341
+ }
342
+ if (closedQuote) {
343
+ if (char === ',') {
344
+ fields.push(field);
345
+ field = '';
346
+ closedQuote = false;
347
+ atFieldStart = true;
348
+ continue;
349
+ }
350
+ if (char === '\r' || char === '\n') {
351
+ fields.push(field);
352
+ return fields;
353
+ }
354
+ return null;
355
+ }
356
+ if (atFieldStart && char === '"') {
357
+ inQuotes = true;
358
+ atFieldStart = false;
359
+ continue;
360
+ }
361
+ if (char === '"')
362
+ return null;
363
+ if (char === ',') {
364
+ fields.push(field);
365
+ field = '';
366
+ atFieldStart = true;
367
+ continue;
368
+ }
369
+ if (char === '\r' || char === '\n') {
370
+ fields.push(field);
371
+ return fields;
372
+ }
373
+ field += char;
374
+ atFieldStart = false;
375
+ }
376
+ if (inQuotes)
377
+ return null;
378
+ fields.push(field);
379
+ return fields;
380
+ }
381
+ function hasExactKeys(record, expected) {
382
+ const actual = Object.keys(record);
383
+ return actual.length === expected.length && expected.every((key) => Object.hasOwn(record, key));
384
+ }
385
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/surveys/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { APIContext } from 'astro';
2
+ export declare const GET: (context: APIContext) => Promise<Response>;
3
+ //# sourceMappingURL=responses.csv.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.csv.d.ts","sourceRoot":"","sources":["../../../../../src/ui/api/surveys/[surveyId]/responses.csv.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAqBvC,eAAO,MAAM,GAAG,GAAI,SAAS,UAAU,sBACsB,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { createSurveyRoutes } from '../../../../routes/surveys.js';
2
+ import { buildSiteAuthz } from '../../_authz.js';
3
+ function toCtx(context) {
4
+ const env = context.locals.cmsEnv ?? {};
5
+ return {
6
+ request: context.request,
7
+ params: { surveyId: context.params.surveyId },
8
+ db: env.SITE_DB,
9
+ env,
10
+ };
11
+ }
12
+ function routeConfig(context) {
13
+ const locals = context.locals;
14
+ return { authz: buildSiteAuthz(context), providers: locals.cmsProviders };
15
+ }
16
+ export const GET = (context) => createSurveyRoutes(routeConfig(context)).csv(toCtx(context));
17
+ //# sourceMappingURL=responses.csv.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"responses.csv.js","sourceRoot":"","sources":["../../../../../src/ui/api/surveys/[surveyId]/responses.csv.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,+BAA+B,CAAA;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAA;AAEhD,SAAS,KAAK,CAAC,OAAmB;IACjC,MAAM,GAAG,GAAI,OAAO,CAAC,MAA+C,CAAC,MAAM,IAAI,EAAE,CAAA;IACjF,OAAO;QACN,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE;QAC7C,EAAE,EAAE,GAAG,CAAC,OAA6B;QACrC,GAAG;KACH,CAAA;AACF,CAAC;AAED,SAAS,WAAW,CAAC,OAAmB;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAkD,CAAA;IACzE,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,CAAA;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,OAAmB,EAAE,EAAE,CAC1C,kBAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA"}
@@ -0,0 +1,3 @@
1
+ import type { APIContext } from 'astro';
2
+ export declare const GET: (context: APIContext) => Promise<Response>;
3
+ //# sourceMappingURL=%5BsurveyId%5D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"[surveyId].d.ts","sourceRoot":"","sources":["../../../../src/ui/api/surveys/[surveyId].ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,OAAO,CAAA;AAqBvC,eAAO,MAAM,GAAG,GAAI,SAAS,UAAU,sBAC0B,CAAA"}
@@ -0,0 +1,17 @@
1
+ import { createSurveyRoutes } from '../../../routes/surveys.js';
2
+ import { buildSiteAuthz } from '../_authz.js';
3
+ function toCtx(context) {
4
+ const env = context.locals.cmsEnv ?? {};
5
+ return {
6
+ request: context.request,
7
+ params: { surveyId: context.params.surveyId },
8
+ db: env.SITE_DB,
9
+ env,
10
+ };
11
+ }
12
+ function routeConfig(context) {
13
+ const locals = context.locals;
14
+ return { authz: buildSiteAuthz(context), providers: locals.cmsProviders };
15
+ }
16
+ export const GET = (context) => createSurveyRoutes(routeConfig(context)).results(toCtx(context));
17
+ //# sourceMappingURL=%5BsurveyId%5D.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"[surveyId].js","sourceRoot":"","sources":["../../../../src/ui/api/surveys/[surveyId].ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,kBAAkB,EAA0B,MAAM,4BAA4B,CAAA;AACvF,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAE7C,SAAS,KAAK,CAAC,OAAmB;IACjC,MAAM,GAAG,GAAI,OAAO,CAAC,MAA+C,CAAC,MAAM,IAAI,EAAE,CAAA;IACjF,OAAO;QACN,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,MAAM,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE;QAC7C,EAAE,EAAE,GAAG,CAAC,OAA6B;QACrC,GAAG;KACH,CAAA;AACF,CAAC;AAED,SAAS,WAAW,CAAC,OAAmB;IACvC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAkD,CAAA;IACzE,OAAO,EAAE,KAAK,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,MAAM,CAAC,YAAY,EAAE,CAAA;AAC1E,CAAC;AAED,MAAM,CAAC,MAAM,GAAG,GAAG,CAAC,OAAmB,EAAE,EAAE,CAC1C,kBAAkB,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/ui/client/mount.tsx"],"names":[],"mappings":"AAOA,OAAO,0BAA0B,CAAA;AAajC,wBAAsB,KAAK,CAAC,SAAS,SAAkB,iBAqBtD"}
1
+ {"version":3,"file":"mount.d.ts","sourceRoot":"","sources":["../../../src/ui/client/mount.tsx"],"names":[],"mappings":"AAOA,OAAO,0BAA0B,CAAA;AAajC,wBAAsB,KAAK,CAAC,SAAS,SAAkB,iBAsBtD"}
@@ -33,6 +33,7 @@ export async function mount(elementId = 'masthead-root') {
33
33
  const initial = initialWorkspaceState(config.workspaces, config.activeWorkspaceId, user);
34
34
  const screens = createCmsScreens({
35
35
  allowInlineAuthorCreation: config.socialSharing.allowInlineAuthorCreation,
36
+ surveyId: config.surveyResults?.surveyId,
36
37
  });
37
38
  createRoot(el).render(_jsx(CmsApp, { initial: initial, screens: screens, boot: boot }));
38
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../../src/ui/client/mount.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAA0B,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,0BAA0B,CAAA;AAEjC,KAAK,UAAU,OAAO,CAAC,IAAY;IAClC,IAAI,CAAC;QACJ,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,SAAS,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC3D,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACR,uDAAuD;QACvD,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,SAAS,GAAG,eAAe;IACtD,MAAM,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;IAC7C,IAAI,CAAC,EAAE;QAAE,OAAM;IAEf,6EAA6E;IAC7E,+EAA+E;IAC/E,0EAA0E;IAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAA;IACjC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAA;IAEjC,MAAM,IAAI,GACT,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI;QACpE,CAAC,CAAC,CAAE,EAAE,CAAC,IAAiC,CAAC,IAAI,IAAI,IAAI,CAAC;QACtD,CAAC,CAAC,IAAI,CAAA;IAER,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,gBAAgB,CAAC;QAChC,yBAAyB,EAAE,MAAM,CAAC,aAAa,CAAC,yBAAyB;KACzE,CAAC,CAAA;IACF,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAC,MAAM,IAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAI,CAAC,CAAA;AAClF,CAAC;AAED,KAAK,KAAK,EAAE,CAAA"}
1
+ {"version":3,"file":"mount.js","sourceRoot":"","sources":["../../../src/ui/client/mount.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gCAAgC,CAAA;AACvD,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAE7C,OAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,CAAA;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAA;AAC/D,OAAO,EAA0B,gBAAgB,EAAE,MAAM,iBAAiB,CAAA;AAC1E,OAAO,0BAA0B,CAAA;AAEjC,KAAK,UAAU,OAAO,CAAC,IAAY;IAClC,IAAI,CAAC;QACJ,MAAM,CAAC,GAAG,MAAM,KAAK,CAAC,GAAG,IAAI,SAAS,CAAC,CAAA;QACvC,MAAM,IAAI,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAA;QAC3D,OAAO,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,IAAI,EAAE,CAAA;IAC5C,CAAC;IAAC,MAAM,CAAC;QACR,uDAAuD;QACvD,OAAO,IAAI,CAAA;IACZ,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CAAC,SAAS,GAAG,eAAe;IACtD,MAAM,EAAE,GAAG,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAA;IAC7C,IAAI,CAAC,EAAE;QAAE,OAAM;IAEf,6EAA6E;IAC7E,+EAA+E;IAC/E,0EAA0E;IAC1E,MAAM,IAAI,GAAG,MAAM,CAAC,aAAa,CAAA;IACjC,MAAM,EAAE,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9B,MAAM,IAAI,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAA;IAEjC,MAAM,IAAI,GACT,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,IAAI,IAAI,OAAO,EAAE,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,IAAI,EAAE,CAAC,IAAI;QACpE,CAAC,CAAC,CAAE,EAAE,CAAC,IAAiC,CAAC,IAAI,IAAI,IAAI,CAAC;QACtD,CAAC,CAAC,IAAI,CAAA;IAER,MAAM,OAAO,GAAG,qBAAqB,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,iBAAiB,EAAE,IAAI,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,gBAAgB,CAAC;QAChC,yBAAyB,EAAE,MAAM,CAAC,aAAa,CAAC,yBAAyB;QACzE,QAAQ,EAAE,MAAM,CAAC,aAAa,EAAE,QAAQ;KACxC,CAAC,CAAA;IACF,UAAU,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,KAAC,MAAM,IAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,GAAI,CAAC,CAAA;AAClF,CAAC;AAED,KAAK,KAAK,EAAE,CAAA"}
@@ -1,4 +1,4 @@
1
- import type { ContentType } from '../schema/types.js';
1
+ import type { CmsRole, ContentType } from '../schema/types.js';
2
2
  import { type Route } from './hash-router.js';
3
3
  export type Command = {
4
4
  kind: 'create';
@@ -20,5 +20,9 @@ export type Command = {
20
20
  id: string;
21
21
  };
22
22
  export declare const baseCommands: Command[];
23
+ export declare function commandsForAccess(options: {
24
+ surveyResultsEnabled: boolean;
25
+ role: CmsRole | null;
26
+ }): Command[];
23
27
  export declare function filterCommands(query: string, all: Command[]): Command[];
24
28
  //# sourceMappingURL=commands.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/ui/commands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AACrD,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,MAAM,OAAO,GAChB;IACA,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,WAAW,CAAA;CACvB,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AA6BzE,eAAO,MAAM,YAAY,EAAE,OAAO,EAcjC,CAAA;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAIvE"}
1
+ {"version":3,"file":"commands.d.ts","sourceRoot":"","sources":["../../src/ui/commands.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAA;AAE9D,OAAO,EAAU,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,MAAM,OAAO,GAChB;IACA,IAAI,EAAE,QAAQ,CAAA;IACd,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,WAAW,CAAA;CACvB,GACD;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACzE;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,CAAA;AA+BzE,eAAO,MAAM,YAAY,EAAE,OAAO,EAcjC,CAAA;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE;IAC1C,oBAAoB,EAAE,OAAO,CAAA;IAC7B,IAAI,EAAE,OAAO,GAAG,IAAI,CAAA;CACpB,GAAG,OAAO,EAAE,CAKZ;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAIvE"}
@@ -1,3 +1,4 @@
1
+ import { canViewSurveyResponses } from '../surveys/access.js';
1
2
  import { ROUTES } from './hash-router.js';
2
3
  const JUMP_LABELS = {
3
4
  dashboard: 'Dashboard',
@@ -9,6 +10,7 @@ const JUMP_LABELS = {
9
10
  topics: 'Topics & tags',
10
11
  'content-insights': 'Content Insights',
11
12
  subscriptions: 'Subscriptions',
13
+ 'survey-responses': 'Survey responses',
12
14
  'social-share': 'Social Share',
13
15
  settings: 'Settings',
14
16
  };
@@ -22,6 +24,7 @@ const JUMP_ICONS = {
22
24
  topics: 'tag',
23
25
  'content-insights': 'sparkle',
24
26
  subscriptions: 'inbox',
27
+ 'survey-responses': 'chart',
25
28
  'social-share': 'share',
26
29
  settings: 'settings',
27
30
  };
@@ -38,6 +41,10 @@ export const baseCommands = [
38
41
  route: r,
39
42
  })),
40
43
  ];
44
+ export function commandsForAccess(options) {
45
+ const canViewSurvey = options.surveyResultsEnabled && canViewSurveyResponses(options.role);
46
+ return baseCommands.filter((command) => command.kind !== 'jump' || command.route !== 'survey-responses' || canViewSurvey);
47
+ }
41
48
  export function filterCommands(query, all) {
42
49
  const q = query.trim().toLowerCase();
43
50
  if (!q)
@@ -1 +1 @@
1
- {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/ui/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAA;AAarD,MAAM,WAAW,GAA0B;IAC1C,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,eAAe;IACvB,kBAAkB,EAAE,kBAAkB;IACtC,aAAa,EAAE,eAAe;IAC9B,cAAc,EAAE,cAAc;IAC9B,QAAQ,EAAE,UAAU;CACpB,CAAA;AACD,MAAM,UAAU,GAA0B;IACzC,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,OAAO;IAClB,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,KAAK;IACb,kBAAkB,EAAE,SAAS;IAC7B,aAAa,EAAE,OAAO;IACtB,cAAc,EAAE,OAAO;IACvB,QAAQ,EAAE,UAAU;CACpB,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAc;IACtC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE;IAC7F,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE;IAC3F,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE;IAC7F,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE;IACvF,GAAG,MAAM,CAAC,GAAG,CACZ,CAAC,CAAC,EAAW,EAAE,CAAC,CAAC;QAChB,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE;QAChC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;QACnB,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC;KACR,CAAC,CACF;CACD,CAAA;AAED,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,GAAc;IAC3D,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9B,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5D,CAAC"}
1
+ {"version":3,"file":"commands.js","sourceRoot":"","sources":["../../src/ui/commands.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAA;AAC7D,OAAO,EAAE,MAAM,EAAc,MAAM,kBAAkB,CAAA;AAarD,MAAM,WAAW,GAA0B;IAC1C,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,mBAAmB;IAC5B,MAAM,EAAE,eAAe;IACvB,kBAAkB,EAAE,kBAAkB;IACtC,aAAa,EAAE,eAAe;IAC9B,kBAAkB,EAAE,kBAAkB;IACtC,cAAc,EAAE,cAAc;IAC9B,QAAQ,EAAE,UAAU;CACpB,CAAA;AACD,MAAM,UAAU,GAA0B;IACzC,SAAS,EAAE,WAAW;IACtB,OAAO,EAAE,SAAS;IAClB,QAAQ,EAAE,UAAU;IACpB,KAAK,EAAE,OAAO;IACd,SAAS,EAAE,OAAO;IAClB,OAAO,EAAE,OAAO;IAChB,MAAM,EAAE,KAAK;IACb,kBAAkB,EAAE,SAAS;IAC7B,aAAa,EAAE,OAAO;IACtB,kBAAkB,EAAE,OAAO;IAC3B,cAAc,EAAE,OAAO;IACvB,QAAQ,EAAE,UAAU;CACpB,CAAA;AAED,MAAM,CAAC,MAAM,YAAY,GAAc;IACtC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE;IAC7F,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,OAAO,EAAE;IAC3F,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,aAAa,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,SAAS,EAAE;IAC7F,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,EAAE;IACvF,GAAG,MAAM,CAAC,GAAG,CACZ,CAAC,CAAC,EAAW,EAAE,CAAC,CAAC;QAChB,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,SAAS,WAAW,CAAC,CAAC,CAAC,EAAE;QAChC,IAAI,EAAE,UAAU,CAAC,CAAC,CAAC;QACnB,IAAI,EAAE,MAAM;QACZ,KAAK,EAAE,CAAC;KACR,CAAC,CACF;CACD,CAAA;AAED,MAAM,UAAU,iBAAiB,CAAC,OAGjC;IACA,MAAM,aAAa,GAAG,OAAO,CAAC,oBAAoB,IAAI,sBAAsB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1F,OAAO,YAAY,CAAC,MAAM,CACzB,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,KAAK,MAAM,IAAI,OAAO,CAAC,KAAK,KAAK,kBAAkB,IAAI,aAAa,CAC7F,CAAA;AACF,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAa,EAAE,GAAc;IAC3D,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;IACpC,IAAI,CAAC,CAAC;QAAE,OAAO,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC9B,OAAO,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAA;AAC5D,CAAC"}
@@ -1,4 +1,5 @@
1
1
  import { type ReactNode } from 'react';
2
+ import type { CmsRole } from '../../schema/types.js';
2
3
  import type { BootState } from '../client/boot-state.js';
3
4
  import type { Route } from '../hash-router.js';
4
5
  import { type WorkspaceState } from '../workspace-context.js';
@@ -13,4 +14,5 @@ export declare function CmsApp(props: {
13
14
  */
14
15
  boot?: BootState;
15
16
  }): import("react").JSX.Element;
17
+ export declare function resolveScreenForAccess(screens: ScreenRegistry, route: Route, role: CmsRole | null): (() => ReactNode) | undefined;
16
18
  //# sourceMappingURL=CmsApp.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CmsApp.d.ts","sourceRoot":"","sources":["../../../src/ui/components/CmsApp.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAA;AACtE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AACxD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG9C,OAAO,EAAqB,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAMhF,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,SAAS,CAAC,CAAC,CAAA;AAEpE,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC7B,OAAO,EAAE,cAAc,CAAA;IACvB,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;CAChB,+BASA"}
1
+ {"version":3,"file":"CmsApp.d.ts","sourceRoot":"","sources":["../../../src/ui/components/CmsApp.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,SAAS,EAAuB,MAAM,OAAO,CAAA;AACtE,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAA;AAEpD,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAA;AAExD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG9C,OAAO,EAAmC,KAAK,cAAc,EAAE,MAAM,yBAAyB,CAAA;AAM9F,MAAM,MAAM,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,SAAS,CAAC,CAAC,CAAA;AAEpE,wBAAgB,MAAM,CAAC,KAAK,EAAE;IAC7B,OAAO,EAAE,cAAc,CAAA;IACvB,OAAO,CAAC,EAAE,cAAc,CAAA;IACxB;;;;OAIG;IACH,IAAI,CAAC,EAAE,SAAS,CAAA;CAChB,+BASA;AAyDD,wBAAgB,sBAAsB,CACrC,OAAO,EAAE,cAAc,EACvB,KAAK,EAAE,KAAK,EACZ,IAAI,EAAE,OAAO,GAAG,IAAI,GAClB,CAAC,MAAM,SAAS,CAAC,GAAG,SAAS,CAG/B"}
@@ -1,8 +1,10 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { Component, useEffect, useState } from 'react';
3
+ import { canViewSurveyResponses } from '../../surveys/access.js';
4
+ import { commandsForAccess } from '../commands.js';
3
5
  import { useHashRouter } from '../use-hash-router.js';
4
6
  import { useTweaks } from '../use-tweaks.js';
5
- import { WorkspaceProvider } from '../workspace-context.js';
7
+ import { useWorkspace, WorkspaceProvider } from '../workspace-context.js';
6
8
  import { CommandPalette } from './CommandPalette.js';
7
9
  import { NoAccessScreen } from './NoAccessScreen.js';
8
10
  import { Sidebar } from './Sidebar.js';
@@ -15,6 +17,7 @@ export function CmsApp(props) {
15
17
  }
16
18
  function Shell({ screens }) {
17
19
  const { route, navigate } = useHashRouter();
20
+ const { state } = useWorkspace();
18
21
  const { t, setTweak } = useTweaks();
19
22
  const [cmd, setCmd] = useState(false);
20
23
  const [collapsed, setCollapsed] = useState(false);
@@ -30,8 +33,16 @@ function Shell({ screens }) {
30
33
  window.addEventListener('keydown', h);
31
34
  return () => window.removeEventListener('keydown', h);
32
35
  }, []);
33
- const screen = screens[route];
34
- return (_jsxs("div", { className: "app", "data-collapsed": collapsed, children: [_jsx(Sidebar, { route: route, navigate: navigate, collapsed: collapsed }), _jsxs("div", { className: "main", children: [_jsx(Topbar, { collapsed: collapsed, setCollapsed: setCollapsed, onCommand: () => setCmd(true), theme: t.theme, setTheme: (v) => setTweak('theme', v) }), _jsx("div", { className: "scroll", children: _jsx(ScreenErrorBoundary, { route: route, children: _jsx(ScreenSlot, { render: screen, route: route }) }, route) })] }), cmd && (_jsx(CommandPalette, { onClose: () => setCmd(false), navigate: navigate, openDoc: () => setCmd(false) }))] }));
36
+ const screen = resolveScreenForAccess(screens, route, state.user?.role ?? null);
37
+ return (_jsxs("div", { className: "app", "data-collapsed": collapsed, children: [_jsx(Sidebar, { route: route, navigate: navigate, collapsed: collapsed, surveyResultsEnabled: Boolean(screens['survey-responses']) }), _jsxs("div", { className: "main", children: [_jsx(Topbar, { collapsed: collapsed, setCollapsed: setCollapsed, onCommand: () => setCmd(true), theme: t.theme, setTheme: (v) => setTweak('theme', v) }), _jsx("div", { className: "scroll", children: _jsx(ScreenErrorBoundary, { route: route, children: _jsx(ScreenSlot, { render: screen, route: route }) }, route) })] }), cmd && (_jsx(CommandPalette, { onClose: () => setCmd(false), navigate: navigate, openDoc: () => setCmd(false), commands: commandsForAccess({
38
+ surveyResultsEnabled: Boolean(screens['survey-responses']),
39
+ role: state.user?.role ?? null,
40
+ }) }))] }));
41
+ }
42
+ export function resolveScreenForAccess(screens, route, role) {
43
+ if (route === 'survey-responses' && !canViewSurveyResponses(role))
44
+ return undefined;
45
+ return screens[route];
35
46
  }
36
47
  function EmptyRoute({ route }) {
37
48
  return (_jsxs("div", { className: "page", style: { padding: 40, color: 'var(--ink-muted)' }, children: ["The \"", route, "\" screen mounts here."] }));