@cognite/dune 0.4.0 → 0.4.2
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/README.md
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
# @cognite/dune
|
|
2
|
+
|
|
3
|
+
Build and deploy React apps to [Cognite Data Fusion](https://docs.cognite.com/).
|
|
4
|
+
|
|
5
|
+
## Quick start
|
|
6
|
+
|
|
7
|
+
Scaffold a new app — AI skills are pulled automatically:
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npx @cognite/dune create
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
This prompts for your app name, org, project, and cluster, then generates a fully configured React + TypeScript project.
|
|
14
|
+
|
|
15
|
+
## Authentication
|
|
16
|
+
|
|
17
|
+
Wrap your app in `DuneAuthProvider` to get an authenticated `CogniteClient` from Fusion's iframe handshake:
|
|
18
|
+
|
|
19
|
+
```tsx
|
|
20
|
+
import { DuneAuthProvider, useDune } from '@cognite/dune/auth';
|
|
21
|
+
|
|
22
|
+
function App() {
|
|
23
|
+
const { sdk, isLoading } = useDune();
|
|
24
|
+
if (isLoading) return <div>Loading...</div>;
|
|
25
|
+
return <MyApp sdk={sdk} />;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export default function Root() {
|
|
29
|
+
return (
|
|
30
|
+
<DuneAuthProvider>
|
|
31
|
+
<App />
|
|
32
|
+
</DuneAuthProvider>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
For apps running inside the new Fusion app host, use `AppSdkAuthProvider` instead — it authenticates via the `@cognite/app-sdk` Comlink handshake.
|
|
38
|
+
|
|
39
|
+
## Deployment
|
|
40
|
+
|
|
41
|
+
Deploy interactively via browser OAuth:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
npx @cognite/dune deploy:interactive
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
For CI, set your client secret as an environment variable and run:
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pnpm deploy
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
Deployment targets are configured in `app.json` at the project root.
|
|
54
|
+
|
|
55
|
+
## AI skills
|
|
56
|
+
|
|
57
|
+
Skills guide your AI agent (Claude Code, Cursor, etc.) through Dune-specific tasks like adding auth, building chat UIs, or reviewing code. They are pulled automatically on `npx @cognite/dune create` and can be synced later:
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx @cognite/dune skills pull
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Browse available skills at [cognitedata/dune-skills](https://github.com/cognitedata/dune-skills).
|
|
64
|
+
|
|
65
|
+
## Requirements
|
|
66
|
+
|
|
67
|
+
- Node.js ≥ 18
|
|
68
|
+
- React ≥ 18 (optional peer dependency — only needed for auth components)
|
|
@@ -23,7 +23,10 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>package.json'
|
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"@cognite/aura": "^0.1.5",
|
|
25
25
|
"@cognite/sdk": "^10.3.0",
|
|
26
|
-
"@cognite/dune": "^0.
|
|
26
|
+
"@cognite/dune": "^0.4.2",
|
|
27
|
+
<% if (infra === 'appsApi') { -%>
|
|
28
|
+
"@cognite/app-sdk": "^0.3.0",
|
|
29
|
+
<% } -%>
|
|
27
30
|
"@tabler/icons-react": "^3.35.0",
|
|
28
31
|
"@tanstack/react-query": "^5.90.10",
|
|
29
32
|
"clsx": "^2.1.1",
|
|
@@ -16,7 +16,12 @@ import {
|
|
|
16
16
|
Loader,
|
|
17
17
|
Separator,
|
|
18
18
|
} from '@cognite/aura/components';
|
|
19
|
+
<% if (infra === 'appsApi') { -%>
|
|
20
|
+
import { connectToHostApp } from '@cognite/app-sdk';
|
|
21
|
+
import { useEffect, useState } from 'react';
|
|
22
|
+
<% } else { -%>
|
|
19
23
|
import { useDune } from '@cognite/dune';
|
|
24
|
+
<% } -%>
|
|
20
25
|
import { IconCaretUpDown, IconRocket } from '@tabler/icons-react';
|
|
21
26
|
|
|
22
27
|
import appConfig from '../app.json';
|
|
@@ -61,44 +66,94 @@ const CHECKLIST_STEPS = [
|
|
|
61
66
|
] as const;
|
|
62
67
|
|
|
63
68
|
function App() {
|
|
69
|
+
<% if (infra === 'appsApi') { -%>
|
|
70
|
+
// Connect to the Fusion host via @cognite/app-sdk. The handshake is
|
|
71
|
+
// asynchronous — `project` is only populated after Comlink finishes
|
|
72
|
+
// exposing the host API, so we render a loader until then.
|
|
73
|
+
const [project, setProject] = useState<string | null>(null);
|
|
74
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
75
|
+
const [error, setError] = useState<string | undefined>();
|
|
76
|
+
|
|
77
|
+
useEffect(() => {
|
|
78
|
+
let cancelled = false;
|
|
79
|
+
connectToHostApp({ applicationName: '<%= name %>' })
|
|
80
|
+
.then(async ({ api }) => {
|
|
81
|
+
if (cancelled) return;
|
|
82
|
+
const proj = await api.getProject();
|
|
83
|
+
if (cancelled) return;
|
|
84
|
+
setProject(proj);
|
|
85
|
+
})
|
|
86
|
+
.catch((err: unknown) => {
|
|
87
|
+
if (cancelled) return;
|
|
88
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
89
|
+
})
|
|
90
|
+
.finally(() => {
|
|
91
|
+
if (!cancelled) setIsLoading(false);
|
|
92
|
+
});
|
|
93
|
+
return () => {
|
|
94
|
+
cancelled = true;
|
|
95
|
+
};
|
|
96
|
+
}, []);
|
|
97
|
+
<% } else { -%>
|
|
64
98
|
const { sdk, isLoading, error } = useDune();
|
|
99
|
+
<% } -%>
|
|
100
|
+
|
|
101
|
+
if (isLoading) {
|
|
102
|
+
return (
|
|
103
|
+
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
104
|
+
<section className="mx-auto flex min-h-screen w-full max-w-lg flex-col justify-center p-4 sm:p-8">
|
|
105
|
+
<div className="mx-auto w-full max-w-sm">
|
|
106
|
+
<Card aria-label="Loading project" aria-live="polite">
|
|
107
|
+
<CardContent>
|
|
108
|
+
<div className="inline-flex items-center gap-3 text-muted-foreground">
|
|
109
|
+
<Loader size={20} />
|
|
110
|
+
<span>Loading project...</span>
|
|
111
|
+
</div>
|
|
112
|
+
</CardContent>
|
|
113
|
+
</Card>
|
|
114
|
+
</div>
|
|
115
|
+
</section>
|
|
116
|
+
</main>
|
|
117
|
+
);
|
|
118
|
+
}
|
|
65
119
|
|
|
120
|
+
<% if (infra === 'appsApi') { -%>
|
|
66
121
|
if (error) {
|
|
67
122
|
return (
|
|
68
123
|
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
69
124
|
<section className="mx-auto flex min-h-screen w-full max-w-lg flex-col justify-center p-4 sm:p-8">
|
|
70
125
|
<div className="mx-auto w-full max-w-sm">
|
|
71
|
-
<Alert
|
|
72
|
-
<AlertDescription>{error}</AlertDescription>
|
|
126
|
+
<Alert>
|
|
127
|
+
<AlertDescription>Failed to connect to Fusion host: {error}</AlertDescription>
|
|
73
128
|
</Alert>
|
|
74
129
|
</div>
|
|
75
130
|
</section>
|
|
76
131
|
</main>
|
|
77
132
|
);
|
|
78
133
|
}
|
|
79
|
-
|
|
80
|
-
if (
|
|
134
|
+
<% } else { -%>
|
|
135
|
+
if (error) {
|
|
81
136
|
return (
|
|
82
137
|
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
83
138
|
<section className="mx-auto flex min-h-screen w-full max-w-lg flex-col justify-center p-4 sm:p-8">
|
|
84
139
|
<div className="mx-auto w-full max-w-sm">
|
|
85
|
-
<
|
|
86
|
-
<
|
|
87
|
-
|
|
88
|
-
<Loader size={20} />
|
|
89
|
-
<span>Loading project...</span>
|
|
90
|
-
</div>
|
|
91
|
-
</CardContent>
|
|
92
|
-
</Card>
|
|
140
|
+
<Alert>
|
|
141
|
+
<AlertDescription>{error}</AlertDescription>
|
|
142
|
+
</Alert>
|
|
93
143
|
</div>
|
|
94
144
|
</section>
|
|
95
145
|
</main>
|
|
96
146
|
);
|
|
97
147
|
}
|
|
148
|
+
<% } -%>
|
|
98
149
|
|
|
99
150
|
const deployment = appConfig.deployments?.[0];
|
|
100
151
|
const orgLabel = deployment?.org ?? '';
|
|
152
|
+
<% if (infra === 'appsApi') { -%>
|
|
153
|
+
const projectLabel = deployment?.project ?? project ?? '';
|
|
154
|
+
<% } else { -%>
|
|
101
155
|
const projectLabel = deployment?.project ?? sdk.project;
|
|
156
|
+
<% } -%>
|
|
102
157
|
|
|
103
158
|
return (
|
|
104
159
|
<main className="min-h-screen bg-muted/50 text-foreground">
|
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/main.tsx'
|
|
3
3
|
---
|
|
4
|
-
<% if (infra
|
|
5
|
-
import { AppSdkAuthProvider } from '@cognite/dune';
|
|
6
|
-
<% } else { -%>
|
|
4
|
+
<% if (infra !== 'appsApi') { -%>
|
|
7
5
|
import { DuneAuthProvider } from '@cognite/dune';
|
|
8
6
|
<% } -%>
|
|
9
7
|
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
|
|
@@ -27,9 +25,7 @@ ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
|
27
25
|
<React.StrictMode>
|
|
28
26
|
<QueryClientProvider client={queryClient}>
|
|
29
27
|
<% if (infra === 'appsApi') { -%>
|
|
30
|
-
<
|
|
31
|
-
<App />
|
|
32
|
-
</AppSdkAuthProvider>
|
|
28
|
+
<App />
|
|
33
29
|
<% } else { -%>
|
|
34
30
|
<DuneAuthProvider>
|
|
35
31
|
<App />
|
package/dist/cli/cli.js
CHANGED
|
@@ -58,6 +58,6 @@ function registerSkillsCommand(parent) {
|
|
|
58
58
|
|
|
59
59
|
// cli/cli.ts
|
|
60
60
|
var program = new Command();
|
|
61
|
-
program.name("dune").description("Build and deploy React apps to Cognite Data Fusion").version("0.4.
|
|
61
|
+
program.name("dune").description("Build and deploy React apps to Cognite Data Fusion").version("0.4.2");
|
|
62
62
|
registerSkillsCommand(program);
|
|
63
63
|
program.parse();
|
package/package.json
CHANGED
|
@@ -1,16 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cognite/dune",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.2",
|
|
4
4
|
"description": "Build and deploy React apps to Cognite Data Fusion",
|
|
5
|
-
"keywords": [
|
|
6
|
-
"cognite",
|
|
7
|
-
"dune",
|
|
8
|
-
"cdf",
|
|
9
|
-
"fusion",
|
|
10
|
-
"react",
|
|
11
|
-
"scaffold",
|
|
12
|
-
"deploy"
|
|
13
|
-
],
|
|
14
5
|
"license": "Apache-2.0",
|
|
15
6
|
"author": "Cognite",
|
|
16
7
|
"repository": {
|