@cognite/dune 0.3.1 → 0.3.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/_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/index.d.ts +2 -2
- package/dist/index.js +1 -1
- 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 +4 -3
- package/src/deploy/index.ts +6 -6
- package/src/deploy/login.ts +7 -7
- package/src/index.ts +1 -1
- package/src/vite/fusion-open-plugin.ts +12 -12
- 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
package/bin/utils/crypto.js
CHANGED
|
@@ -4,9 +4,8 @@
|
|
|
4
4
|
* Provides functions for generating secure random strings and PKCE code challenges.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import crypto from
|
|
7
|
+
import crypto from 'node:crypto';
|
|
8
8
|
|
|
9
|
-
// biome-ignore lint/complexity/noStaticOnlyClass: Utility class pattern
|
|
10
9
|
export class CryptoUtils {
|
|
11
10
|
/**
|
|
12
11
|
* Generate a cryptographically secure random string
|
|
@@ -16,10 +15,10 @@ export class CryptoUtils {
|
|
|
16
15
|
static generateRandomString(length) {
|
|
17
16
|
const bytes = crypto.randomBytes(length);
|
|
18
17
|
return bytes
|
|
19
|
-
.toString(
|
|
20
|
-
.replace(/\+/g,
|
|
21
|
-
.replace(/\//g,
|
|
22
|
-
.replace(/=/g,
|
|
18
|
+
.toString('base64')
|
|
19
|
+
.replace(/\+/g, '-')
|
|
20
|
+
.replace(/\//g, '_')
|
|
21
|
+
.replace(/=/g, '')
|
|
23
22
|
.slice(0, length);
|
|
24
23
|
}
|
|
25
24
|
|
|
@@ -29,7 +28,7 @@ export class CryptoUtils {
|
|
|
29
28
|
* @returns {string} Base64url-encoded SHA256 hash of the verifier
|
|
30
29
|
*/
|
|
31
30
|
static generateCodeChallenge(verifier) {
|
|
32
|
-
const hash = crypto.createHash(
|
|
33
|
-
return hash.toString(
|
|
31
|
+
const hash = crypto.createHash('sha256').update(verifier).digest();
|
|
32
|
+
return hash.toString('base64').replace(/\+/g, '-').replace(/\//g, '_').replace(/=/g, '');
|
|
34
33
|
}
|
|
35
34
|
}
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,31 +1,28 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import * as
|
|
2
|
+
import * as react from 'react';
|
|
3
|
+
import { ReactNode } from 'react';
|
|
3
4
|
import { CogniteClient } from '@cognite/sdk';
|
|
4
|
-
import React from 'react';
|
|
5
5
|
|
|
6
|
-
|
|
6
|
+
interface DuneContextValue {
|
|
7
7
|
sdk: CogniteClient;
|
|
8
8
|
isLoading: boolean;
|
|
9
9
|
error?: string;
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
|
+
declare const DuneAuthProviderContext: react.Context<DuneContextValue>;
|
|
11
12
|
interface DuneAuthProviderProps {
|
|
12
|
-
children:
|
|
13
|
+
children: ReactNode;
|
|
13
14
|
useIFrameAuthentication?: boolean;
|
|
14
15
|
useLocalConfiguration?: {
|
|
15
16
|
org: string;
|
|
16
17
|
project: string;
|
|
17
18
|
baseUrl: string;
|
|
18
19
|
};
|
|
19
|
-
loadingComponent?:
|
|
20
|
-
errorComponent?: (error: string) =>
|
|
20
|
+
loadingComponent?: ReactNode;
|
|
21
|
+
errorComponent?: (error: string) => ReactNode;
|
|
21
22
|
}
|
|
22
23
|
declare const DuneAuthProvider: ({ children, loadingComponent, errorComponent, }: DuneAuthProviderProps) => react_jsx_runtime.JSX.Element;
|
|
23
24
|
|
|
24
|
-
declare const useDune: () =>
|
|
25
|
-
sdk: _cognite_sdk.CogniteClient;
|
|
26
|
-
isLoading: boolean;
|
|
27
|
-
error?: string;
|
|
28
|
-
};
|
|
25
|
+
declare const useDune: () => DuneContextValue;
|
|
29
26
|
|
|
30
27
|
interface CDFConfig {
|
|
31
28
|
project: string;
|
|
@@ -38,4 +35,4 @@ declare const getToken: (clientId: string, clientSecret: string) => Promise<any>
|
|
|
38
35
|
declare const createCDFSDK: (config: CDFConfig) => Promise<CogniteClient>;
|
|
39
36
|
declare const EMPTY_SDK: CogniteClient;
|
|
40
37
|
|
|
41
|
-
export { type CDFConfig, DuneAuthProvider, DuneAuthProviderContext, type DuneAuthProviderProps, EMPTY_SDK, createCDFSDK, getToken, useDune };
|
|
38
|
+
export { type CDFConfig, DuneAuthProvider, DuneAuthProviderContext, type DuneAuthProviderProps, type DuneContextValue, EMPTY_SDK, createCDFSDK, getToken, useDune };
|
package/dist/auth/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/auth/dune-auth-provider.tsx
|
|
2
2
|
import { CogniteClient as CogniteClient2 } from "@cognite/sdk";
|
|
3
|
-
import { createContext, useEffect } from "react";
|
|
4
|
-
import { useState } from "react";
|
|
3
|
+
import { createContext, useEffect, useState } from "react";
|
|
5
4
|
|
|
6
5
|
// src/auth/utils.ts
|
|
7
6
|
import { CogniteClient } from "@cognite/sdk";
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { CDFConfig, DuneAuthProvider, DuneAuthProviderContext, DuneAuthProviderProps, EMPTY_SDK, createCDFSDK, getToken, useDune } from './auth/index.js';
|
|
1
|
+
export { CDFConfig, DuneAuthProvider, DuneAuthProviderContext, DuneAuthProviderProps, DuneContextValue, EMPTY_SDK, createCDFSDK, getToken, useDune } from './auth/index.js';
|
|
2
2
|
import 'react/jsx-runtime';
|
|
3
|
-
import '@cognite/sdk';
|
|
4
3
|
import 'react';
|
|
4
|
+
import '@cognite/sdk';
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,24 +1,25 @@
|
|
|
1
|
-
import { CogniteClient } from
|
|
2
|
-
import type
|
|
3
|
-
import { createContext, useEffect } from "react";
|
|
4
|
-
import { useState } from "react";
|
|
5
|
-
import { EMPTY_SDK, handleCredentialsResponse, requestCredentials } from "./utils";
|
|
1
|
+
import { CogniteClient } from '@cognite/sdk';
|
|
2
|
+
import { createContext, useEffect, useState, type ReactNode } from 'react';
|
|
6
3
|
|
|
7
|
-
|
|
4
|
+
import { EMPTY_SDK, handleCredentialsResponse, requestCredentials } from './utils';
|
|
5
|
+
|
|
6
|
+
export interface DuneContextValue {
|
|
8
7
|
sdk: CogniteClient;
|
|
9
8
|
isLoading: boolean;
|
|
10
9
|
error?: string;
|
|
11
|
-
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export const DuneAuthProviderContext = createContext<DuneContextValue>({
|
|
12
13
|
sdk: EMPTY_SDK,
|
|
13
14
|
isLoading: false,
|
|
14
15
|
});
|
|
15
16
|
|
|
16
17
|
export interface DuneAuthProviderProps {
|
|
17
|
-
children:
|
|
18
|
+
children: ReactNode;
|
|
18
19
|
useIFrameAuthentication?: boolean;
|
|
19
20
|
useLocalConfiguration?: { org: string; project: string; baseUrl: string };
|
|
20
|
-
loadingComponent?:
|
|
21
|
-
errorComponent?: (error: string) =>
|
|
21
|
+
loadingComponent?: ReactNode;
|
|
22
|
+
errorComponent?: (error: string) => ReactNode;
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
export const DuneAuthProvider = ({
|
|
@@ -50,7 +51,7 @@ export const FusionIframeAuthenticationInnerProvider = ({
|
|
|
50
51
|
requestCredentials();
|
|
51
52
|
|
|
52
53
|
const handleMessage = async (event: MessageEvent) => {
|
|
53
|
-
console.log(
|
|
54
|
+
console.log('🔍 Handling message from Fusion');
|
|
54
55
|
|
|
55
56
|
const credentials = handleCredentialsResponse(event);
|
|
56
57
|
|
|
@@ -60,7 +61,7 @@ export const FusionIframeAuthenticationInnerProvider = ({
|
|
|
60
61
|
|
|
61
62
|
// Process credentials (initial or refresh)
|
|
62
63
|
const sdk = new CogniteClient({
|
|
63
|
-
appId:
|
|
64
|
+
appId: 'dune-app',
|
|
64
65
|
project: credentials.project,
|
|
65
66
|
baseUrl: credentials.baseUrl,
|
|
66
67
|
oidcTokenProvider: async () => {
|
|
@@ -74,12 +75,12 @@ export const FusionIframeAuthenticationInnerProvider = ({
|
|
|
74
75
|
setIsLoading(false);
|
|
75
76
|
};
|
|
76
77
|
|
|
77
|
-
console.log(
|
|
78
|
-
window.addEventListener(
|
|
79
|
-
return () => window.removeEventListener(
|
|
78
|
+
console.log('🔍 Adding message listener');
|
|
79
|
+
window.addEventListener('message', handleMessage);
|
|
80
|
+
return () => window.removeEventListener('message', handleMessage);
|
|
80
81
|
}, []);
|
|
81
82
|
|
|
82
|
-
console.log(
|
|
83
|
+
console.log('🔍 CDFIframeAuthenticationInnerProvider', sdk, isLoading, error);
|
|
83
84
|
|
|
84
85
|
if (error && errorComponent) {
|
|
85
86
|
return <>{errorComponent(error)}</>;
|
package/src/auth/index.ts
CHANGED
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
export {
|
|
3
3
|
DuneAuthProvider,
|
|
4
4
|
DuneAuthProviderContext,
|
|
5
|
-
} from
|
|
6
|
-
export { useDune } from
|
|
7
|
-
export { getToken, createCDFSDK, EMPTY_SDK } from
|
|
5
|
+
} from './dune-auth-provider';
|
|
6
|
+
export { useDune } from './use-dune';
|
|
7
|
+
export { getToken, createCDFSDK, EMPTY_SDK } from './utils';
|
|
8
8
|
|
|
9
9
|
// Type exports
|
|
10
|
-
export type { CDFConfig } from
|
|
11
|
-
export type { DuneAuthProviderProps } from
|
|
10
|
+
export type { CDFConfig } from './utils';
|
|
11
|
+
export type { DuneAuthProviderProps, DuneContextValue } from './dune-auth-provider';
|
package/src/auth/use-dune.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import { useContext } from
|
|
2
|
-
import { DuneAuthProviderContext } from "./dune-auth-provider";
|
|
1
|
+
import { useContext } from 'react';
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
import { DuneAuthProviderContext, type DuneContextValue } from './dune-auth-provider';
|
|
4
|
+
|
|
5
|
+
export const useDune = (): DuneContextValue => {
|
|
5
6
|
const context = useContext(DuneAuthProviderContext);
|
|
6
7
|
|
|
7
8
|
if (!context) {
|
|
8
|
-
throw new Error(
|
|
9
|
+
throw new Error('useDune must be used within a DuneAuthProvider');
|
|
9
10
|
}
|
|
10
11
|
|
|
11
12
|
return context;
|
package/src/auth/utils.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { CogniteClient } from
|
|
1
|
+
import { CogniteClient } from '@cognite/sdk';
|
|
2
2
|
|
|
3
3
|
export const MESSAGE_TYPES = {
|
|
4
|
-
APP_HOST_READY:
|
|
5
|
-
APP_READY:
|
|
6
|
-
CREDENTIALS:
|
|
7
|
-
REQUEST_CREDENTIALS:
|
|
4
|
+
APP_HOST_READY: 'APP_HOST_READY',
|
|
5
|
+
APP_READY: 'APP_READY',
|
|
6
|
+
CREDENTIALS: 'CREDENTIALS',
|
|
7
|
+
REQUEST_CREDENTIALS: 'REQUEST_CREDENTIALS',
|
|
8
8
|
} as const;
|
|
9
9
|
|
|
10
10
|
export interface CDFConfig {
|
|
@@ -18,14 +18,14 @@ export interface CDFConfig {
|
|
|
18
18
|
export const getToken = async (clientId: string, clientSecret: string) => {
|
|
19
19
|
const header = `Basic ${btoa(`${clientId}:${clientSecret}`)}`;
|
|
20
20
|
|
|
21
|
-
const response = await fetch(
|
|
22
|
-
method:
|
|
21
|
+
const response = await fetch('https://auth.cognite.com/oauth2/token', {
|
|
22
|
+
method: 'POST',
|
|
23
23
|
headers: {
|
|
24
24
|
Authorization: header,
|
|
25
|
-
|
|
25
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
26
26
|
},
|
|
27
27
|
body: new URLSearchParams({
|
|
28
|
-
grant_type:
|
|
28
|
+
grant_type: 'client_credentials',
|
|
29
29
|
}),
|
|
30
30
|
});
|
|
31
31
|
|
|
@@ -34,11 +34,11 @@ export const getToken = async (clientId: string, clientSecret: string) => {
|
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
export const createCDFSDK = async (config: CDFConfig) => {
|
|
37
|
-
const { project, baseUrl, clientId, clientSecret, appId =
|
|
37
|
+
const { project, baseUrl, clientId, clientSecret, appId = 'cdf-authentication-package' } = config;
|
|
38
38
|
|
|
39
39
|
if (!project || !baseUrl || !clientId || !clientSecret) {
|
|
40
40
|
throw new Error(
|
|
41
|
-
|
|
41
|
+
'Missing required configuration. Please provide: project, baseUrl, clientId, clientSecret'
|
|
42
42
|
);
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -56,9 +56,9 @@ export const createCDFSDK = async (config: CDFConfig) => {
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
export const EMPTY_SDK = new CogniteClient({
|
|
59
|
-
appId:
|
|
60
|
-
project:
|
|
61
|
-
oidcTokenProvider: async () =>
|
|
59
|
+
appId: 'cdf-authentication-package',
|
|
60
|
+
project: '',
|
|
61
|
+
oidcTokenProvider: async () => '',
|
|
62
62
|
});
|
|
63
63
|
|
|
64
64
|
interface Credentials {
|
|
@@ -68,18 +68,18 @@ interface Credentials {
|
|
|
68
68
|
}
|
|
69
69
|
|
|
70
70
|
export const requestCredentials = () => {
|
|
71
|
-
console.log(
|
|
71
|
+
console.log('🔑 Requesting credentials from parent...');
|
|
72
72
|
if (window.parent && window.parent !== window) {
|
|
73
|
-
window.parent.postMessage({ type:
|
|
73
|
+
window.parent.postMessage({ type: 'REQUEST_CREDENTIALS' }, '*');
|
|
74
74
|
}
|
|
75
75
|
};
|
|
76
76
|
|
|
77
77
|
export const handleCredentialsResponse = (event: MessageEvent) => {
|
|
78
78
|
// Check if this is a credentials message (wrapped in type/credentials format)
|
|
79
|
-
if (event.data?.type ===
|
|
79
|
+
if (event.data?.type === 'PROVIDE_CREDENTIALS' && event.data?.credentials) {
|
|
80
80
|
const creds = event.data.credentials;
|
|
81
81
|
if (creds.token && creds.baseUrl && creds.project) {
|
|
82
|
-
console.log(
|
|
82
|
+
console.log('🎉 useCredentials received credentials:', {
|
|
83
83
|
hasToken: !!creds.token,
|
|
84
84
|
tokenLength: creds.token?.length || 0,
|
|
85
85
|
project: creds.project,
|
|
@@ -4,8 +4,9 @@
|
|
|
4
4
|
* Handles deployment of packaged applications to CDF.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import fs from
|
|
8
|
-
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
|
|
9
|
+
import type { CogniteClient } from '@cognite/sdk';
|
|
9
10
|
|
|
10
11
|
export class CdfApplicationDeployer {
|
|
11
12
|
private client: CogniteClient;
|
|
@@ -17,7 +18,7 @@ export class CdfApplicationDeployer {
|
|
|
17
18
|
this.client = client;
|
|
18
19
|
}
|
|
19
20
|
|
|
20
|
-
private DATA_SET_EXTERNAL_ID =
|
|
21
|
+
private DATA_SET_EXTERNAL_ID = 'published-custom-apps';
|
|
21
22
|
|
|
22
23
|
/**
|
|
23
24
|
* Validate that the required data set exists and is accessible
|
|
@@ -36,8 +37,8 @@ export class CdfApplicationDeployer {
|
|
|
36
37
|
const created = await this.client.datasets.create([
|
|
37
38
|
{
|
|
38
39
|
externalId: this.DATA_SET_EXTERNAL_ID,
|
|
39
|
-
name:
|
|
40
|
-
description:
|
|
40
|
+
name: 'Published Custom Apps',
|
|
41
|
+
description: 'Published Custom Apps',
|
|
41
42
|
writeProtected: false,
|
|
42
43
|
},
|
|
43
44
|
]);
|
|
@@ -69,11 +70,11 @@ export class CdfApplicationDeployer {
|
|
|
69
70
|
published = false
|
|
70
71
|
): Promise<void> {
|
|
71
72
|
// Validate data set exists and get its ID
|
|
72
|
-
console.log(
|
|
73
|
+
console.log('🔍 Validating data set access...');
|
|
73
74
|
const dataSetId = await this.validateDataSet();
|
|
74
75
|
console.log(`✅ Data set '${this.DATA_SET_EXTERNAL_ID}' validated (ID: ${dataSetId})\n`);
|
|
75
76
|
|
|
76
|
-
console.log(
|
|
77
|
+
console.log('📁 Creating file record...');
|
|
77
78
|
|
|
78
79
|
const fileContent = fs.readFileSync(zipFilename);
|
|
79
80
|
const metadata = {
|
|
@@ -88,7 +89,7 @@ export class CdfApplicationDeployer {
|
|
|
88
89
|
{
|
|
89
90
|
name: `${appExternalId}-${versionTag}.zip`,
|
|
90
91
|
externalId: `${appExternalId}-${versionTag}`,
|
|
91
|
-
directory:
|
|
92
|
+
directory: '/dune-apps',
|
|
92
93
|
metadata: metadata,
|
|
93
94
|
dataSetId: dataSetId,
|
|
94
95
|
},
|
|
@@ -97,7 +98,7 @@ export class CdfApplicationDeployer {
|
|
|
97
98
|
true // waitUntilAcknowledged
|
|
98
99
|
);
|
|
99
100
|
|
|
100
|
-
console.log(
|
|
101
|
+
console.log('✅ File record created');
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
/**
|
|
@@ -117,7 +118,7 @@ export class CdfApplicationDeployer {
|
|
|
117
118
|
zipFilename: string,
|
|
118
119
|
published = false
|
|
119
120
|
): Promise<void> {
|
|
120
|
-
console.log(
|
|
121
|
+
console.log('\n🚀 Deploying application to CDF...\n');
|
|
121
122
|
|
|
122
123
|
try {
|
|
123
124
|
// Upload to Files API
|
|
@@ -130,7 +131,7 @@ export class CdfApplicationDeployer {
|
|
|
130
131
|
published
|
|
131
132
|
);
|
|
132
133
|
|
|
133
|
-
console.log(
|
|
134
|
+
console.log('\n✅ Deployment successful!');
|
|
134
135
|
} catch (error: unknown) {
|
|
135
136
|
const message = error instanceof Error ? error.message : String(error);
|
|
136
137
|
throw new Error(`Deployment failed: ${message}`);
|
|
@@ -4,9 +4,10 @@
|
|
|
4
4
|
* Handles packaging of build directories into deployment-ready zip files.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import fs from
|
|
8
|
-
import path from
|
|
9
|
-
|
|
7
|
+
import fs from 'node:fs';
|
|
8
|
+
import path from 'node:path';
|
|
9
|
+
|
|
10
|
+
import archiver from 'archiver';
|
|
10
11
|
|
|
11
12
|
export class ApplicationPackager {
|
|
12
13
|
private distPath: string;
|
|
@@ -14,7 +15,7 @@ export class ApplicationPackager {
|
|
|
14
15
|
/**
|
|
15
16
|
* @param {string} distDirectory - Build directory to package (can be relative or absolute)
|
|
16
17
|
*/
|
|
17
|
-
constructor(distDirectory =
|
|
18
|
+
constructor(distDirectory = 'dist') {
|
|
18
19
|
// If distDirectory is already an absolute path, use it as-is
|
|
19
20
|
// Otherwise, join it with the current working directory
|
|
20
21
|
this.distPath = path.isAbsolute(distDirectory)
|
|
@@ -38,29 +39,29 @@ export class ApplicationPackager {
|
|
|
38
39
|
* @param {boolean} verbose - Enable verbose logging
|
|
39
40
|
* @returns {Promise<string>} Path to created zip file
|
|
40
41
|
*/
|
|
41
|
-
async createZip(outputFilename =
|
|
42
|
+
async createZip(outputFilename = 'app.zip', verbose = false): Promise<string> {
|
|
42
43
|
this.validateBuildDirectory();
|
|
43
44
|
|
|
44
|
-
console.log(
|
|
45
|
+
console.log('📦 Packaging application...');
|
|
45
46
|
|
|
46
47
|
return new Promise((resolve, reject) => {
|
|
47
48
|
const output = fs.createWriteStream(outputFilename);
|
|
48
|
-
const archive = archiver(
|
|
49
|
+
const archive = archiver('zip', {
|
|
49
50
|
zlib: { level: 9 }, // Maximum compression
|
|
50
51
|
});
|
|
51
52
|
|
|
52
|
-
output.on(
|
|
53
|
+
output.on('close', () => {
|
|
53
54
|
const sizeMB = (archive.pointer() / 1024 / 1024).toFixed(2);
|
|
54
55
|
console.log(`✅ App packaged: ${outputFilename} (${sizeMB} MB)`);
|
|
55
56
|
resolve(outputFilename);
|
|
56
57
|
});
|
|
57
58
|
|
|
58
|
-
archive.on(
|
|
59
|
+
archive.on('error', (err: Error) => {
|
|
59
60
|
reject(new Error(`Failed to create zip: ${err.message}`));
|
|
60
61
|
});
|
|
61
62
|
|
|
62
63
|
if (verbose) {
|
|
63
|
-
archive.on(
|
|
64
|
+
archive.on('entry', (entry: archiver.EntryData) => {
|
|
64
65
|
console.log(` 📄 ${entry.name}`);
|
|
65
66
|
});
|
|
66
67
|
}
|
package/src/deploy/deploy.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import fs from
|
|
2
|
-
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
|
|
3
|
+
import { CdfApplicationDeployer } from './application-deployer';
|
|
4
|
+
import { ApplicationPackager } from './application-packager';
|
|
5
|
+
import { getSdk } from './get-sdk';
|
|
6
|
+
import type { App, Deployment } from './types';
|
|
6
7
|
|
|
7
8
|
export const deploy = async (deployment: Deployment, app: App, folder: string) => {
|
|
8
9
|
// Step 1: Get an SDK instance
|
|
@@ -11,7 +12,7 @@ export const deploy = async (deployment: Deployment, app: App, folder: string) =
|
|
|
11
12
|
// Step 2: Package application (from the dist subdirectory)
|
|
12
13
|
const distPath = `${folder}/dist`;
|
|
13
14
|
const packager = new ApplicationPackager(distPath);
|
|
14
|
-
const zipFilename = await packager.createZip(
|
|
15
|
+
const zipFilename = await packager.createZip('app.zip', true);
|
|
15
16
|
|
|
16
17
|
// Step 3: Deploy to CDF
|
|
17
18
|
const deployer = new CdfApplicationDeployer(sdk);
|
package/src/deploy/get-sdk.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { CogniteClient } from
|
|
2
|
-
|
|
3
|
-
import
|
|
1
|
+
import { CogniteClient } from '@cognite/sdk';
|
|
2
|
+
|
|
3
|
+
import { getToken } from './login';
|
|
4
|
+
import type { Deployment } from './types';
|
|
4
5
|
|
|
5
6
|
export const getSdk = async (deployment: Deployment, folder: string) => {
|
|
6
7
|
const token = await getToken(deployment.deployClientId, deployment.deploySecretName);
|
package/src/deploy/index.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
// Deploy exports for CI/CD and programmatic deployment
|
|
2
|
-
export { deploy } from
|
|
3
|
-
export { CdfApplicationDeployer } from
|
|
4
|
-
export { ApplicationPackager } from
|
|
5
|
-
export { getSdk } from
|
|
6
|
-
export { getToken } from
|
|
2
|
+
export { deploy } from './deploy';
|
|
3
|
+
export { CdfApplicationDeployer } from './application-deployer';
|
|
4
|
+
export { ApplicationPackager } from './application-packager';
|
|
5
|
+
export { getSdk } from './get-sdk';
|
|
6
|
+
export { getToken } from './login';
|
|
7
7
|
|
|
8
8
|
// Type exports
|
|
9
|
-
export type { Deployment, App } from
|
|
9
|
+
export type { Deployment, App } from './types';
|
package/src/deploy/login.ts
CHANGED
|
@@ -13,16 +13,16 @@ const loadSecretsFromEnv = (): Record<string, string> => {
|
|
|
13
13
|
const normalizedSecrets: Record<string, string> = {};
|
|
14
14
|
|
|
15
15
|
for (const [key, value] of Object.entries(secrets)) {
|
|
16
|
-
if (typeof value ===
|
|
16
|
+
if (typeof value === 'string') {
|
|
17
17
|
// Convert UPPER_CASE to lower-case-with-dashes
|
|
18
|
-
const normalizedKey = key.toLowerCase().replace(/_/g,
|
|
18
|
+
const normalizedKey = key.toLowerCase().replace(/_/g, '-');
|
|
19
19
|
normalizedSecrets[normalizedKey] = value;
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
|
|
23
23
|
return normalizedSecrets;
|
|
24
24
|
} catch (error) {
|
|
25
|
-
console.error(
|
|
25
|
+
console.error('Error parsing DEPLOYMENT_SECRETS:', error);
|
|
26
26
|
return {};
|
|
27
27
|
}
|
|
28
28
|
};
|
|
@@ -51,13 +51,13 @@ export const getToken = async (deployClientId: string, deploySecretName: string)
|
|
|
51
51
|
}
|
|
52
52
|
|
|
53
53
|
const header = `Basic ${btoa(`${deployClientId}:${deploySecret}`)}`;
|
|
54
|
-
const response = await fetch(
|
|
55
|
-
method:
|
|
54
|
+
const response = await fetch('https://auth.cognite.com/oauth2/token', {
|
|
55
|
+
method: 'POST',
|
|
56
56
|
headers: {
|
|
57
57
|
Authorization: header,
|
|
58
|
-
|
|
58
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
59
59
|
},
|
|
60
|
-
body: new URLSearchParams({ grant_type:
|
|
60
|
+
body: new URLSearchParams({ grant_type: 'client_credentials' }),
|
|
61
61
|
});
|
|
62
62
|
|
|
63
63
|
if (!response.ok) {
|
package/src/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Main entry point - re-exports auth for convenience
|
|
2
|
-
export * from
|
|
2
|
+
export * from './auth';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { exec } from
|
|
2
|
-
import fs from
|
|
3
|
-
import path from
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import fs from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
4
|
|
|
5
5
|
const openUrl = (url: string) => {
|
|
6
6
|
const start =
|
|
7
|
-
process.platform ===
|
|
8
|
-
if (process.platform ===
|
|
7
|
+
process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open';
|
|
8
|
+
if (process.platform === 'win32') {
|
|
9
9
|
exec(`start "" "${url}"`);
|
|
10
10
|
} else {
|
|
11
11
|
exec(`${start} "${url}"`);
|
|
@@ -21,20 +21,20 @@ interface ViteDevServer {
|
|
|
21
21
|
|
|
22
22
|
export const fusionOpenPlugin = () => {
|
|
23
23
|
return {
|
|
24
|
-
name:
|
|
24
|
+
name: 'fusion-open',
|
|
25
25
|
configureServer(server: ViteDevServer) {
|
|
26
|
-
server.httpServer?.on(
|
|
26
|
+
server.httpServer?.on('listening', () => {
|
|
27
27
|
const address = server.httpServer?.address();
|
|
28
|
-
const port = address && typeof address ===
|
|
28
|
+
const port = address && typeof address === 'object' ? address.port : 3001;
|
|
29
29
|
|
|
30
|
-
const appJsonPath = path.join(process.cwd(),
|
|
30
|
+
const appJsonPath = path.join(process.cwd(), 'app.json');
|
|
31
31
|
if (fs.existsSync(appJsonPath)) {
|
|
32
32
|
try {
|
|
33
|
-
const appJson = JSON.parse(fs.readFileSync(appJsonPath,
|
|
33
|
+
const appJson = JSON.parse(fs.readFileSync(appJsonPath, 'utf-8'));
|
|
34
34
|
const firstDeployment = appJson.deployments?.[0];
|
|
35
35
|
const { org, project, baseUrl } = firstDeployment || {};
|
|
36
36
|
|
|
37
|
-
const parsedBaseUrl = baseUrl?.split(
|
|
37
|
+
const parsedBaseUrl = baseUrl?.split('//')[1];
|
|
38
38
|
|
|
39
39
|
if (org && project && baseUrl) {
|
|
40
40
|
const fusionUrl = `https://${org}.fusion.cognite.com/${project}/streamlit-apps/dune/development/${port}?cluster=${parsedBaseUrl}&workspace=industrial-tools`;
|
|
@@ -42,7 +42,7 @@ export const fusionOpenPlugin = () => {
|
|
|
42
42
|
openUrl(fusionUrl);
|
|
43
43
|
}
|
|
44
44
|
} catch (error) {
|
|
45
|
-
console.warn(
|
|
45
|
+
console.warn('Failed to read app.json for Fusion URL', error);
|
|
46
46
|
}
|
|
47
47
|
}
|
|
48
48
|
});
|
package/src/vite/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// Vite plugin exports
|
|
2
|
-
export { fusionOpenPlugin } from
|
|
2
|
+
export { fusionOpenPlugin } from './fusion-open-plugin';
|