@malloy-publisher/sdk 0.0.65 → 0.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs.js +25 -25
- package/dist/index.es.js +4028 -3639
- package/package.json +1 -1
- package/src/components/Home/Home.tsx +397 -28
package/package.json
CHANGED
|
@@ -1,8 +1,26 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import AnalyticsRoundedIcon from "@mui/icons-material/AnalyticsRounded";
|
|
2
|
+
import ArrowForwardRoundedIcon from "@mui/icons-material/ArrowForwardRounded";
|
|
3
|
+
import AutoAwesomeRoundedIcon from "@mui/icons-material/AutoAwesomeRounded";
|
|
4
|
+
import CodeRoundedIcon from "@mui/icons-material/CodeRounded";
|
|
5
|
+
import ExploreRoundedIcon from "@mui/icons-material/ExploreRounded";
|
|
6
|
+
import PsychologyRoundedIcon from "@mui/icons-material/PsychologyRounded";
|
|
7
|
+
import StorageRoundedIcon from "@mui/icons-material/StorageRounded";
|
|
8
|
+
import {
|
|
9
|
+
Box,
|
|
10
|
+
Button,
|
|
11
|
+
Card,
|
|
12
|
+
CardContent,
|
|
13
|
+
Chip,
|
|
14
|
+
Container,
|
|
15
|
+
Divider,
|
|
16
|
+
Grid,
|
|
17
|
+
Stack,
|
|
18
|
+
Typography,
|
|
19
|
+
} from "@mui/material";
|
|
20
|
+
import { Configuration, ProjectsApi } from "../../client";
|
|
21
|
+
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
3
22
|
import { ApiErrorDisplay } from "../ApiErrorDisplay";
|
|
4
23
|
import { Loading } from "../Loading";
|
|
5
|
-
import { useQueryWithApiError } from "../../hooks/useQueryWithApiError";
|
|
6
24
|
|
|
7
25
|
const projectsApi = new ProjectsApi(new Configuration());
|
|
8
26
|
|
|
@@ -10,6 +28,36 @@ interface HomeProps {
|
|
|
10
28
|
navigate?: (to: string, event?: React.MouseEvent) => void;
|
|
11
29
|
}
|
|
12
30
|
|
|
31
|
+
// Helper function to extract a brief description from README content
|
|
32
|
+
const getProjectDescription = (readme: string | undefined): string => {
|
|
33
|
+
if (!readme) {
|
|
34
|
+
return "Explore semantic models, run queries, and build dashboards";
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Remove markdown formatting and get first paragraph
|
|
38
|
+
const cleanText = readme
|
|
39
|
+
.replace(/^#+\s+/gm, "") // Remove headers
|
|
40
|
+
.replace(/\*\*(.*?)\*\*/g, "$1") // Remove bold
|
|
41
|
+
.replace(/\*(.*?)\*/g, "$1") // Remove italic
|
|
42
|
+
.replace(/\[([^\]]+)\]\([^)]+\)/g, "$1") // Remove links
|
|
43
|
+
.replace(/`([^`]+)`/g, "$1") // Remove code
|
|
44
|
+
.trim();
|
|
45
|
+
|
|
46
|
+
// Get first paragraph (split by double newlines)
|
|
47
|
+
const paragraphs = cleanText.split(/\n\s*\n/);
|
|
48
|
+
const firstParagraph = paragraphs[0] || cleanText;
|
|
49
|
+
|
|
50
|
+
// Limit to ~120 characters
|
|
51
|
+
if (firstParagraph.length <= 120) {
|
|
52
|
+
return firstParagraph;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Truncate at word boundary
|
|
56
|
+
const truncated = firstParagraph.substring(0, 120).split(" ");
|
|
57
|
+
truncated.pop(); // Remove last partial word
|
|
58
|
+
return truncated.join(" ") + "...";
|
|
59
|
+
};
|
|
60
|
+
|
|
13
61
|
export default function Home({ navigate }: HomeProps) {
|
|
14
62
|
const { data, isSuccess, isError, error } = useQueryWithApiError({
|
|
15
63
|
queryKey: ["projects"],
|
|
@@ -21,34 +69,355 @@ export default function Home({ navigate }: HomeProps) {
|
|
|
21
69
|
}
|
|
22
70
|
|
|
23
71
|
if (isSuccess) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
<
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
72
|
+
return (
|
|
73
|
+
<Container maxWidth="lg" sx={{ py: 4 }}>
|
|
74
|
+
{/* Hero Section */}
|
|
75
|
+
<Box sx={{ textAlign: "center", mb: 6 }}>
|
|
76
|
+
<Stack
|
|
77
|
+
direction="row"
|
|
78
|
+
justifyContent="center"
|
|
79
|
+
alignItems="center"
|
|
80
|
+
spacing={1}
|
|
81
|
+
sx={{ mb: 2 }}
|
|
82
|
+
>
|
|
83
|
+
<AutoAwesomeRoundedIcon
|
|
84
|
+
sx={{ fontSize: 32, color: "primary.main" }}
|
|
85
|
+
/>
|
|
86
|
+
<Typography variant="h3" component="h1" fontWeight={700}>
|
|
87
|
+
Publisher
|
|
88
|
+
</Typography>
|
|
89
|
+
</Stack>
|
|
90
|
+
<Typography
|
|
91
|
+
variant="h5"
|
|
92
|
+
color="text.secondary"
|
|
93
|
+
sx={{ mb: 3, maxWidth: 600, mx: "auto" }}
|
|
94
|
+
>
|
|
95
|
+
The open-source semantic model server for the Malloy data
|
|
96
|
+
language
|
|
97
|
+
</Typography>
|
|
98
|
+
<Typography
|
|
99
|
+
variant="body1"
|
|
100
|
+
color="text.secondary"
|
|
101
|
+
sx={{ maxWidth: 800, mx: "auto" }}
|
|
102
|
+
>
|
|
103
|
+
Define semantic models once — and use them everywhere.
|
|
104
|
+
Publisher serves Malloy models through clean APIs, enabling
|
|
105
|
+
consistent, interpretable, and AI-ready data access for tools,
|
|
106
|
+
applications, and agents.
|
|
107
|
+
</Typography>
|
|
108
|
+
</Box>
|
|
109
|
+
|
|
110
|
+
{/* Feature Cards */}
|
|
111
|
+
<Grid container spacing={3} sx={{ mb: 6 }}>
|
|
112
|
+
<Grid size={{ xs: 12, md: 4 }}>
|
|
113
|
+
<Card
|
|
114
|
+
variant="outlined"
|
|
115
|
+
onClick={() => {
|
|
116
|
+
window.open(
|
|
117
|
+
"https://github.com/malloydata/publisher/blob/main/README.md#ad-hoc-data-analysis",
|
|
118
|
+
"_blank",
|
|
119
|
+
);
|
|
120
|
+
}}
|
|
121
|
+
sx={{
|
|
122
|
+
height: "100%",
|
|
123
|
+
cursor: "pointer",
|
|
124
|
+
transition: "all 0.2s ease",
|
|
125
|
+
"&:hover": {
|
|
126
|
+
transform: "translateY(-2px)",
|
|
127
|
+
boxShadow: 2,
|
|
128
|
+
},
|
|
129
|
+
}}
|
|
130
|
+
>
|
|
131
|
+
<CardContent sx={{ p: 3 }}>
|
|
132
|
+
<Stack
|
|
133
|
+
direction="row"
|
|
134
|
+
alignItems="center"
|
|
135
|
+
spacing={1}
|
|
136
|
+
sx={{ mb: 2 }}
|
|
137
|
+
>
|
|
138
|
+
<AnalyticsRoundedIcon
|
|
139
|
+
sx={{ color: "info.main", fontSize: 28 }}
|
|
140
|
+
/>
|
|
141
|
+
<Typography variant="h6" fontWeight={600}>
|
|
142
|
+
Ad Hoc Analysis
|
|
143
|
+
</Typography>
|
|
144
|
+
</Stack>
|
|
145
|
+
<Typography
|
|
146
|
+
variant="body2"
|
|
147
|
+
color="text.secondary"
|
|
148
|
+
sx={{ mb: 2 }}
|
|
149
|
+
>
|
|
150
|
+
Use Explorer, a visual query builder that allows
|
|
151
|
+
analysts to browse semantic sources, build queries,
|
|
152
|
+
and run nested logic — all without writing code.
|
|
153
|
+
</Typography>
|
|
154
|
+
<Chip
|
|
155
|
+
label="No-code"
|
|
156
|
+
size="small"
|
|
157
|
+
color="primary"
|
|
158
|
+
variant="outlined"
|
|
159
|
+
/>
|
|
160
|
+
</CardContent>
|
|
161
|
+
</Card>
|
|
162
|
+
</Grid>
|
|
163
|
+
|
|
164
|
+
<Grid size={{ xs: 12, md: 4 }}>
|
|
165
|
+
<Card
|
|
166
|
+
variant="outlined"
|
|
167
|
+
onClick={() => {
|
|
168
|
+
window.open(
|
|
169
|
+
"https://github.com/malloydata/publisher/blob/main/README.md#notebook-based-dashboards",
|
|
170
|
+
"_blank",
|
|
171
|
+
);
|
|
172
|
+
}}
|
|
173
|
+
sx={{
|
|
174
|
+
height: "100%",
|
|
175
|
+
cursor: "pointer",
|
|
176
|
+
transition: "all 0.2s ease",
|
|
177
|
+
"&:hover": {
|
|
178
|
+
transform: "translateY(-2px)",
|
|
179
|
+
boxShadow: 2,
|
|
180
|
+
},
|
|
181
|
+
}}
|
|
182
|
+
>
|
|
183
|
+
<CardContent sx={{ p: 3 }}>
|
|
184
|
+
<Stack
|
|
185
|
+
direction="row"
|
|
186
|
+
alignItems="center"
|
|
187
|
+
spacing={1}
|
|
188
|
+
sx={{ mb: 2 }}
|
|
189
|
+
>
|
|
190
|
+
<CodeRoundedIcon
|
|
191
|
+
sx={{ color: "warning.main", fontSize: 28 }}
|
|
192
|
+
/>
|
|
193
|
+
<Typography variant="h6" fontWeight={600}>
|
|
194
|
+
Notebook Dashboards
|
|
195
|
+
</Typography>
|
|
196
|
+
</Stack>
|
|
197
|
+
<Typography
|
|
198
|
+
variant="body2"
|
|
199
|
+
color="text.secondary"
|
|
200
|
+
sx={{ mb: 2 }}
|
|
201
|
+
>
|
|
202
|
+
Create shareable, code-first dashboards using Malloy
|
|
203
|
+
notebooks. Include text, charts, and reusable views —
|
|
204
|
+
all versioned alongside your models.
|
|
205
|
+
</Typography>
|
|
206
|
+
<Chip
|
|
207
|
+
label="Versioned"
|
|
208
|
+
size="small"
|
|
209
|
+
color="warning"
|
|
210
|
+
variant="outlined"
|
|
211
|
+
/>
|
|
212
|
+
</CardContent>
|
|
213
|
+
</Card>
|
|
214
|
+
</Grid>
|
|
215
|
+
|
|
216
|
+
<Grid size={{ xs: 12, md: 4 }}>
|
|
217
|
+
<Card
|
|
218
|
+
variant="outlined"
|
|
219
|
+
onClick={() => {
|
|
220
|
+
window.open(
|
|
221
|
+
"https://github.com/malloydata/publisher/blob/main/README.md#mcp-based-ai-data-agents",
|
|
222
|
+
"_blank",
|
|
223
|
+
);
|
|
224
|
+
}}
|
|
225
|
+
sx={{
|
|
226
|
+
height: "100%",
|
|
227
|
+
cursor: "pointer",
|
|
228
|
+
transition: "all 0.2s ease",
|
|
229
|
+
"&:hover": {
|
|
230
|
+
transform: "translateY(-2px)",
|
|
231
|
+
boxShadow: 2,
|
|
232
|
+
},
|
|
233
|
+
}}
|
|
234
|
+
>
|
|
235
|
+
<CardContent sx={{ p: 3 }}>
|
|
236
|
+
<Stack
|
|
237
|
+
direction="row"
|
|
238
|
+
alignItems="center"
|
|
239
|
+
spacing={1}
|
|
240
|
+
sx={{ mb: 2 }}
|
|
241
|
+
>
|
|
242
|
+
<PsychologyRoundedIcon
|
|
243
|
+
sx={{ color: "success.main", fontSize: 28 }}
|
|
244
|
+
/>
|
|
245
|
+
<Typography variant="h6" fontWeight={600}>
|
|
246
|
+
AI Data Agents
|
|
247
|
+
</Typography>
|
|
248
|
+
</Stack>
|
|
249
|
+
<Typography
|
|
250
|
+
variant="body2"
|
|
251
|
+
color="text.secondary"
|
|
252
|
+
sx={{ mb: 2 }}
|
|
253
|
+
>
|
|
254
|
+
Expose your semantic models via the Model Context
|
|
255
|
+
Protocol (MCP), enabling AI agents to discover
|
|
256
|
+
sources and ask well-formed questions.
|
|
257
|
+
</Typography>
|
|
258
|
+
<Chip
|
|
259
|
+
label="AI-Ready"
|
|
260
|
+
size="small"
|
|
261
|
+
color="success"
|
|
262
|
+
variant="outlined"
|
|
263
|
+
/>
|
|
264
|
+
</CardContent>
|
|
265
|
+
</Card>
|
|
266
|
+
</Grid>
|
|
267
|
+
</Grid>
|
|
268
|
+
|
|
269
|
+
<Divider sx={{ my: 4 }} />
|
|
270
|
+
|
|
271
|
+
{/* Project Selection Section */}
|
|
272
|
+
{data.data.length > 0 ? (
|
|
273
|
+
<>
|
|
274
|
+
<Box sx={{ textAlign: "center", mb: 4 }}>
|
|
275
|
+
<Stack
|
|
276
|
+
direction="row"
|
|
277
|
+
justifyContent="center"
|
|
278
|
+
alignItems="center"
|
|
279
|
+
spacing={1}
|
|
280
|
+
sx={{ mb: 2 }}
|
|
44
281
|
>
|
|
45
|
-
|
|
282
|
+
<StorageRoundedIcon
|
|
283
|
+
sx={{ color: "primary.main", fontSize: 24 }}
|
|
284
|
+
/>
|
|
285
|
+
<Typography variant="h4" fontWeight={600}>
|
|
286
|
+
Select a Project
|
|
287
|
+
</Typography>
|
|
288
|
+
</Stack>
|
|
289
|
+
<Typography variant="body1" color="text.secondary">
|
|
290
|
+
Choose a project to explore its semantic models and
|
|
291
|
+
start analyzing your data
|
|
46
292
|
</Typography>
|
|
293
|
+
</Box>
|
|
294
|
+
<Grid container spacing={3} justifyContent="center">
|
|
295
|
+
{data.data.map((project) => (
|
|
296
|
+
<Grid
|
|
297
|
+
size={{ xs: 12, sm: 6, md: 4 }}
|
|
298
|
+
key={project.name}
|
|
299
|
+
>
|
|
300
|
+
<Card
|
|
301
|
+
variant="outlined"
|
|
302
|
+
sx={{
|
|
303
|
+
height: "100%",
|
|
304
|
+
cursor: "pointer",
|
|
305
|
+
transition: "all 0.2s ease",
|
|
306
|
+
"&:hover": {
|
|
307
|
+
transform: "translateY(-2px)",
|
|
308
|
+
boxShadow: 2,
|
|
309
|
+
borderColor: "primary.main",
|
|
310
|
+
},
|
|
311
|
+
}}
|
|
312
|
+
onClick={(event) =>
|
|
313
|
+
navigate(`/${project.name}/`, event)
|
|
314
|
+
}
|
|
315
|
+
>
|
|
316
|
+
<CardContent sx={{ p: 3, textAlign: "center" }}>
|
|
317
|
+
<ExploreRoundedIcon
|
|
318
|
+
sx={{
|
|
319
|
+
fontSize: 48,
|
|
320
|
+
color: "primary.main",
|
|
321
|
+
mb: 2,
|
|
322
|
+
}}
|
|
323
|
+
/>
|
|
324
|
+
<Typography
|
|
325
|
+
variant="h6"
|
|
326
|
+
fontWeight={600}
|
|
327
|
+
gutterBottom
|
|
328
|
+
>
|
|
329
|
+
{project.name}
|
|
330
|
+
</Typography>
|
|
331
|
+
<Typography
|
|
332
|
+
variant="body2"
|
|
333
|
+
color="text.secondary"
|
|
334
|
+
sx={{ mb: 2 }}
|
|
335
|
+
>
|
|
336
|
+
{getProjectDescription(project.readme)}
|
|
337
|
+
</Typography>
|
|
338
|
+
<Button
|
|
339
|
+
variant="contained"
|
|
340
|
+
color="secondary"
|
|
341
|
+
endIcon={<ArrowForwardRoundedIcon />}
|
|
342
|
+
fullWidth
|
|
343
|
+
>
|
|
344
|
+
Open Project
|
|
345
|
+
</Button>
|
|
346
|
+
</CardContent>
|
|
347
|
+
</Card>
|
|
348
|
+
</Grid>
|
|
349
|
+
))}
|
|
47
350
|
</Grid>
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
351
|
+
</>
|
|
352
|
+
) : (
|
|
353
|
+
<Box sx={{ textAlign: "center", mb: 4 }}>
|
|
354
|
+
<Stack
|
|
355
|
+
direction="row"
|
|
356
|
+
justifyContent="center"
|
|
357
|
+
alignItems="center"
|
|
358
|
+
spacing={1}
|
|
359
|
+
sx={{ mb: 2 }}
|
|
360
|
+
>
|
|
361
|
+
<StorageRoundedIcon
|
|
362
|
+
sx={{ color: "primary.main", fontSize: 24 }}
|
|
363
|
+
/>
|
|
364
|
+
<Typography variant="h4" fontWeight={600}>
|
|
365
|
+
Get Started
|
|
366
|
+
</Typography>
|
|
367
|
+
</Stack>
|
|
368
|
+
<Typography
|
|
369
|
+
variant="body1"
|
|
370
|
+
color="text.secondary"
|
|
371
|
+
sx={{ mb: 3 }}
|
|
372
|
+
>
|
|
373
|
+
No projects found. Create your first Malloy project to
|
|
374
|
+
start exploring semantic models and building data
|
|
375
|
+
experiences.
|
|
376
|
+
</Typography>
|
|
377
|
+
<Button
|
|
378
|
+
variant="contained"
|
|
379
|
+
size="large"
|
|
380
|
+
color="primary"
|
|
381
|
+
startIcon={<AutoAwesomeRoundedIcon />}
|
|
382
|
+
href="https://github.com/malloydata/publisher/blob/main/README.md#server-configuration"
|
|
383
|
+
target="_blank"
|
|
384
|
+
rel="noopener noreferrer"
|
|
385
|
+
>
|
|
386
|
+
Learn How to Create Models
|
|
387
|
+
</Button>
|
|
388
|
+
</Box>
|
|
389
|
+
)}
|
|
390
|
+
|
|
391
|
+
{/* Footer Section */}
|
|
392
|
+
<Box
|
|
393
|
+
sx={{
|
|
394
|
+
textAlign: "center",
|
|
395
|
+
mt: 6,
|
|
396
|
+
pt: 4,
|
|
397
|
+
borderTop: 1,
|
|
398
|
+
borderColor: "divider",
|
|
399
|
+
}}
|
|
400
|
+
>
|
|
401
|
+
<Typography variant="body2" color="text.secondary">
|
|
402
|
+
Publisher is built on fully open infrastructure and designed
|
|
403
|
+
for the AI era. Join the{" "}
|
|
404
|
+
<a
|
|
405
|
+
href="https://join.slack.com/t/malloy-community/shared_invite/zt-1kgfwgi5g-CrsdaRqs81QY67QW0~t_uw"
|
|
406
|
+
target="_blank"
|
|
407
|
+
rel="noopener noreferrer"
|
|
408
|
+
style={{
|
|
409
|
+
color: "primary.main",
|
|
410
|
+
textDecoration: "underline",
|
|
411
|
+
}}
|
|
412
|
+
>
|
|
413
|
+
Malloy Slack community
|
|
414
|
+
</a>{" "}
|
|
415
|
+
to ask questions, share ideas, and contribute to the future of
|
|
416
|
+
data modeling.
|
|
417
|
+
</Typography>
|
|
418
|
+
</Box>
|
|
419
|
+
</Container>
|
|
420
|
+
);
|
|
52
421
|
} else {
|
|
53
422
|
return <Loading text="Loading projects..." />;
|
|
54
423
|
}
|