@cognite/dune 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.
- package/_templates/app/new/App.test.tsx.ejs.t +38 -0
- package/_templates/app/new/App.tsx.ejs.t +23 -0
- package/_templates/app/new/app.json.ejs.t +20 -0
- package/_templates/app/new/biome.json.ejs.t +25 -0
- package/_templates/app/new/gitignore.ejs.t +21 -0
- package/_templates/app/new/index.html.ejs.t +36 -0
- package/_templates/app/new/main.tsx.ejs.t +28 -0
- package/_templates/app/new/package.json.ejs.t +44 -0
- package/_templates/app/new/prompt.js +57 -0
- package/_templates/app/new/tsconfig.json.ejs.t +33 -0
- package/_templates/app/new/tsconfig.node.json.ejs.t +26 -0
- package/_templates/app/new/vite.config.ts.ejs.t +15 -0
- package/_templates/app/new/vitest.config.ts.ejs.t +15 -0
- package/_templates/app/new/vitest.setup.ts.ejs.t +5 -0
- package/bin/cli.js +64 -0
- package/dist/auth/index.d.ts +41 -0
- package/dist/auth/index.js +16 -0
- package/dist/chunk-VIBN7U5H.js +152 -0
- package/dist/deploy/index.d.ts +83 -0
- package/dist/deploy/index.js +219 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +16 -0
- package/dist/vite/index.d.ts +14 -0
- package/dist/vite/index.js +41 -0
- package/package.json +93 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/src/App.test.tsx
|
|
3
|
+
---
|
|
4
|
+
import * as dune from "@cognite/dune";
|
|
5
|
+
import { render, screen } from "@testing-library/react";
|
|
6
|
+
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
7
|
+
import App from "./App";
|
|
8
|
+
|
|
9
|
+
// Mock the @cognite/dune module
|
|
10
|
+
vi.mock(import("@cognite/dune"));
|
|
11
|
+
|
|
12
|
+
describe("App", () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vi.clearAllMocks();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it("renders loading state", () => {
|
|
18
|
+
vi.mocked(dune.useDune).mockReturnValue({
|
|
19
|
+
sdk: { project: "test-project" } as any,
|
|
20
|
+
isLoading: true,
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
render(<App />);
|
|
24
|
+
expect(screen.getByText("Loading...")).toBeInTheDocument();
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it("renders app with project name", () => {
|
|
28
|
+
vi.mocked(dune.useDune).mockReturnValue({
|
|
29
|
+
sdk: { project: "my-test-project" } as any,
|
|
30
|
+
isLoading: false,
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
render(<App />);
|
|
34
|
+
expect(screen.getByText("<%= displayName %>")).toBeInTheDocument();
|
|
35
|
+
expect(screen.getByText("Project: my-test-project")).toBeInTheDocument();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/src/App.tsx
|
|
3
|
+
---
|
|
4
|
+
import { useDune } from "@cognite/dune";
|
|
5
|
+
|
|
6
|
+
function App() {
|
|
7
|
+
const { sdk, isLoading } = useDune();
|
|
8
|
+
const project = sdk.project;
|
|
9
|
+
|
|
10
|
+
if (isLoading) {
|
|
11
|
+
return <div>Loading...</div>;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div>
|
|
16
|
+
<h1><%= displayName %></h1>
|
|
17
|
+
<p>Project: {project}</p>
|
|
18
|
+
</div>
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export default App;
|
|
23
|
+
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/app.json
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"name": "<%= displayName %>",
|
|
6
|
+
"description": "<%= description %>",
|
|
7
|
+
"externalId": "<%= name %>",
|
|
8
|
+
"versionTag": "0.0.1",
|
|
9
|
+
"deployments": [
|
|
10
|
+
{
|
|
11
|
+
"org": "<%= org %>",
|
|
12
|
+
"project": "<%= project %>",
|
|
13
|
+
"baseUrl": "https://<%= cluster %>.cognitedata.com",
|
|
14
|
+
"published": false,
|
|
15
|
+
"deployClientId": "",
|
|
16
|
+
"deploySecretName": "<%= org %>_<%= project %>_<%= cluster %>"
|
|
17
|
+
}
|
|
18
|
+
]
|
|
19
|
+
}
|
|
20
|
+
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/biome.json
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
|
|
6
|
+
"vcs": {
|
|
7
|
+
"enabled": true,
|
|
8
|
+
"clientKind": "git",
|
|
9
|
+
"useIgnoreFile": true
|
|
10
|
+
},
|
|
11
|
+
"organizeImports": {
|
|
12
|
+
"enabled": true
|
|
13
|
+
},
|
|
14
|
+
"linter": {
|
|
15
|
+
"enabled": true,
|
|
16
|
+
"rules": {
|
|
17
|
+
"recommended": true
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"formatter": {
|
|
21
|
+
"enabled": true,
|
|
22
|
+
"indentStyle": "tab"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/.gitignore
|
|
3
|
+
---
|
|
4
|
+
# Dependencies
|
|
5
|
+
node_modules
|
|
6
|
+
|
|
7
|
+
# Build output
|
|
8
|
+
dist
|
|
9
|
+
|
|
10
|
+
# Environment variables
|
|
11
|
+
.env
|
|
12
|
+
.env.local
|
|
13
|
+
|
|
14
|
+
# Editor directories
|
|
15
|
+
.vscode
|
|
16
|
+
.idea
|
|
17
|
+
|
|
18
|
+
# OS files
|
|
19
|
+
.DS_Store
|
|
20
|
+
Thumbs.db
|
|
21
|
+
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/index.html
|
|
3
|
+
---
|
|
4
|
+
<!DOCTYPE html>
|
|
5
|
+
<html lang="en">
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="UTF-8" />
|
|
8
|
+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
|
9
|
+
<meta
|
|
10
|
+
name="viewport"
|
|
11
|
+
content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
|
12
|
+
/>
|
|
13
|
+
<meta name="theme-color" content="#000000" />
|
|
14
|
+
<meta name="description" content="Cognite Data Fusion Application" />
|
|
15
|
+
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
16
|
+
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
17
|
+
<meta name="apple-mobile-web-app-title" content="CDF Application" />
|
|
18
|
+
<title><%= displayName %></title>
|
|
19
|
+
|
|
20
|
+
<!-- PWA Manifest -->
|
|
21
|
+
<link rel="manifest" href="/manifest.json" />
|
|
22
|
+
|
|
23
|
+
<!-- Fonts -->
|
|
24
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
25
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
26
|
+
<link
|
|
27
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Source+Code+Pro:wght@500&display=swap"
|
|
28
|
+
rel="stylesheet"
|
|
29
|
+
/>
|
|
30
|
+
</head>
|
|
31
|
+
<body>
|
|
32
|
+
<div id="root"></div>
|
|
33
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
34
|
+
</body>
|
|
35
|
+
</html>
|
|
36
|
+
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/src/main.tsx
|
|
3
|
+
---
|
|
4
|
+
import { DuneAuthProvider } from "@cognite/dune";
|
|
5
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
6
|
+
import React from "react";
|
|
7
|
+
import ReactDOM from "react-dom/client";
|
|
8
|
+
import App from "./App.tsx";
|
|
9
|
+
|
|
10
|
+
const queryClient = new QueryClient({
|
|
11
|
+
defaultOptions: {
|
|
12
|
+
queries: {
|
|
13
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
14
|
+
gcTime: 10 * 60 * 1000, // 10 minutes
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
20
|
+
<React.StrictMode>
|
|
21
|
+
<QueryClientProvider client={queryClient}>
|
|
22
|
+
<DuneAuthProvider>
|
|
23
|
+
<App />
|
|
24
|
+
</DuneAuthProvider>
|
|
25
|
+
</QueryClientProvider>
|
|
26
|
+
</React.StrictMode>
|
|
27
|
+
);
|
|
28
|
+
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/package.json
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"name": "<%= name %>",
|
|
6
|
+
"version": "0.0.0",
|
|
7
|
+
"private": true,
|
|
8
|
+
"type": "module",
|
|
9
|
+
"scripts": {
|
|
10
|
+
"start": "vite",
|
|
11
|
+
"dev": "vite",
|
|
12
|
+
"build": "tsc && vite build",
|
|
13
|
+
"preview": "vite preview",
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest",
|
|
16
|
+
"test:ui": "vitest --ui",
|
|
17
|
+
"lint": "biome check .",
|
|
18
|
+
"lint:fix": "biome check --write ."
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@cognite/sdk": "^10.3.0",
|
|
22
|
+
"@cognite/dune": "^0.1.0",
|
|
23
|
+
"@tanstack/react-query": "^5.90.10",
|
|
24
|
+
"react": "^19.2.0",
|
|
25
|
+
"react-dom": "^19.2.0"
|
|
26
|
+
},
|
|
27
|
+
"devDependencies": {
|
|
28
|
+
"@biomejs/biome": "^1.9.4",
|
|
29
|
+
"@testing-library/jest-dom": "^6.6.3",
|
|
30
|
+
"@testing-library/react": "^16.1.0",
|
|
31
|
+
"@testing-library/user-event": "^14.5.2",
|
|
32
|
+
"@types/node": "^24.10.1",
|
|
33
|
+
"@types/react": "^19.2.6",
|
|
34
|
+
"@types/react-dom": "^19.2.3",
|
|
35
|
+
"@vitejs/plugin-react": "^5.1.1",
|
|
36
|
+
"@vitest/ui": "^2.1.8",
|
|
37
|
+
"happy-dom": "^20.0.2",
|
|
38
|
+
"typescript": "^5.0.0",
|
|
39
|
+
"vite": "^7.2.4",
|
|
40
|
+
"vite-plugin-mkcert": "^1.17.9",
|
|
41
|
+
"vitest": "^2.1.8"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
module.exports = [
|
|
2
|
+
{
|
|
3
|
+
type: "input",
|
|
4
|
+
name: "name",
|
|
5
|
+
message: "What is the app name? (use kebab-case, e.g., my-awesome-app)",
|
|
6
|
+
initial: "my-dune-app",
|
|
7
|
+
validate: (input) => {
|
|
8
|
+
if (!input) return "App name is required";
|
|
9
|
+
if (!/^[a-z][a-z0-9-]*$/.test(input)) {
|
|
10
|
+
return "App name must be kebab-case (lowercase, hyphens only)";
|
|
11
|
+
}
|
|
12
|
+
return true;
|
|
13
|
+
},
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
type: "input",
|
|
17
|
+
name: "displayName",
|
|
18
|
+
message: "What is the display name? (e.g., My Awesome App)",
|
|
19
|
+
initial: "My Dune app",
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
type: "input",
|
|
23
|
+
name: "description",
|
|
24
|
+
message: "What is the app description?",
|
|
25
|
+
initial: "A Dune application",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
type: "input",
|
|
29
|
+
name: "org",
|
|
30
|
+
message: "Deployment org? (e.g., cog-demo, cog-atlas)",
|
|
31
|
+
initial: "cog-demo",
|
|
32
|
+
validate: (input) => {
|
|
33
|
+
if (!input) return "Org is required";
|
|
34
|
+
return true;
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "input",
|
|
39
|
+
name: "project",
|
|
40
|
+
message: "Deployment project? (e.g., lervik-industries, atlas-greenfield)",
|
|
41
|
+
initial: "lervik-industries",
|
|
42
|
+
validate: (input) => {
|
|
43
|
+
if (!input) return "Project is required";
|
|
44
|
+
return true;
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
type: "input",
|
|
49
|
+
name: "cluster",
|
|
50
|
+
message: "Cluster/baseUrl? (e.g., greenfield, westeurope-1, api)",
|
|
51
|
+
initial: "api",
|
|
52
|
+
validate: (input) => {
|
|
53
|
+
if (!input) return "Cluster is required";
|
|
54
|
+
return true;
|
|
55
|
+
},
|
|
56
|
+
},
|
|
57
|
+
];
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/tsconfig.json
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"target": "ES2020",
|
|
7
|
+
"useDefineForClassFields": true,
|
|
8
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
9
|
+
"module": "ESNext",
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
|
|
12
|
+
/* Bundler mode */
|
|
13
|
+
"moduleResolution": "bundler",
|
|
14
|
+
"allowImportingTsExtensions": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"moduleDetection": "force",
|
|
17
|
+
"noEmit": true,
|
|
18
|
+
"jsx": "react-jsx",
|
|
19
|
+
|
|
20
|
+
/* Linting */
|
|
21
|
+
"strict": true,
|
|
22
|
+
"noUnusedLocals": true,
|
|
23
|
+
"noUnusedParameters": true,
|
|
24
|
+
"noFallthroughCasesInSwitch": true,
|
|
25
|
+
|
|
26
|
+
/* Testing */
|
|
27
|
+
"types": ["vitest/globals", "@testing-library/jest-dom"],
|
|
28
|
+
"baseUrl": "."
|
|
29
|
+
},
|
|
30
|
+
"include": ["src"],
|
|
31
|
+
"references": [{ "path": "./tsconfig.node.json" }]
|
|
32
|
+
}
|
|
33
|
+
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/tsconfig.node.json
|
|
3
|
+
---
|
|
4
|
+
{
|
|
5
|
+
"compilerOptions": {
|
|
6
|
+
"target": "ES2022",
|
|
7
|
+
"lib": ["ES2023"],
|
|
8
|
+
"module": "ESNext",
|
|
9
|
+
"skipLibCheck": true,
|
|
10
|
+
|
|
11
|
+
/* Bundler mode */
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"isolatedModules": true,
|
|
15
|
+
"moduleDetection": "force",
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
|
|
18
|
+
/* Linting */
|
|
19
|
+
"strict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"noFallthroughCasesInSwitch": true
|
|
23
|
+
},
|
|
24
|
+
"include": ["vite.config.ts", "vitest.config.ts"]
|
|
25
|
+
}
|
|
26
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/vite.config.ts
|
|
3
|
+
---
|
|
4
|
+
import react from "@vitejs/plugin-react";
|
|
5
|
+
import { defineConfig } from "vite";
|
|
6
|
+
import mkcert from "vite-plugin-mkcert";
|
|
7
|
+
|
|
8
|
+
export default defineConfig({
|
|
9
|
+
plugins: [react(), mkcert()],
|
|
10
|
+
server: {
|
|
11
|
+
https: true,
|
|
12
|
+
port: 3000,
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: <%= name %>/vitest.config.ts
|
|
3
|
+
---
|
|
4
|
+
import react from "@vitejs/plugin-react";
|
|
5
|
+
import { defineConfig } from "vitest/config";
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [react()],
|
|
9
|
+
test: {
|
|
10
|
+
globals: true,
|
|
11
|
+
environment: "happy-dom",
|
|
12
|
+
setupFiles: ["./vitest.setup.ts"],
|
|
13
|
+
},
|
|
14
|
+
});
|
|
15
|
+
|
package/bin/cli.js
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { dirname, resolve } from "node:path";
|
|
4
|
+
import { fileURLToPath } from "node:url";
|
|
5
|
+
import { Logger, runner } from "hygen";
|
|
6
|
+
|
|
7
|
+
const defaultTemplates = resolve(dirname(fileURLToPath(import.meta.url)), "..", "_templates");
|
|
8
|
+
|
|
9
|
+
async function main() {
|
|
10
|
+
const args = process.argv.slice(2);
|
|
11
|
+
const command = args[0];
|
|
12
|
+
|
|
13
|
+
// Handle different commands
|
|
14
|
+
if (command === "create" || command === "new" || !command) {
|
|
15
|
+
// Run the app generator
|
|
16
|
+
const hygenArgs = ["app", "new"];
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
const enquirer = await import("enquirer");
|
|
20
|
+
|
|
21
|
+
await runner(hygenArgs, {
|
|
22
|
+
templates: defaultTemplates,
|
|
23
|
+
cwd: process.cwd(),
|
|
24
|
+
logger: new Logger(console.log.bind(console)),
|
|
25
|
+
createPrompter: () => enquirer.default,
|
|
26
|
+
exec: async (action, body) => {
|
|
27
|
+
const { execa } = await import("execa");
|
|
28
|
+
const opts = body && body.length > 0 ? { input: body } : {};
|
|
29
|
+
return execa(action, { shell: true, ...opts });
|
|
30
|
+
},
|
|
31
|
+
debug: !!process.env.DEBUG,
|
|
32
|
+
});
|
|
33
|
+
} catch (error) {
|
|
34
|
+
console.error("Error:", error.message);
|
|
35
|
+
process.exit(1);
|
|
36
|
+
}
|
|
37
|
+
} else if (command === "help" || command === "--help" || command === "-h") {
|
|
38
|
+
console.log(`
|
|
39
|
+
@cognite/dune - Build and deploy React apps to Cognite Data Fusion
|
|
40
|
+
|
|
41
|
+
Usage:
|
|
42
|
+
npx @cognite/dune [command]
|
|
43
|
+
|
|
44
|
+
Commands:
|
|
45
|
+
create, new Create a new Dune application (default)
|
|
46
|
+
help Show this help message
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
npx @cognite/dune # Create a new app (interactive)
|
|
50
|
+
npx @cognite/dune create # Create a new app (interactive)
|
|
51
|
+
|
|
52
|
+
For programmatic usage:
|
|
53
|
+
import { DuneAuthProvider, useDune } from "@cognite/dune/auth"
|
|
54
|
+
import { deploy } from "@cognite/dune/deploy"
|
|
55
|
+
import { fusionOpenPlugin } from "@cognite/dune/vite"
|
|
56
|
+
`);
|
|
57
|
+
} else {
|
|
58
|
+
console.error(`Unknown command: ${command}`);
|
|
59
|
+
console.log('Run "npx @cognite/dune help" for usage information.');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
main();
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as _cognite_sdk from '@cognite/sdk';
|
|
3
|
+
import { CogniteClient } from '@cognite/sdk';
|
|
4
|
+
import React from 'react';
|
|
5
|
+
|
|
6
|
+
declare const DuneAuthProviderContext: React.Context<{
|
|
7
|
+
sdk: CogniteClient;
|
|
8
|
+
isLoading: boolean;
|
|
9
|
+
error?: string;
|
|
10
|
+
}>;
|
|
11
|
+
interface DuneAuthProviderProps {
|
|
12
|
+
children: React.ReactNode;
|
|
13
|
+
useIFrameAuthentication?: boolean;
|
|
14
|
+
useLocalConfiguration?: {
|
|
15
|
+
org: string;
|
|
16
|
+
project: string;
|
|
17
|
+
baseUrl: string;
|
|
18
|
+
};
|
|
19
|
+
loadingComponent?: React.ReactNode;
|
|
20
|
+
errorComponent?: (error: string) => React.ReactNode;
|
|
21
|
+
}
|
|
22
|
+
declare const DuneAuthProvider: ({ children, loadingComponent, errorComponent, }: DuneAuthProviderProps) => react_jsx_runtime.JSX.Element;
|
|
23
|
+
|
|
24
|
+
declare const useDune: () => {
|
|
25
|
+
sdk: _cognite_sdk.CogniteClient;
|
|
26
|
+
isLoading: boolean;
|
|
27
|
+
error?: string;
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
interface CDFConfig {
|
|
31
|
+
project: string;
|
|
32
|
+
baseUrl: string;
|
|
33
|
+
clientId: string;
|
|
34
|
+
clientSecret: string;
|
|
35
|
+
appId?: string;
|
|
36
|
+
}
|
|
37
|
+
declare const getToken: (clientId: string, clientSecret: string) => Promise<any>;
|
|
38
|
+
declare const createCDFSDK: (config: CDFConfig) => Promise<CogniteClient>;
|
|
39
|
+
declare const EMPTY_SDK: CogniteClient;
|
|
40
|
+
|
|
41
|
+
export { type CDFConfig, DuneAuthProvider, DuneAuthProviderContext, type DuneAuthProviderProps, EMPTY_SDK, createCDFSDK, getToken, useDune };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DuneAuthProvider,
|
|
3
|
+
DuneAuthProviderContext,
|
|
4
|
+
EMPTY_SDK,
|
|
5
|
+
createCDFSDK,
|
|
6
|
+
getToken,
|
|
7
|
+
useDune
|
|
8
|
+
} from "../chunk-VIBN7U5H.js";
|
|
9
|
+
export {
|
|
10
|
+
DuneAuthProvider,
|
|
11
|
+
DuneAuthProviderContext,
|
|
12
|
+
EMPTY_SDK,
|
|
13
|
+
createCDFSDK,
|
|
14
|
+
getToken,
|
|
15
|
+
useDune
|
|
16
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
// src/auth/dune-auth-provider.tsx
|
|
2
|
+
import { CogniteClient as CogniteClient2 } from "@cognite/sdk";
|
|
3
|
+
import { createContext, useEffect } from "react";
|
|
4
|
+
import { useState } from "react";
|
|
5
|
+
|
|
6
|
+
// src/auth/utils.ts
|
|
7
|
+
import { CogniteClient } from "@cognite/sdk";
|
|
8
|
+
var getToken = async (clientId, clientSecret) => {
|
|
9
|
+
const header = `Basic ${btoa(`${clientId}:${clientSecret}`)}`;
|
|
10
|
+
const response = await fetch("https://auth.cognite.com/oauth2/token", {
|
|
11
|
+
method: "POST",
|
|
12
|
+
headers: {
|
|
13
|
+
Authorization: header,
|
|
14
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
15
|
+
},
|
|
16
|
+
body: new URLSearchParams({
|
|
17
|
+
grant_type: "client_credentials"
|
|
18
|
+
})
|
|
19
|
+
});
|
|
20
|
+
const data = await response.json();
|
|
21
|
+
return data.access_token;
|
|
22
|
+
};
|
|
23
|
+
var createCDFSDK = async (config) => {
|
|
24
|
+
const { project, baseUrl, clientId, clientSecret, appId = "cdf-authentication-package" } = config;
|
|
25
|
+
if (!project || !baseUrl || !clientId || !clientSecret) {
|
|
26
|
+
throw new Error(
|
|
27
|
+
"Missing required configuration. Please provide: project, baseUrl, clientId, clientSecret"
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
const sdk = new CogniteClient({
|
|
31
|
+
appId,
|
|
32
|
+
project,
|
|
33
|
+
baseUrl,
|
|
34
|
+
oidcTokenProvider: async () => {
|
|
35
|
+
return await getToken(clientId, clientSecret);
|
|
36
|
+
}
|
|
37
|
+
});
|
|
38
|
+
await sdk.authenticate();
|
|
39
|
+
return sdk;
|
|
40
|
+
};
|
|
41
|
+
var EMPTY_SDK = new CogniteClient({
|
|
42
|
+
appId: "cdf-authentication-package",
|
|
43
|
+
project: "",
|
|
44
|
+
oidcTokenProvider: async () => ""
|
|
45
|
+
});
|
|
46
|
+
var requestCredentials = () => {
|
|
47
|
+
console.log("\u{1F511} Requesting credentials from parent...");
|
|
48
|
+
if (window.parent && window.parent !== window) {
|
|
49
|
+
window.parent.postMessage({ type: "REQUEST_CREDENTIALS" }, "*");
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
var handleCredentialsResponse = (event) => {
|
|
53
|
+
if (event.data?.type === "PROVIDE_CREDENTIALS" && event.data?.credentials) {
|
|
54
|
+
const creds = event.data.credentials;
|
|
55
|
+
if (creds.token && creds.baseUrl && creds.project) {
|
|
56
|
+
console.log("\u{1F389} useCredentials received credentials:", {
|
|
57
|
+
hasToken: !!creds.token,
|
|
58
|
+
tokenLength: creds.token?.length || 0,
|
|
59
|
+
project: creds.project,
|
|
60
|
+
baseUrl: creds.baseUrl
|
|
61
|
+
});
|
|
62
|
+
return creds;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
// src/auth/dune-auth-provider.tsx
|
|
68
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
69
|
+
var DuneAuthProviderContext = createContext({
|
|
70
|
+
sdk: EMPTY_SDK,
|
|
71
|
+
isLoading: false
|
|
72
|
+
});
|
|
73
|
+
var DuneAuthProvider = ({
|
|
74
|
+
children,
|
|
75
|
+
loadingComponent = /* @__PURE__ */ jsx("div", { children: "Loading CDF authentication..." }),
|
|
76
|
+
errorComponent = (error) => /* @__PURE__ */ jsxs("div", { children: [
|
|
77
|
+
"Authentication error: ",
|
|
78
|
+
error
|
|
79
|
+
] })
|
|
80
|
+
}) => {
|
|
81
|
+
return /* @__PURE__ */ jsx(
|
|
82
|
+
FusionIframeAuthenticationInnerProvider,
|
|
83
|
+
{
|
|
84
|
+
loadingComponent,
|
|
85
|
+
errorComponent,
|
|
86
|
+
children
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
};
|
|
90
|
+
var FusionIframeAuthenticationInnerProvider = ({
|
|
91
|
+
children,
|
|
92
|
+
loadingComponent = /* @__PURE__ */ jsx("div", { children: "Loading CDF authentication..." }),
|
|
93
|
+
errorComponent = (error) => /* @__PURE__ */ jsxs("div", { children: [
|
|
94
|
+
"Authentication error: ",
|
|
95
|
+
error
|
|
96
|
+
] })
|
|
97
|
+
}) => {
|
|
98
|
+
const [isLoading, setIsLoading] = useState(true);
|
|
99
|
+
const [sdk, setSdk] = useState(EMPTY_SDK);
|
|
100
|
+
const [error] = useState();
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
requestCredentials();
|
|
103
|
+
const handleMessage = async (event) => {
|
|
104
|
+
console.log("\u{1F50D} Handling message from Fusion");
|
|
105
|
+
const credentials = handleCredentialsResponse(event);
|
|
106
|
+
if (!credentials) {
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
const sdk2 = new CogniteClient2({
|
|
110
|
+
appId: "dune-app",
|
|
111
|
+
project: credentials.project,
|
|
112
|
+
baseUrl: credentials.baseUrl,
|
|
113
|
+
oidcTokenProvider: async () => {
|
|
114
|
+
return credentials.token;
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
await sdk2.authenticate();
|
|
118
|
+
setSdk(sdk2);
|
|
119
|
+
setIsLoading(false);
|
|
120
|
+
};
|
|
121
|
+
console.log("\u{1F50D} Adding message listener");
|
|
122
|
+
window.addEventListener("message", handleMessage);
|
|
123
|
+
return () => window.removeEventListener("message", handleMessage);
|
|
124
|
+
}, []);
|
|
125
|
+
console.log("\u{1F50D} CDFIframeAuthenticationInnerProvider", sdk, isLoading, error);
|
|
126
|
+
if (error && errorComponent) {
|
|
127
|
+
return /* @__PURE__ */ jsx(Fragment, { children: errorComponent(error) });
|
|
128
|
+
}
|
|
129
|
+
if (isLoading && loadingComponent) {
|
|
130
|
+
return /* @__PURE__ */ jsx(Fragment, { children: loadingComponent });
|
|
131
|
+
}
|
|
132
|
+
return /* @__PURE__ */ jsx(DuneAuthProviderContext.Provider, { value: { sdk, isLoading, error }, children });
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
// src/auth/use-dune.ts
|
|
136
|
+
import { useContext } from "react";
|
|
137
|
+
var useDune = () => {
|
|
138
|
+
const context = useContext(DuneAuthProviderContext);
|
|
139
|
+
if (!context) {
|
|
140
|
+
throw new Error("useDune must be used within a DuneAuthProvider");
|
|
141
|
+
}
|
|
142
|
+
return context;
|
|
143
|
+
};
|
|
144
|
+
|
|
145
|
+
export {
|
|
146
|
+
getToken,
|
|
147
|
+
createCDFSDK,
|
|
148
|
+
EMPTY_SDK,
|
|
149
|
+
DuneAuthProviderContext,
|
|
150
|
+
DuneAuthProvider,
|
|
151
|
+
useDune
|
|
152
|
+
};
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { CogniteClient } from '@cognite/sdk';
|
|
2
|
+
|
|
3
|
+
type Deployment = {
|
|
4
|
+
org: string;
|
|
5
|
+
project: string;
|
|
6
|
+
baseUrl: string;
|
|
7
|
+
deployClientId: string;
|
|
8
|
+
deploySecretName: string;
|
|
9
|
+
published: boolean;
|
|
10
|
+
};
|
|
11
|
+
type App = {
|
|
12
|
+
externalId: string;
|
|
13
|
+
name: string;
|
|
14
|
+
description: string;
|
|
15
|
+
versionTag: string;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
declare const deploy: (deployment: Deployment, app: App, folder: string) => Promise<void>;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* CDF Application Deployment
|
|
22
|
+
*
|
|
23
|
+
* Handles deployment of packaged applications to CDF.
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
declare class CdfApplicationDeployer {
|
|
27
|
+
private client;
|
|
28
|
+
/**
|
|
29
|
+
* @param {CogniteClient} client - Cognite SDK client
|
|
30
|
+
*/
|
|
31
|
+
constructor(client: CogniteClient);
|
|
32
|
+
/**
|
|
33
|
+
* Upload application package to CDF Files API
|
|
34
|
+
* @param {string} appExternalId - Application external ID
|
|
35
|
+
* @param {string} name - Application name
|
|
36
|
+
* @param {string} description - Application description
|
|
37
|
+
* @param {string} versionTag - Version tag
|
|
38
|
+
* @param {string} zipFilename - Path to zip file
|
|
39
|
+
* @param {boolean} published - Whether the application should be published
|
|
40
|
+
*/
|
|
41
|
+
uploadToFilesApi(appExternalId: string, name: string, description: string, versionTag: string, zipFilename: string, published?: boolean): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Execute complete deployment to CDF
|
|
44
|
+
* @param {string} appExternalId - Application external ID
|
|
45
|
+
* @param {string} name - Application name
|
|
46
|
+
* @param {string} description - Application description
|
|
47
|
+
* @param {string} versionTag - Version tag
|
|
48
|
+
* @param {string} zipFilename - Path to zip file
|
|
49
|
+
* @param {boolean} published - Whether the application should be published
|
|
50
|
+
*/
|
|
51
|
+
deploy(appExternalId: string, name: string, description: string, versionTag: string, zipFilename: string, published?: boolean): Promise<void>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Application Packaging
|
|
56
|
+
*
|
|
57
|
+
* Handles packaging of build directories into deployment-ready zip files.
|
|
58
|
+
*/
|
|
59
|
+
declare class ApplicationPackager {
|
|
60
|
+
private distPath;
|
|
61
|
+
/**
|
|
62
|
+
* @param {string} distDirectory - Build directory to package (can be relative or absolute)
|
|
63
|
+
*/
|
|
64
|
+
constructor(distDirectory?: string);
|
|
65
|
+
/**
|
|
66
|
+
* Validate that build directory exists
|
|
67
|
+
* @throws {Error} If build directory not found
|
|
68
|
+
*/
|
|
69
|
+
validateBuildDirectory(): void;
|
|
70
|
+
/**
|
|
71
|
+
* Create zip file from build directory
|
|
72
|
+
* @param {string} outputFilename - Output zip filename
|
|
73
|
+
* @param {boolean} verbose - Enable verbose logging
|
|
74
|
+
* @returns {Promise<string>} Path to created zip file
|
|
75
|
+
*/
|
|
76
|
+
createZip(outputFilename?: string, verbose?: boolean): Promise<string>;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
declare const getSdk: (deployment: Deployment, folder: string) => Promise<CogniteClient>;
|
|
80
|
+
|
|
81
|
+
declare const getToken: (deployClientId: string, deploySecretName: string) => Promise<any>;
|
|
82
|
+
|
|
83
|
+
export { type App, ApplicationPackager, CdfApplicationDeployer, type Deployment, deploy, getSdk, getToken };
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
// src/deploy/application-deployer.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
var CdfApplicationDeployer = class {
|
|
4
|
+
/**
|
|
5
|
+
* @param {CogniteClient} client - Cognite SDK client
|
|
6
|
+
*/
|
|
7
|
+
constructor(client) {
|
|
8
|
+
this.client = client;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Upload application package to CDF Files API
|
|
12
|
+
* @param {string} appExternalId - Application external ID
|
|
13
|
+
* @param {string} name - Application name
|
|
14
|
+
* @param {string} description - Application description
|
|
15
|
+
* @param {string} versionTag - Version tag
|
|
16
|
+
* @param {string} zipFilename - Path to zip file
|
|
17
|
+
* @param {boolean} published - Whether the application should be published
|
|
18
|
+
*/
|
|
19
|
+
async uploadToFilesApi(appExternalId, name, description, versionTag, zipFilename, published = false) {
|
|
20
|
+
console.log("\u{1F4C1} Creating file record...");
|
|
21
|
+
const fileContent = fs.readFileSync(zipFilename);
|
|
22
|
+
const metadata = {
|
|
23
|
+
published: String(published),
|
|
24
|
+
name,
|
|
25
|
+
description,
|
|
26
|
+
externalId: `${appExternalId}-${versionTag}`,
|
|
27
|
+
version: versionTag
|
|
28
|
+
};
|
|
29
|
+
await this.client.files.upload(
|
|
30
|
+
{
|
|
31
|
+
name: `${appExternalId}-${versionTag}.zip`,
|
|
32
|
+
externalId: `${appExternalId}-${versionTag}`,
|
|
33
|
+
directory: "/dune-apps",
|
|
34
|
+
metadata
|
|
35
|
+
},
|
|
36
|
+
fileContent,
|
|
37
|
+
true,
|
|
38
|
+
// overwrite
|
|
39
|
+
true
|
|
40
|
+
// waitUntilAcknowledged
|
|
41
|
+
);
|
|
42
|
+
console.log("\u2705 File record created");
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Execute complete deployment to CDF
|
|
46
|
+
* @param {string} appExternalId - Application external ID
|
|
47
|
+
* @param {string} name - Application name
|
|
48
|
+
* @param {string} description - Application description
|
|
49
|
+
* @param {string} versionTag - Version tag
|
|
50
|
+
* @param {string} zipFilename - Path to zip file
|
|
51
|
+
* @param {boolean} published - Whether the application should be published
|
|
52
|
+
*/
|
|
53
|
+
async deploy(appExternalId, name, description, versionTag, zipFilename, published = false) {
|
|
54
|
+
console.log("\n\u{1F680} Deploying application to CDF...\n");
|
|
55
|
+
try {
|
|
56
|
+
await this.uploadToFilesApi(
|
|
57
|
+
appExternalId,
|
|
58
|
+
name,
|
|
59
|
+
description,
|
|
60
|
+
versionTag,
|
|
61
|
+
zipFilename,
|
|
62
|
+
published
|
|
63
|
+
);
|
|
64
|
+
console.log("\n\u2705 Deployment successful!");
|
|
65
|
+
} catch (error) {
|
|
66
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
67
|
+
throw new Error(`Deployment failed: ${message}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// src/deploy/application-packager.ts
|
|
73
|
+
import fs2 from "fs";
|
|
74
|
+
import path from "path";
|
|
75
|
+
import archiver from "archiver";
|
|
76
|
+
var ApplicationPackager = class {
|
|
77
|
+
/**
|
|
78
|
+
* @param {string} distDirectory - Build directory to package (can be relative or absolute)
|
|
79
|
+
*/
|
|
80
|
+
constructor(distDirectory = "dist") {
|
|
81
|
+
this.distPath = path.isAbsolute(distDirectory) ? distDirectory : path.join(process.cwd(), distDirectory);
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Validate that build directory exists
|
|
85
|
+
* @throws {Error} If build directory not found
|
|
86
|
+
*/
|
|
87
|
+
validateBuildDirectory() {
|
|
88
|
+
if (!fs2.existsSync(this.distPath)) {
|
|
89
|
+
throw new Error(`Build directory "${this.distPath}" not found. Run build first.`);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Create zip file from build directory
|
|
94
|
+
* @param {string} outputFilename - Output zip filename
|
|
95
|
+
* @param {boolean} verbose - Enable verbose logging
|
|
96
|
+
* @returns {Promise<string>} Path to created zip file
|
|
97
|
+
*/
|
|
98
|
+
async createZip(outputFilename = "app.zip", verbose = false) {
|
|
99
|
+
this.validateBuildDirectory();
|
|
100
|
+
console.log("\u{1F4E6} Packaging application...");
|
|
101
|
+
return new Promise((resolve, reject) => {
|
|
102
|
+
const output = fs2.createWriteStream(outputFilename);
|
|
103
|
+
const archive = archiver("zip", {
|
|
104
|
+
zlib: { level: 9 }
|
|
105
|
+
// Maximum compression
|
|
106
|
+
});
|
|
107
|
+
output.on("close", () => {
|
|
108
|
+
const sizeMB = (archive.pointer() / 1024 / 1024).toFixed(2);
|
|
109
|
+
console.log(`\u2705 App packaged: ${outputFilename} (${sizeMB} MB)`);
|
|
110
|
+
resolve(outputFilename);
|
|
111
|
+
});
|
|
112
|
+
archive.on("error", (err) => {
|
|
113
|
+
reject(new Error(`Failed to create zip: ${err.message}`));
|
|
114
|
+
});
|
|
115
|
+
if (verbose) {
|
|
116
|
+
archive.on("entry", (entry) => {
|
|
117
|
+
console.log(` \u{1F4C4} ${entry.name}`);
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
archive.pipe(output);
|
|
121
|
+
archive.directory(this.distPath, false);
|
|
122
|
+
archive.finalize();
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
|
|
127
|
+
// src/deploy/get-sdk.ts
|
|
128
|
+
import { CogniteClient } from "@cognite/sdk";
|
|
129
|
+
|
|
130
|
+
// src/deploy/login.ts
|
|
131
|
+
var loadSecretsFromEnv = () => {
|
|
132
|
+
const secretsJson = process.env.DEPLOYMENT_SECRETS;
|
|
133
|
+
if (!secretsJson) {
|
|
134
|
+
return {};
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const secrets = JSON.parse(secretsJson);
|
|
138
|
+
const normalizedSecrets = {};
|
|
139
|
+
for (const [key, value] of Object.entries(secrets)) {
|
|
140
|
+
if (typeof value === "string") {
|
|
141
|
+
const normalizedKey = key.toLowerCase().replace(/_/g, "-");
|
|
142
|
+
normalizedSecrets[normalizedKey] = value;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return normalizedSecrets;
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error("Error parsing DEPLOYMENT_SECRETS:", error);
|
|
148
|
+
return {};
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
var getToken = async (deployClientId, deploySecretName) => {
|
|
152
|
+
let deploySecret;
|
|
153
|
+
if (process.env.DEPLOYMENT_SECRET) {
|
|
154
|
+
deploySecret = process.env.DEPLOYMENT_SECRET;
|
|
155
|
+
}
|
|
156
|
+
if (!deploySecret) {
|
|
157
|
+
const secrets = loadSecretsFromEnv();
|
|
158
|
+
deploySecret = secrets[deploySecretName];
|
|
159
|
+
}
|
|
160
|
+
if (!deploySecret) {
|
|
161
|
+
deploySecret = process.env[deploySecretName];
|
|
162
|
+
}
|
|
163
|
+
if (!deploySecret) {
|
|
164
|
+
throw new Error(`Deployment secret not found in environment: ${deploySecretName}`);
|
|
165
|
+
}
|
|
166
|
+
const header = `Basic ${btoa(`${deployClientId}:${deploySecret}`)}`;
|
|
167
|
+
const response = await fetch("https://auth.cognite.com/oauth2/token", {
|
|
168
|
+
method: "POST",
|
|
169
|
+
headers: {
|
|
170
|
+
Authorization: header,
|
|
171
|
+
"Content-Type": "application/x-www-form-urlencoded"
|
|
172
|
+
},
|
|
173
|
+
body: new URLSearchParams({ grant_type: "client_credentials" })
|
|
174
|
+
});
|
|
175
|
+
if (!response.ok) {
|
|
176
|
+
throw new Error(`Failed to get token: ${response.status} ${response.statusText}`);
|
|
177
|
+
}
|
|
178
|
+
const data = await response.json();
|
|
179
|
+
return data.access_token;
|
|
180
|
+
};
|
|
181
|
+
|
|
182
|
+
// src/deploy/get-sdk.ts
|
|
183
|
+
var getSdk = async (deployment, folder) => {
|
|
184
|
+
const token = await getToken(deployment.deployClientId, deployment.deploySecretName);
|
|
185
|
+
const sdk = new CogniteClient({
|
|
186
|
+
appId: folder,
|
|
187
|
+
project: deployment.project,
|
|
188
|
+
baseUrl: deployment.baseUrl,
|
|
189
|
+
oidcTokenProvider: async () => {
|
|
190
|
+
return token;
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
await sdk.authenticate();
|
|
194
|
+
return sdk;
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
// src/deploy/deploy.ts
|
|
198
|
+
var deploy = async (deployment, app, folder) => {
|
|
199
|
+
const sdk = await getSdk(deployment, folder);
|
|
200
|
+
const distPath = `${folder}/dist`;
|
|
201
|
+
const packager = new ApplicationPackager(distPath);
|
|
202
|
+
const zipFilename = await packager.createZip("app.zip", true);
|
|
203
|
+
const deployer = new CdfApplicationDeployer(sdk);
|
|
204
|
+
await deployer.deploy(
|
|
205
|
+
app.externalId,
|
|
206
|
+
app.name,
|
|
207
|
+
app.description,
|
|
208
|
+
app.versionTag,
|
|
209
|
+
zipFilename,
|
|
210
|
+
deployment.published
|
|
211
|
+
);
|
|
212
|
+
};
|
|
213
|
+
export {
|
|
214
|
+
ApplicationPackager,
|
|
215
|
+
CdfApplicationDeployer,
|
|
216
|
+
deploy,
|
|
217
|
+
getSdk,
|
|
218
|
+
getToken
|
|
219
|
+
};
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import {
|
|
2
|
+
DuneAuthProvider,
|
|
3
|
+
DuneAuthProviderContext,
|
|
4
|
+
EMPTY_SDK,
|
|
5
|
+
createCDFSDK,
|
|
6
|
+
getToken,
|
|
7
|
+
useDune
|
|
8
|
+
} from "./chunk-VIBN7U5H.js";
|
|
9
|
+
export {
|
|
10
|
+
DuneAuthProvider,
|
|
11
|
+
DuneAuthProviderContext,
|
|
12
|
+
EMPTY_SDK,
|
|
13
|
+
createCDFSDK,
|
|
14
|
+
getToken,
|
|
15
|
+
useDune
|
|
16
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
interface ViteDevServer {
|
|
2
|
+
httpServer?: {
|
|
3
|
+
address: () => {
|
|
4
|
+
port: number;
|
|
5
|
+
} | string | null;
|
|
6
|
+
on: (event: string, callback: () => void) => void;
|
|
7
|
+
} | null;
|
|
8
|
+
}
|
|
9
|
+
declare const fusionOpenPlugin: () => {
|
|
10
|
+
name: string;
|
|
11
|
+
configureServer(server: ViteDevServer): void;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
export { fusionOpenPlugin };
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// src/vite/fusion-open-plugin.ts
|
|
2
|
+
import { exec } from "child_process";
|
|
3
|
+
import fs from "fs";
|
|
4
|
+
import path from "path";
|
|
5
|
+
var openUrl = (url) => {
|
|
6
|
+
const start = process.platform === "darwin" ? "open" : process.platform === "win32" ? "start" : "xdg-open";
|
|
7
|
+
if (process.platform === "win32") {
|
|
8
|
+
exec(`start "" "${url}"`);
|
|
9
|
+
} else {
|
|
10
|
+
exec(`${start} "${url}"`);
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
var fusionOpenPlugin = () => {
|
|
14
|
+
return {
|
|
15
|
+
name: "fusion-open",
|
|
16
|
+
configureServer(server) {
|
|
17
|
+
server.httpServer?.on("listening", () => {
|
|
18
|
+
const address = server.httpServer?.address();
|
|
19
|
+
const port = address && typeof address === "object" ? address.port : 3e3;
|
|
20
|
+
const appJsonPath = path.join(process.cwd(), "app.json");
|
|
21
|
+
if (fs.existsSync(appJsonPath)) {
|
|
22
|
+
try {
|
|
23
|
+
const appJson = JSON.parse(fs.readFileSync(appJsonPath, "utf-8"));
|
|
24
|
+
const firstDeployment = appJson.deployments?.[0];
|
|
25
|
+
const { org, project, baseUrl } = firstDeployment || {};
|
|
26
|
+
const parsedBaseUrl = baseUrl?.split("//")[1];
|
|
27
|
+
if (org && project && baseUrl) {
|
|
28
|
+
const fusionUrl = `https://${org}.fusion.cognite.com/${project}/streamlit-apps/dune/development/${port}?cluster=${parsedBaseUrl}&workspace=industrial-tools`;
|
|
29
|
+
openUrl(fusionUrl);
|
|
30
|
+
}
|
|
31
|
+
} catch (error) {
|
|
32
|
+
console.warn("Failed to read app.json for Fusion URL", error);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
export {
|
|
40
|
+
fusionOpenPlugin
|
|
41
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@cognite/dune",
|
|
3
|
+
"version": "0.1.0",
|
|
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
|
+
"license": "Apache-2.0",
|
|
15
|
+
"author": "Cognite",
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "https://github.com/cognitedata/dune.git",
|
|
19
|
+
"directory": "packages/dune"
|
|
20
|
+
},
|
|
21
|
+
"type": "module",
|
|
22
|
+
"main": "./dist/index.js",
|
|
23
|
+
"types": "./dist/index.d.ts",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./src/index.ts",
|
|
27
|
+
"development": "./src/index.ts",
|
|
28
|
+
"default": "./dist/index.js"
|
|
29
|
+
},
|
|
30
|
+
"./auth": {
|
|
31
|
+
"types": "./src/auth/index.ts",
|
|
32
|
+
"development": "./src/auth/index.ts",
|
|
33
|
+
"default": "./dist/auth/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./deploy": {
|
|
36
|
+
"types": "./src/deploy/index.ts",
|
|
37
|
+
"development": "./src/deploy/index.ts",
|
|
38
|
+
"default": "./dist/deploy/index.js"
|
|
39
|
+
},
|
|
40
|
+
"./vite": {
|
|
41
|
+
"types": "./src/vite/index.ts",
|
|
42
|
+
"development": "./src/vite/index.ts",
|
|
43
|
+
"default": "./dist/vite/index.js"
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
"bin": {
|
|
47
|
+
"dune": "./bin/cli.js"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"bin",
|
|
51
|
+
"dist",
|
|
52
|
+
"_templates"
|
|
53
|
+
],
|
|
54
|
+
"dependencies": {
|
|
55
|
+
"archiver": "^7.0.1",
|
|
56
|
+
"enquirer": "^2.4.1",
|
|
57
|
+
"execa": "^5.1.1",
|
|
58
|
+
"hygen": "^6.2.11"
|
|
59
|
+
},
|
|
60
|
+
"peerDependencies": {
|
|
61
|
+
"@cognite/sdk": ">=9.0.0",
|
|
62
|
+
"react": ">=18.0.0",
|
|
63
|
+
"react-dom": ">=18.0.0"
|
|
64
|
+
},
|
|
65
|
+
"peerDependenciesMeta": {
|
|
66
|
+
"@cognite/sdk": {
|
|
67
|
+
"optional": true
|
|
68
|
+
},
|
|
69
|
+
"react": {
|
|
70
|
+
"optional": true
|
|
71
|
+
},
|
|
72
|
+
"react-dom": {
|
|
73
|
+
"optional": true
|
|
74
|
+
}
|
|
75
|
+
},
|
|
76
|
+
"devDependencies": {
|
|
77
|
+
"@cognite/sdk": "^10.3.0",
|
|
78
|
+
"@types/archiver": "^7.0.0",
|
|
79
|
+
"@types/node": "^24.10.1",
|
|
80
|
+
"@types/react": "^19.2.6",
|
|
81
|
+
"@types/react-dom": "^19.2.3",
|
|
82
|
+
"react": "^19.2.0",
|
|
83
|
+
"react-dom": "^19.2.0",
|
|
84
|
+
"tsup": "^8.4.0",
|
|
85
|
+
"typescript": "^5.0.0"
|
|
86
|
+
},
|
|
87
|
+
"engines": {
|
|
88
|
+
"node": ">=18"
|
|
89
|
+
},
|
|
90
|
+
"scripts": {
|
|
91
|
+
"build": "tsup"
|
|
92
|
+
}
|
|
93
|
+
}
|