@cognite/dune 0.3.1 → 0.3.3
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/config/eslint.config.mjs.ejs.t +96 -0
- package/_templates/app/new/config/tailwind.config.js.ejs.t +1 -5
- package/_templates/app/new/config/vite.config.ts.ejs.t +9 -10
- package/_templates/app/new/config/vitest.config.ts.ejs.t +4 -5
- package/_templates/app/new/config/vitest.setup.ts.ejs.t +1 -2
- package/_templates/app/new/cursor/mcp.json.ejs.t +0 -5
- package/_templates/app/new/cursor/rules.mdc.ejs.t +1 -2
- package/_templates/app/new/prompt.js +29 -29
- package/_templates/app/new/root/index.html.ejs.t +3 -3
- package/_templates/app/new/root/package.json.ejs.t +11 -5
- package/_templates/app/new/src/App.test.tsx.ejs.t +32 -20
- package/_templates/app/new/src/App.tsx.ejs.t +118 -7
- package/_templates/app/new/src/lib/utils.ts.ejs.t +2 -3
- package/_templates/app/new/src/main.tsx.ejs.t +8 -8
- package/_templates/app/new/src/styles.css.ejs.t +5 -19
- package/bin/auth/authentication-flow.js +16 -14
- package/bin/auth/callback-server.js +23 -23
- package/bin/auth/certificate-manager.js +13 -13
- package/bin/auth/client-credentials.js +31 -32
- package/bin/auth/oauth-client.js +7 -7
- package/bin/cli.js +31 -30
- package/bin/deploy-command.js +32 -32
- package/bin/deploy-interactive-command.js +73 -73
- package/bin/skills-command.js +28 -28
- package/bin/utils/crypto.js +7 -8
- package/dist/auth/index.d.ts +10 -13
- package/dist/auth/index.js +1 -1
- package/dist/{chunk-VIBN7U5H.js → chunk-53VTKDSC.js} +1 -2
- package/dist/deploy/index.d.ts +9 -1
- package/dist/deploy/index.js +89 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/vite/index.d.ts +1 -0
- package/dist/vite/index.js +5 -2
- package/package.json +1 -1
- package/src/auth/dune-auth-provider.tsx +17 -16
- package/src/auth/index.ts +5 -5
- package/src/auth/use-dune.ts +5 -4
- package/src/auth/utils.ts +18 -18
- package/src/deploy/application-deployer.ts +12 -11
- package/src/deploy/application-packager.ts +11 -10
- package/src/deploy/deploy.ts +7 -6
- package/src/deploy/get-sdk.ts +5 -4
- package/src/deploy/index.ts +6 -6
- package/src/deploy/login.test.ts +49 -0
- package/src/deploy/login.ts +134 -11
- package/src/deploy/types.ts +4 -0
- package/src/index.ts +1 -1
- package/src/vite/fusion-open-plugin.ts +17 -15
- package/src/vite/index.ts +1 -1
- package/_templates/app/new/config/biome.json.ejs.t +0 -54
- package/_templates/app/new/config/components.json.ejs.t +0 -28
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
---
|
|
2
|
+
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>eslint.config.mjs'
|
|
3
|
+
---
|
|
4
|
+
import js from '@eslint/js';
|
|
5
|
+
import importPlugin from 'eslint-plugin-import';
|
|
6
|
+
import noOnlyTestsPlugin from 'eslint-plugin-no-only-tests';
|
|
7
|
+
import reactHooks from 'eslint-plugin-react-hooks';
|
|
8
|
+
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
9
|
+
import globals from 'globals';
|
|
10
|
+
import tseslint from 'typescript-eslint';
|
|
11
|
+
|
|
12
|
+
const sharedRules = {
|
|
13
|
+
'import/first': 'error',
|
|
14
|
+
'import/no-duplicates': 'error',
|
|
15
|
+
'import/order': [
|
|
16
|
+
'error',
|
|
17
|
+
{
|
|
18
|
+
groups: ['builtin', 'external', 'internal', 'parent', ['sibling', 'index']],
|
|
19
|
+
'newlines-between': 'always',
|
|
20
|
+
alphabetize: {
|
|
21
|
+
order: 'asc',
|
|
22
|
+
caseInsensitive: true,
|
|
23
|
+
},
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
'no-only-tests/no-only-tests': 'error',
|
|
27
|
+
quotes: ['error', 'single', { avoidEscape: true }],
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
const noUnusedVarsOptions = {
|
|
31
|
+
argsIgnorePattern: '^_',
|
|
32
|
+
caughtErrorsIgnorePattern: '^_',
|
|
33
|
+
varsIgnorePattern: '^_',
|
|
34
|
+
ignoreRestSiblings: true,
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default tseslint.config(
|
|
38
|
+
{
|
|
39
|
+
ignores: ['dist', 'build', '.next', 'coverage', '*.min.js'],
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
files: ['**/*.{js,mjs,cjs,ts,tsx}'],
|
|
43
|
+
plugins: {
|
|
44
|
+
import: importPlugin,
|
|
45
|
+
'no-only-tests': noOnlyTestsPlugin,
|
|
46
|
+
},
|
|
47
|
+
rules: sharedRules,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
files: ['**/*.{js,mjs,cjs}'],
|
|
51
|
+
extends: [js.configs.recommended],
|
|
52
|
+
languageOptions: {
|
|
53
|
+
ecmaVersion: 'latest',
|
|
54
|
+
sourceType: 'module',
|
|
55
|
+
globals: {
|
|
56
|
+
...globals.browser,
|
|
57
|
+
...globals.node,
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
rules: {
|
|
61
|
+
'no-unused-vars': ['error', noUnusedVarsOptions],
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
files: ['**/*.cjs'],
|
|
66
|
+
languageOptions: {
|
|
67
|
+
sourceType: 'commonjs',
|
|
68
|
+
globals: {
|
|
69
|
+
...globals.node,
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
files: ['**/*.{ts,tsx}'],
|
|
75
|
+
extends: [js.configs.recommended, ...tseslint.configs.recommended],
|
|
76
|
+
languageOptions: {
|
|
77
|
+
ecmaVersion: 'latest',
|
|
78
|
+
globals: {
|
|
79
|
+
...globals.browser,
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
plugins: {
|
|
83
|
+
'react-hooks': reactHooks,
|
|
84
|
+
'react-refresh': reactRefresh,
|
|
85
|
+
},
|
|
86
|
+
rules: {
|
|
87
|
+
...reactHooks.configs.recommended.rules,
|
|
88
|
+
'@typescript-eslint/consistent-type-imports': 'error',
|
|
89
|
+
'@typescript-eslint/no-explicit-any': 'error',
|
|
90
|
+
'@typescript-eslint/no-non-null-assertion': 'off',
|
|
91
|
+
'@typescript-eslint/no-unused-vars': ['error', noUnusedVarsOptions],
|
|
92
|
+
'no-unused-vars': 'off',
|
|
93
|
+
'react-refresh/only-export-components': ['error', { allowConstantExport: true }],
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
);
|
|
@@ -3,13 +3,9 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>tailwind.config.
|
|
|
3
3
|
---
|
|
4
4
|
/** @type {import('tailwindcss').Config} */
|
|
5
5
|
export default {
|
|
6
|
-
content: [
|
|
6
|
+
content: ['./index.html', './src/**/*.{js,ts,jsx,tsx}'],
|
|
7
7
|
theme: {
|
|
8
8
|
extend: {},
|
|
9
9
|
},
|
|
10
10
|
plugins: [],
|
|
11
|
-
registries: {
|
|
12
|
-
"@aura": "https://cognitedata.github.io/aura/r/{name}.json",
|
|
13
|
-
},
|
|
14
11
|
};
|
|
15
|
-
|
|
@@ -1,27 +1,26 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>vite.config.ts'
|
|
3
3
|
---
|
|
4
|
-
import path from
|
|
5
|
-
import react from "@vitejs/plugin-react";
|
|
6
|
-
import tailwindcss from "@tailwindcss/vite";
|
|
7
|
-
import { defineConfig } from "vite";
|
|
8
|
-
import mkcert from "vite-plugin-mkcert";
|
|
4
|
+
import path from 'node:path';
|
|
9
5
|
|
|
10
|
-
import { fusionOpenPlugin } from
|
|
6
|
+
import { fusionOpenPlugin } from '@cognite/dune/vite';
|
|
7
|
+
import tailwindcss from '@tailwindcss/vite';
|
|
8
|
+
import react from '@vitejs/plugin-react';
|
|
9
|
+
import { defineConfig } from 'vite';
|
|
10
|
+
import mkcert from 'vite-plugin-mkcert';
|
|
11
11
|
|
|
12
12
|
export default defineConfig({
|
|
13
|
-
base:
|
|
13
|
+
base: './',
|
|
14
14
|
plugins: [react(), mkcert(), fusionOpenPlugin(), tailwindcss()],
|
|
15
15
|
resolve: {
|
|
16
16
|
alias: {
|
|
17
|
-
|
|
17
|
+
'@': path.resolve(__dirname, './src'),
|
|
18
18
|
},
|
|
19
19
|
},
|
|
20
20
|
server: {
|
|
21
21
|
port: 3001,
|
|
22
22
|
},
|
|
23
23
|
worker: {
|
|
24
|
-
format:
|
|
24
|
+
format: 'es',
|
|
25
25
|
},
|
|
26
26
|
});
|
|
27
|
-
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>vitest.config.ts'
|
|
3
3
|
---
|
|
4
|
-
import react from
|
|
5
|
-
import { defineConfig } from
|
|
4
|
+
import react from '@vitejs/plugin-react';
|
|
5
|
+
import { defineConfig } from 'vitest/config';
|
|
6
6
|
|
|
7
7
|
export default defineConfig({
|
|
8
8
|
plugins: [react()],
|
|
9
9
|
test: {
|
|
10
10
|
globals: true,
|
|
11
|
-
environment:
|
|
12
|
-
setupFiles: [
|
|
11
|
+
environment: 'happy-dom',
|
|
12
|
+
setupFiles: ['./vitest.setup.ts'],
|
|
13
13
|
},
|
|
14
14
|
});
|
|
15
|
-
|
|
@@ -3,13 +3,8 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>.cursor/mcp.json
|
|
|
3
3
|
---
|
|
4
4
|
{
|
|
5
5
|
"mcpServers": {
|
|
6
|
-
"shadcn": {
|
|
7
|
-
"command": "npx",
|
|
8
|
-
"args": ["shadcn@latest", "mcp"]
|
|
9
|
-
},
|
|
10
6
|
"cdf-datamodeling-mcp": {
|
|
11
7
|
"command": "npx cdf-datamodelling-mcp-server"
|
|
12
8
|
}
|
|
13
9
|
}
|
|
14
10
|
}
|
|
15
|
-
|
|
@@ -6,7 +6,6 @@ description: Describes global rules
|
|
|
6
6
|
alwaysApply: true
|
|
7
7
|
---
|
|
8
8
|
|
|
9
|
-
- Use
|
|
9
|
+
- Use direct `@cognite/aura/components` exports whenever Aura provides the component you need. Fall back to custom markup only when Aura does not expose an equivalent primitive.
|
|
10
10
|
- Look at the PRD.md file at the root for requirements. If the file is empty, write some yourself as the first thing, and confirm with the user the requirements.
|
|
11
11
|
- The PRD.md file should contain the following: 1.1 Purpose, 1.2 Scope, 1.3 Target Audience, 2. Functional Requirements, 3. Non-Functional Requirements, 4. Data Models & Integration, 4.1 CDF Data Model, 4.1.1 Existing views, 4.1.2 New views, 4.1.3 Spaces, 5. User Stories
|
|
12
|
-
|
|
@@ -1,56 +1,56 @@
|
|
|
1
1
|
export default [
|
|
2
2
|
{
|
|
3
|
-
type:
|
|
4
|
-
name:
|
|
5
|
-
message:
|
|
6
|
-
initial:
|
|
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
7
|
validate: (input) => {
|
|
8
|
-
if (!input) return
|
|
8
|
+
if (!input) return 'App name is required';
|
|
9
9
|
if (!/^[a-z][a-z0-9-]*$/.test(input)) {
|
|
10
|
-
return
|
|
10
|
+
return 'App name must be kebab-case (lowercase, hyphens only)';
|
|
11
11
|
}
|
|
12
12
|
return true;
|
|
13
13
|
},
|
|
14
14
|
},
|
|
15
15
|
{
|
|
16
|
-
type:
|
|
17
|
-
name:
|
|
18
|
-
message:
|
|
19
|
-
initial:
|
|
16
|
+
type: 'input',
|
|
17
|
+
name: 'displayName',
|
|
18
|
+
message: 'What is the display name? (e.g., My Awesome App)',
|
|
19
|
+
initial: 'My Dune app',
|
|
20
20
|
},
|
|
21
21
|
{
|
|
22
|
-
type:
|
|
23
|
-
name:
|
|
24
|
-
message:
|
|
25
|
-
initial:
|
|
22
|
+
type: 'input',
|
|
23
|
+
name: 'description',
|
|
24
|
+
message: 'What is the app description?',
|
|
25
|
+
initial: 'A Dune application',
|
|
26
26
|
},
|
|
27
27
|
{
|
|
28
|
-
type:
|
|
29
|
-
name:
|
|
30
|
-
message:
|
|
31
|
-
initial:
|
|
28
|
+
type: 'input',
|
|
29
|
+
name: 'org',
|
|
30
|
+
message: 'Deployment org? (e.g., cog-demo, cog-atlas)',
|
|
31
|
+
initial: 'cog-demo',
|
|
32
32
|
validate: (input) => {
|
|
33
|
-
if (!input) return
|
|
33
|
+
if (!input) return 'Org is required';
|
|
34
34
|
return true;
|
|
35
35
|
},
|
|
36
36
|
},
|
|
37
37
|
{
|
|
38
|
-
type:
|
|
39
|
-
name:
|
|
40
|
-
message:
|
|
41
|
-
initial:
|
|
38
|
+
type: 'input',
|
|
39
|
+
name: 'project',
|
|
40
|
+
message: 'Deployment project? (e.g., lervik-industries, atlas-greenfield)',
|
|
41
|
+
initial: 'lervik-industries',
|
|
42
42
|
validate: (input) => {
|
|
43
|
-
if (!input) return
|
|
43
|
+
if (!input) return 'Project is required';
|
|
44
44
|
return true;
|
|
45
45
|
},
|
|
46
46
|
},
|
|
47
47
|
{
|
|
48
|
-
type:
|
|
49
|
-
name:
|
|
50
|
-
message:
|
|
51
|
-
initial:
|
|
48
|
+
type: 'input',
|
|
49
|
+
name: 'cluster',
|
|
50
|
+
message: 'Cluster/baseUrl? (e.g., greenfield, westeurope-1, api)',
|
|
51
|
+
initial: 'api',
|
|
52
52
|
validate: (input) => {
|
|
53
|
-
if (!input) return
|
|
53
|
+
if (!input) return 'Cluster is required';
|
|
54
54
|
return true;
|
|
55
55
|
},
|
|
56
56
|
},
|
|
@@ -20,17 +20,17 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>index.html'
|
|
|
20
20
|
<!-- PWA Manifest -->
|
|
21
21
|
<link rel="manifest" href="/manifest.json" />
|
|
22
22
|
|
|
23
|
-
<!--
|
|
23
|
+
<!-- Aura typography compatibility -->
|
|
24
24
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
25
25
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
26
26
|
<link
|
|
27
|
-
href="https://fonts.googleapis.com/css2?family=Inter:wght@
|
|
27
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@100..900&family=Space+Grotesk:wght@300..700&family=Source+Code+Pro:wght@200..900&display=swap"
|
|
28
28
|
rel="stylesheet"
|
|
29
29
|
/>
|
|
30
|
+
|
|
30
31
|
</head>
|
|
31
32
|
<body>
|
|
32
33
|
<div id="root"></div>
|
|
33
34
|
<script type="module" src="/src/main.tsx"></script>
|
|
34
35
|
</body>
|
|
35
36
|
</html>
|
|
36
|
-
|
|
@@ -15,12 +15,13 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>package.json'
|
|
|
15
15
|
"test": "vitest run",
|
|
16
16
|
"test:watch": "vitest",
|
|
17
17
|
"test:ui": "vitest --ui",
|
|
18
|
-
"lint": "
|
|
19
|
-
"lint:fix": "
|
|
18
|
+
"lint": "eslint . --ext .js,.mjs,.cjs,.ts,.tsx",
|
|
19
|
+
"lint:fix": "eslint . --fix --ext .js,.mjs,.cjs,.ts,.tsx",
|
|
20
20
|
"deploy": "dune deploy:interactive --published",
|
|
21
21
|
"deploy-preview": "dune deploy:interactive"
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
|
+
"@cognite/aura": "^0.1.1",
|
|
24
25
|
"@cognite/sdk": "^10.3.0",
|
|
25
26
|
"@cognite/dune": "^0.2.4",
|
|
26
27
|
"@tanstack/react-query": "^5.90.10",
|
|
@@ -30,7 +31,7 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>package.json'
|
|
|
30
31
|
"tailwind-merge": "^3.4.0"
|
|
31
32
|
},
|
|
32
33
|
"devDependencies": {
|
|
33
|
-
"@
|
|
34
|
+
"@eslint/js": "9.39.2",
|
|
34
35
|
"@tailwindcss/vite": "^4.1.17",
|
|
35
36
|
"@testing-library/jest-dom": "^6.6.3",
|
|
36
37
|
"@testing-library/react": "^16.1.0",
|
|
@@ -41,14 +42,19 @@ to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>package.json'
|
|
|
41
42
|
"@vitejs/plugin-react": "^5.1.1",
|
|
42
43
|
"@vitest/ui": "^2.1.8",
|
|
43
44
|
"autoprefixer": "^10.4.22",
|
|
45
|
+
"eslint": "9.39.2",
|
|
46
|
+
"eslint-plugin-import": "^2.32.0",
|
|
47
|
+
"eslint-plugin-no-only-tests": "^3.3.0",
|
|
48
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
49
|
+
"eslint-plugin-react-refresh": "^0.4.24",
|
|
50
|
+
"globals": "^16.5.0",
|
|
44
51
|
"happy-dom": "^20.0.2",
|
|
45
52
|
"postcss": "^8.5.6",
|
|
46
|
-
"shadcn": "^3.5.2",
|
|
47
53
|
"tailwindcss": "^4.1.17",
|
|
48
54
|
"typescript": "^5.0.0",
|
|
55
|
+
"typescript-eslint": "^8.46.4",
|
|
49
56
|
"vite": "^7.2.4",
|
|
50
57
|
"vite-plugin-mkcert": "^1.17.9",
|
|
51
58
|
"vitest": "^2.1.8"
|
|
52
59
|
}
|
|
53
60
|
}
|
|
54
|
-
|
|
@@ -1,38 +1,50 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/App.test.tsx'
|
|
3
3
|
---
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import
|
|
4
|
+
import { useDune } from '@cognite/dune';
|
|
5
|
+
import { CogniteClient } from '@cognite/sdk';
|
|
6
|
+
import { render, screen } from '@testing-library/react';
|
|
7
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
8
|
+
|
|
9
|
+
import App from './App';
|
|
8
10
|
|
|
9
11
|
// Mock the @cognite/dune module
|
|
10
|
-
vi.mock(import(
|
|
12
|
+
vi.mock(import('@cognite/dune'));
|
|
13
|
+
|
|
14
|
+
function mockUseDune(project: string, isLoading: boolean): ReturnType<typeof useDune> {
|
|
15
|
+
const sdk = new CogniteClient({
|
|
16
|
+
appId: 'dune-template-test',
|
|
17
|
+
project,
|
|
18
|
+
baseUrl: 'https://api.cognitedata.com',
|
|
19
|
+
oidcTokenProvider: async () => '',
|
|
20
|
+
});
|
|
11
21
|
|
|
12
|
-
|
|
22
|
+
const contextValue = {
|
|
23
|
+
sdk,
|
|
24
|
+
isLoading,
|
|
25
|
+
} satisfies ReturnType<typeof useDune>;
|
|
26
|
+
|
|
27
|
+
return contextValue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
describe('App', () => {
|
|
13
31
|
beforeEach(() => {
|
|
14
32
|
vi.clearAllMocks();
|
|
15
33
|
});
|
|
16
34
|
|
|
17
|
-
it(
|
|
18
|
-
vi.mocked(
|
|
19
|
-
sdk: { project: "test-project" } as any,
|
|
20
|
-
isLoading: true,
|
|
21
|
-
});
|
|
35
|
+
it('renders loading state', () => {
|
|
36
|
+
vi.mocked(useDune).mockReturnValue(mockUseDune('test-project', true));
|
|
22
37
|
|
|
23
38
|
render(<App />);
|
|
24
|
-
expect(screen.getByText(
|
|
39
|
+
expect(screen.getByText('Loading project...')).toBeInTheDocument();
|
|
25
40
|
});
|
|
26
41
|
|
|
27
|
-
it(
|
|
28
|
-
vi.mocked(
|
|
29
|
-
sdk: { project: "my-test-project" } as any,
|
|
30
|
-
isLoading: false,
|
|
31
|
-
});
|
|
42
|
+
it('renders app with project name', () => {
|
|
43
|
+
vi.mocked(useDune).mockReturnValue(mockUseDune('my-test-project', false));
|
|
32
44
|
|
|
33
45
|
render(<App />);
|
|
34
|
-
expect(screen.getByText(
|
|
35
|
-
expect(screen.getByText(
|
|
46
|
+
expect(screen.getByText('Welcome to my-test-project')).toBeInTheDocument();
|
|
47
|
+
expect(screen.getByText('Open starter config')).toBeInTheDocument();
|
|
48
|
+
expect(screen.getByText('<%= org %> / <%= project %>')).toBeInTheDocument();
|
|
36
49
|
});
|
|
37
50
|
});
|
|
38
|
-
|
|
@@ -1,22 +1,133 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/App.tsx'
|
|
3
3
|
---
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
Badge,
|
|
6
|
+
CodeBlock,
|
|
7
|
+
Dialog,
|
|
8
|
+
DialogContent,
|
|
9
|
+
DialogDescription,
|
|
10
|
+
DialogFooter,
|
|
11
|
+
DialogHeader,
|
|
12
|
+
DialogTitle,
|
|
13
|
+
DialogTrigger,
|
|
14
|
+
Loader,
|
|
15
|
+
Separator,
|
|
16
|
+
buttonVariants,
|
|
17
|
+
} from '@cognite/aura/components';
|
|
18
|
+
import { useDune } from '@cognite/dune';
|
|
19
|
+
import appConfig from '../app.json';
|
|
20
|
+
|
|
21
|
+
const deploymentChecklist = [
|
|
22
|
+
'Confirm org, project, and cluster in app.json.',
|
|
23
|
+
'Replace the starter workflow with your first real query.',
|
|
24
|
+
'Deploy with dune deploy:interactive when the shell is ready.',
|
|
25
|
+
];
|
|
26
|
+
|
|
27
|
+
function getCluster(baseUrl?: string) {
|
|
28
|
+
return baseUrl?.replace(/^https?:\/\//, '').replace(/\.cognitedata\.com$/, '') ?? '';
|
|
29
|
+
}
|
|
5
30
|
|
|
6
31
|
function App() {
|
|
7
32
|
const { sdk, isLoading } = useDune();
|
|
8
33
|
|
|
9
34
|
if (isLoading) {
|
|
10
|
-
return
|
|
35
|
+
return (
|
|
36
|
+
<main className="min-h-screen bg-[linear-gradient(145deg,var(--background)_0%,var(--mountain-50)_55%,var(--mountain-100)_100%)] text-foreground">
|
|
37
|
+
<section className="mx-auto grid min-h-screen w-full max-w-[58rem] place-content-center p-4 sm:p-8">
|
|
38
|
+
<div
|
|
39
|
+
className="mx-auto grid w-full max-w-sm justify-items-center gap-6 rounded-3xl border border-border bg-card p-5 shadow-xl backdrop-blur-lg sm:p-8"
|
|
40
|
+
aria-label="Loading project"
|
|
41
|
+
aria-live="polite"
|
|
42
|
+
>
|
|
43
|
+
<div className="inline-flex items-center gap-3 text-muted-foreground">
|
|
44
|
+
<Loader size={20} />
|
|
45
|
+
<span>Loading project...</span>
|
|
46
|
+
</div>
|
|
47
|
+
</div>
|
|
48
|
+
</section>
|
|
49
|
+
</main>
|
|
50
|
+
);
|
|
11
51
|
}
|
|
12
52
|
|
|
53
|
+
const deployment = appConfig.deployments?.[0];
|
|
54
|
+
const deploymentLabel = [deployment?.org, deployment?.project ?? sdk.project].filter(Boolean).join(' / ');
|
|
55
|
+
const starterConfigPreview = JSON.stringify(
|
|
56
|
+
{
|
|
57
|
+
org: deployment?.org ?? '',
|
|
58
|
+
project: deployment?.project ?? sdk.project,
|
|
59
|
+
cluster: getCluster(deployment?.baseUrl),
|
|
60
|
+
},
|
|
61
|
+
null,
|
|
62
|
+
2
|
|
63
|
+
);
|
|
64
|
+
|
|
13
65
|
return (
|
|
14
|
-
<
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
66
|
+
<main className="min-h-screen bg-[linear-gradient(145deg,var(--background)_0%,var(--mountain-50)_55%,var(--mountain-100)_100%)] text-foreground">
|
|
67
|
+
<section className="mx-auto grid min-h-screen w-full max-w-[58rem] place-content-center p-4 sm:p-8">
|
|
68
|
+
<div className="grid gap-6 rounded-3xl border border-border bg-card p-5 shadow-xl backdrop-blur-lg sm:p-8">
|
|
69
|
+
<div className="flex flex-col gap-4 lg:flex-row lg:items-start lg:justify-between">
|
|
70
|
+
<div>
|
|
71
|
+
<h1 className="text-[clamp(2rem,4vw,3rem)] leading-none font-semibold tracking-[-0.04em]">
|
|
72
|
+
Welcome to {sdk.project}
|
|
73
|
+
</h1>
|
|
74
|
+
<div className="mt-3">
|
|
75
|
+
<Badge variant="fjord" background>
|
|
76
|
+
{deploymentLabel}
|
|
77
|
+
</Badge>
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
<Dialog>
|
|
81
|
+
<DialogTrigger className={buttonVariants()}>Open starter config</DialogTrigger>
|
|
82
|
+
<DialogContent className="max-w-xl">
|
|
83
|
+
<DialogHeader>
|
|
84
|
+
<DialogTitle>Starter config</DialogTitle>
|
|
85
|
+
<DialogDescription>Current starter values as JSON.</DialogDescription>
|
|
86
|
+
</DialogHeader>
|
|
87
|
+
<div className="grid gap-2">
|
|
88
|
+
<div className="overflow-hidden rounded-2xl border border-border bg-background">
|
|
89
|
+
<CodeBlock code={starterConfigPreview} language="json" />
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
<DialogFooter>
|
|
93
|
+
<Badge variant="fjord" background>{sdk.project}</Badge>
|
|
94
|
+
</DialogFooter>
|
|
95
|
+
</DialogContent>
|
|
96
|
+
</Dialog>
|
|
97
|
+
</div>
|
|
98
|
+
|
|
99
|
+
<Separator />
|
|
100
|
+
|
|
101
|
+
<div className="grid gap-4">
|
|
102
|
+
<div id="deployment-checklist" className="rounded-2xl border border-border bg-muted p-4">
|
|
103
|
+
<div className="flex items-center justify-between gap-3">
|
|
104
|
+
<div>
|
|
105
|
+
<p className="text-sm font-semibold">Deployment checklist</p>
|
|
106
|
+
<p className="mt-1 text-sm text-muted-foreground">Use this to turn the starter into a deployable app.</p>
|
|
107
|
+
</div>
|
|
108
|
+
<Badge variant="fjord" background>
|
|
109
|
+
3 steps
|
|
110
|
+
</Badge>
|
|
111
|
+
</div>
|
|
112
|
+
<div className="mt-4 grid gap-2">
|
|
113
|
+
{deploymentChecklist.map((item, index) => (
|
|
114
|
+
<div
|
|
115
|
+
key={item}
|
|
116
|
+
className="grid grid-cols-[auto_1fr] items-start gap-3 rounded-xl border border-border bg-card px-3 py-2"
|
|
117
|
+
>
|
|
118
|
+
<span className="inline-flex h-6 w-6 items-center justify-center rounded-full bg-foreground text-xs font-semibold text-background">
|
|
119
|
+
{index + 1}
|
|
120
|
+
</span>
|
|
121
|
+
<p className="text-sm text-card-foreground">{item}</p>
|
|
122
|
+
</div>
|
|
123
|
+
))}
|
|
124
|
+
</div>
|
|
125
|
+
</div>
|
|
126
|
+
</div>
|
|
127
|
+
</div>
|
|
128
|
+
</section>
|
|
129
|
+
</main>
|
|
18
130
|
);
|
|
19
131
|
}
|
|
20
132
|
|
|
21
133
|
export default App;
|
|
22
|
-
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/lib/utils.ts'
|
|
3
3
|
---
|
|
4
|
-
import { type ClassValue, clsx } from
|
|
5
|
-
import { twMerge } from
|
|
4
|
+
import { type ClassValue, clsx } from 'clsx';
|
|
5
|
+
import { twMerge } from 'tailwind-merge';
|
|
6
6
|
|
|
7
7
|
export function cn(...inputs: ClassValue[]) {
|
|
8
8
|
return twMerge(clsx(inputs));
|
|
9
9
|
}
|
|
10
|
-
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/main.tsx'
|
|
3
3
|
---
|
|
4
|
-
import { DuneAuthProvider } from
|
|
5
|
-
import { QueryClient, QueryClientProvider } from
|
|
6
|
-
import React from
|
|
7
|
-
import ReactDOM from
|
|
8
|
-
import App from "./App.tsx";
|
|
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';
|
|
9
8
|
|
|
10
|
-
import
|
|
9
|
+
import App from './App.tsx';
|
|
10
|
+
|
|
11
|
+
import './styles.css';
|
|
11
12
|
|
|
12
13
|
const queryClient = new QueryClient({
|
|
13
14
|
defaultOptions: {
|
|
@@ -18,7 +19,7 @@ const queryClient = new QueryClient({
|
|
|
18
19
|
},
|
|
19
20
|
});
|
|
20
21
|
|
|
21
|
-
ReactDOM.createRoot(document.getElementById(
|
|
22
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
22
23
|
<React.StrictMode>
|
|
23
24
|
<QueryClientProvider client={queryClient}>
|
|
24
25
|
<DuneAuthProvider>
|
|
@@ -27,4 +28,3 @@ ReactDOM.createRoot(document.getElementById("root")!).render(
|
|
|
27
28
|
</QueryClientProvider>
|
|
28
29
|
</React.StrictMode>
|
|
29
30
|
);
|
|
30
|
-
|
|
@@ -1,25 +1,11 @@
|
|
|
1
1
|
---
|
|
2
2
|
to: '<%= useCurrentDir ? "" : ((directoryName || name) + "/") %>src/styles.css'
|
|
3
3
|
---
|
|
4
|
+
@import "@cognite/aura/styles.css";
|
|
4
5
|
@import "tailwindcss";
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
font-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
align-items: center;
|
|
11
|
-
justify-content: center;
|
|
12
|
-
background: linear-gradient(135deg, #f5f7fa 0%, #e4e8ec 100%);
|
|
7
|
+
:root {
|
|
8
|
+
--font-inter: "Inter", ui-sans-serif, system-ui, sans-serif;
|
|
9
|
+
--font-source-code-pro: "Source Code Pro", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas,
|
|
10
|
+
"Liberation Mono", "Courier New", monospace;
|
|
13
11
|
}
|
|
14
|
-
|
|
15
|
-
h1 {
|
|
16
|
-
font-size: 2rem;
|
|
17
|
-
font-weight: 600;
|
|
18
|
-
color: #1a1a2e;
|
|
19
|
-
margin-bottom: 0.5rem;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
p {
|
|
23
|
-
color: #6b7280;
|
|
24
|
-
}
|
|
25
|
-
|