@zea.cl/cranium-sdk 0.3.4
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/bin/cranium-add.mjs +212 -0
- package/bin/cranium-init.mjs +80 -0
- package/dist/components/index.d.mts +38 -0
- package/dist/components/index.d.ts +38 -0
- package/dist/components/index.js +632 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/index.mjs +626 -0
- package/dist/components/index.mjs.map +1 -0
- package/dist/hooks/index.d.mts +15 -0
- package/dist/hooks/index.d.ts +15 -0
- package/dist/hooks/index.js +85 -0
- package/dist/hooks/index.js.map +1 -0
- package/dist/hooks/index.mjs +83 -0
- package/dist/hooks/index.mjs.map +1 -0
- package/dist/index.d.mts +76 -0
- package/dist/index.d.ts +76 -0
- package/dist/index.js +638 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +627 -0
- package/dist/index.mjs.map +1 -0
- package/dist/styles/base.css +173 -0
- package/dist/types-C91Zqt3G.d.mts +30 -0
- package/dist/types-C91Zqt3G.d.ts +30 -0
- package/package.json +70 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* cranium-add â Add a ZEA module to a Cranium microfrontend app
|
|
5
|
+
*
|
|
6
|
+
* Usage: npx cranium-add thalamus
|
|
7
|
+
*
|
|
8
|
+
* Steps for 'thalamus':
|
|
9
|
+
* 1. Install @zea/thalamus-sdk
|
|
10
|
+
* 2. Run thalamus-init (browser OAuth flow â saves .zea-config.json)
|
|
11
|
+
* 3. Patch src/App.tsx with auth gate + UserMenu
|
|
12
|
+
*/
|
|
13
|
+
|
|
14
|
+
import { readFileSync, writeFileSync, existsSync } from 'fs'
|
|
15
|
+
import { execSync, spawn } from 'child_process'
|
|
16
|
+
import { resolve } from 'path'
|
|
17
|
+
|
|
18
|
+
const MODULE = process.argv[2]
|
|
19
|
+
|
|
20
|
+
if (!MODULE) {
|
|
21
|
+
console.log('')
|
|
22
|
+
console.log('ðĶī cranium-add â Add a ZEA module to your Cranium app')
|
|
23
|
+
console.log('')
|
|
24
|
+
console.log('Usage: npx cranium-add <module>')
|
|
25
|
+
console.log('')
|
|
26
|
+
console.log('Available modules:')
|
|
27
|
+
console.log(' thalamus Add ZEA auth (OAuth2 PKCE login, user menu)')
|
|
28
|
+
console.log('')
|
|
29
|
+
process.exit(0)
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
if (MODULE !== 'thalamus') {
|
|
33
|
+
console.log(`â Unknown module: ${MODULE}`)
|
|
34
|
+
console.log(' Available: thalamus')
|
|
35
|
+
process.exit(1)
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const PROJECT_DIR = process.cwd()
|
|
39
|
+
const SDK_PATH = resolve(import.meta.dirname || __dirname, '..')
|
|
40
|
+
|
|
41
|
+
// Read Cranium app port from vite.config.ts
|
|
42
|
+
function getAppPort() {
|
|
43
|
+
const vitePath = resolve(PROJECT_DIR, 'vite.config.ts')
|
|
44
|
+
try {
|
|
45
|
+
const vite = readFileSync(vitePath, 'utf8')
|
|
46
|
+
const m = vite.match(/port:\s*(\d+)/)
|
|
47
|
+
if (m) return parseInt(m[1], 10)
|
|
48
|
+
} catch {}
|
|
49
|
+
return 5499
|
|
50
|
+
}
|
|
51
|
+
const APP_PORT = getAppPort()
|
|
52
|
+
|
|
53
|
+
console.log('')
|
|
54
|
+
console.log('ðĶī cranium-add thalamus')
|
|
55
|
+
console.log('')
|
|
56
|
+
|
|
57
|
+
// ââ Step 1: Install @zea/thalamus-sdk ââ
|
|
58
|
+
console.log('ðĶ Installing @zea/thalamus-sdk...')
|
|
59
|
+
try {
|
|
60
|
+
execSync('npm install @zea/thalamus-sdk', { stdio: 'inherit', cwd: PROJECT_DIR })
|
|
61
|
+
console.log('')
|
|
62
|
+
} catch {
|
|
63
|
+
// Try local path fallback
|
|
64
|
+
try {
|
|
65
|
+
execSync(`npm install file:${resolve(SDK_PATH, '../../thalamus/sdk')}`, { stdio: 'inherit', cwd: PROJECT_DIR })
|
|
66
|
+
console.log('')
|
|
67
|
+
} catch (e2) {
|
|
68
|
+
console.log('â ïļ Could not install @zea/thalamus-sdk. Run manually:')
|
|
69
|
+
console.log(' npm install @zea/thalamus-sdk')
|
|
70
|
+
process.exit(1)
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// ââ Step 2: Run thalamus-init (auth setup) ââ
|
|
75
|
+
console.log('ð§ Starting Thalamus setup...')
|
|
76
|
+
console.log(` Cranium app port: ${APP_PORT}`)
|
|
77
|
+
console.log(' A browser window will open for authentication.')
|
|
78
|
+
console.log('')
|
|
79
|
+
|
|
80
|
+
await new Promise((resolvePromise, rejectPromise) => {
|
|
81
|
+
const child = spawn('npx', ['thalamus-init'], {
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
cwd: PROJECT_DIR,
|
|
84
|
+
shell: true,
|
|
85
|
+
env: { ...process.env, PORT: String(APP_PORT) },
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
child.on('close', (code) => {
|
|
89
|
+
if (code === 0) {
|
|
90
|
+
resolvePromise()
|
|
91
|
+
} else {
|
|
92
|
+
console.log('')
|
|
93
|
+
console.log('â ïļ thalamus-init exited with code', code)
|
|
94
|
+
console.log(' You can run it manually: npx thalamus-init')
|
|
95
|
+
console.log(' Then re-run: npx cranium-add thalamus')
|
|
96
|
+
process.exit(1)
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
child.on('error', (err) => {
|
|
101
|
+
rejectPromise(err)
|
|
102
|
+
})
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// ââ Step 3: Read .zea-config.json ââ
|
|
106
|
+
const zeaConfigPath = resolve(PROJECT_DIR, '.zea-config.json')
|
|
107
|
+
if (!existsSync(zeaConfigPath)) {
|
|
108
|
+
console.log('')
|
|
109
|
+
console.log('â ïļ .zea-config.json not found after thalamus-init.')
|
|
110
|
+
console.log(' Make sure the setup completed successfully.')
|
|
111
|
+
process.exit(1)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const zeaConfig = JSON.parse(readFileSync(zeaConfigPath, 'utf8'))
|
|
115
|
+
const { clientId, redirectUri, baseUrl } = zeaConfig
|
|
116
|
+
|
|
117
|
+
if (!clientId || !baseUrl) {
|
|
118
|
+
console.log('')
|
|
119
|
+
console.log('â ïļ Missing clientId or baseUrl in .zea-config.json')
|
|
120
|
+
process.exit(1)
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
console.log('')
|
|
124
|
+
console.log('â
Thalamus configured:')
|
|
125
|
+
console.log(` Client ID : ${clientId}`)
|
|
126
|
+
console.log(` Base URL : ${baseUrl}`)
|
|
127
|
+
console.log('')
|
|
128
|
+
|
|
129
|
+
// ââ Step 4: Patch src/App.tsx ââ
|
|
130
|
+
const appPath = resolve(PROJECT_DIR, 'src', 'App.tsx')
|
|
131
|
+
if (!existsSync(appPath)) {
|
|
132
|
+
console.log('â ïļ src/App.tsx not found. Are you in a Cranium project?')
|
|
133
|
+
process.exit(1)
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const thalamusConfig = JSON.stringify({
|
|
137
|
+
clientId,
|
|
138
|
+
redirectUri: redirectUri || `http://localhost:5499`,
|
|
139
|
+
baseUrl,
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
const newAppTsx = `import { CraniumShell } from '@zea/cranium-sdk'
|
|
143
|
+
import '@zea/cranium-sdk/styles/base.css'
|
|
144
|
+
import { useThalamus, LoginButton, UserMenu } from '@zea/thalamus-sdk'
|
|
145
|
+
|
|
146
|
+
const thalamusConfig = ${thalamusConfig}
|
|
147
|
+
|
|
148
|
+
function LoadingScreen() {
|
|
149
|
+
return (
|
|
150
|
+
<div style={{
|
|
151
|
+
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
152
|
+
height: '100vh', background: '#0d1117', color: '#8b949e', fontSize: 14,
|
|
153
|
+
}}>
|
|
154
|
+
Loading...
|
|
155
|
+
</div>
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
function LoginScreen() {
|
|
160
|
+
return (
|
|
161
|
+
<div style={{
|
|
162
|
+
display: 'grid', gridTemplateColumns: '1fr 1fr',
|
|
163
|
+
height: '100vh', width: '100vw', background: '#0d1117',
|
|
164
|
+
fontFamily: 'system-ui, sans-serif',
|
|
165
|
+
}}>
|
|
166
|
+
{/* Left â Welcome */}
|
|
167
|
+
<div style={{
|
|
168
|
+
display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center',
|
|
169
|
+
padding: 48, gap: 20,
|
|
170
|
+
}}>
|
|
171
|
+
<div style={{ fontSize: 64 }}>ðĶī</div>
|
|
172
|
+
<h1 style={{ fontSize: 28, fontWeight: 700, color: '#e6edf3', margin: 0 }}>
|
|
173
|
+
Welcome to Cranium
|
|
174
|
+
</h1>
|
|
175
|
+
<p style={{ fontSize: 14, color: '#8b949e', textAlign: 'center', maxWidth: 320, margin: 0, lineHeight: 1.6 }}>
|
|
176
|
+
Your microfrontend workspace. Sign in to access your pieces, tools, and dashboards.
|
|
177
|
+
</p>
|
|
178
|
+
</div>
|
|
179
|
+
{/* Right â Login */}
|
|
180
|
+
<div style={{
|
|
181
|
+
display: 'flex', alignItems: 'center', justifyContent: 'center',
|
|
182
|
+
background: '#161b22', borderLeft: '1px solid #21262d',
|
|
183
|
+
}}>
|
|
184
|
+
<LoginButton config={thalamusConfig} label="Login with ZEA" />
|
|
185
|
+
</div>
|
|
186
|
+
</div>
|
|
187
|
+
)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export default function App() {
|
|
191
|
+
const { isAuthenticated, isLoading } = useThalamus(thalamusConfig)
|
|
192
|
+
|
|
193
|
+
if (isLoading) return <LoadingScreen />
|
|
194
|
+
if (!isAuthenticated) return <LoginScreen />
|
|
195
|
+
|
|
196
|
+
return (
|
|
197
|
+
<CraniumShell
|
|
198
|
+
config={{
|
|
199
|
+
apiKey: 'your-api-key',
|
|
200
|
+
baseUrl: 'http://cranium.zea.localhost',
|
|
201
|
+
}}
|
|
202
|
+
/>
|
|
203
|
+
)
|
|
204
|
+
}
|
|
205
|
+
`
|
|
206
|
+
|
|
207
|
+
writeFileSync(appPath, newAppTsx)
|
|
208
|
+
|
|
209
|
+
console.log('â
src/App.tsx updated with Thalamus auth')
|
|
210
|
+
console.log('')
|
|
211
|
+
console.log('ð Ready! Run: npm run dev')
|
|
212
|
+
console.log('')
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { writeFileSync, mkdirSync } from 'fs'
|
|
4
|
+
import { execSync, exec, spawn } from 'child_process'
|
|
5
|
+
import { resolve, dirname } from 'path'
|
|
6
|
+
import { fileURLToPath } from 'url'
|
|
7
|
+
|
|
8
|
+
const __dirname = dirname(fileURLToPath(import.meta.url))
|
|
9
|
+
const SDK_PATH = resolve(__dirname, '..')
|
|
10
|
+
const PORT = '5499'
|
|
11
|
+
|
|
12
|
+
console.log('')
|
|
13
|
+
console.log('ðĶī ZEA Cranium â Microfrontend App Creator')
|
|
14
|
+
console.log('')
|
|
15
|
+
|
|
16
|
+
// Create scaffold
|
|
17
|
+
mkdirSync('src', { recursive: true })
|
|
18
|
+
|
|
19
|
+
writeFileSync('package.json', JSON.stringify({
|
|
20
|
+
name: 'my-cranium-app', private: true, type: 'module',
|
|
21
|
+
scripts: { dev: 'vite', build: 'tsc && vite build' },
|
|
22
|
+
}, null, 2))
|
|
23
|
+
|
|
24
|
+
writeFileSync('vite.config.ts', `import { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nexport default defineConfig({ plugins: [react()], server: { port: ${PORT} } })\n`)
|
|
25
|
+
|
|
26
|
+
writeFileSync('tsconfig.json', JSON.stringify({
|
|
27
|
+
compilerOptions: { target: 'ES2022', module: 'ESNext', moduleResolution: 'bundler', jsx: 'react-jsx', strict: true, skipLibCheck: true, noEmit: true },
|
|
28
|
+
include: ['src'],
|
|
29
|
+
}, null, 2))
|
|
30
|
+
|
|
31
|
+
writeFileSync('index.html', '<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width,initial-scale=1.0"/><title>My Cranium App</title><style>body{margin:0;padding:0;overflow:hidden;background:#0d1117}</style></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>\n')
|
|
32
|
+
|
|
33
|
+
writeFileSync('src/main.tsx', `import React from 'react'\nimport ReactDOM from 'react-dom/client'\nimport App from './App'\nReactDOM.createRoot(document.getElementById('root')!).render(<React.StrictMode><App /></React.StrictMode>)\n`)
|
|
34
|
+
|
|
35
|
+
writeFileSync('src/App.tsx', `import { CraniumShell } from '@zea/cranium-sdk'\nimport '@zea/cranium-sdk/styles/base.css'\n\nexport default function App() {\n return (\n <CraniumShell\n config={{\n apiKey: 'your-api-key',\n baseUrl: 'http://cranium.zea.localhost',\n }}\n />\n )\n}\n`)
|
|
36
|
+
|
|
37
|
+
writeFileSync('.gitignore', 'node_modules\ndist\n.env\n')
|
|
38
|
+
|
|
39
|
+
console.log('â
Scaffold created')
|
|
40
|
+
console.log('')
|
|
41
|
+
|
|
42
|
+
// Install ALL dependencies in one go
|
|
43
|
+
console.log('ðĶ Installing dependencies...')
|
|
44
|
+
try {
|
|
45
|
+
const deps = [
|
|
46
|
+
'react', 'react-dom',
|
|
47
|
+
SDK_PATH, // @zea/cranium-sdk from local path
|
|
48
|
+
]
|
|
49
|
+
const devDeps = [
|
|
50
|
+
'vite', '@vitejs/plugin-react', 'typescript',
|
|
51
|
+
'@types/react', '@types/react-dom',
|
|
52
|
+
]
|
|
53
|
+
|
|
54
|
+
execSync(`npm install ${deps.join(' ')}`, { stdio: 'inherit' })
|
|
55
|
+
execSync(`npm install -D ${devDeps.join(' ')}`, { stdio: 'inherit' })
|
|
56
|
+
|
|
57
|
+
console.log('')
|
|
58
|
+
console.log('â
Everything installed!')
|
|
59
|
+
console.log('')
|
|
60
|
+
console.log('ð Starting dev server...')
|
|
61
|
+
console.log('')
|
|
62
|
+
|
|
63
|
+
// Auto start dev server and open browser
|
|
64
|
+
const vite = spawn('npx', ['vite', '--host', '0.0.0.0', '--port', PORT], { stdio: 'inherit', shell: true })
|
|
65
|
+
|
|
66
|
+
setTimeout(() => {
|
|
67
|
+
const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'start' : 'xdg-open'
|
|
68
|
+
exec(`${cmd} http://localhost:${PORT}`)
|
|
69
|
+
}, 2000)
|
|
70
|
+
|
|
71
|
+
// Keep process alive
|
|
72
|
+
process.on('SIGINT', () => { vite.kill(); process.exit(0) })
|
|
73
|
+
process.on('SIGTERM', () => { vite.kill(); process.exit(0) })
|
|
74
|
+
} catch (e) {
|
|
75
|
+
console.log('')
|
|
76
|
+
console.log('â ïļ Install failed. Run manually:')
|
|
77
|
+
console.log(` npm install react react-dom ${SDK_PATH}`)
|
|
78
|
+
console.log(' npm install -D vite @vitejs/plugin-react typescript @types/react @types/react-dom')
|
|
79
|
+
console.log(' npm run dev')
|
|
80
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { C as CraniumOptions } from '../types-C91Zqt3G.mjs';
|
|
3
|
+
|
|
4
|
+
interface CraniumTheme {
|
|
5
|
+
bg?: string;
|
|
6
|
+
b1?: string;
|
|
7
|
+
bc?: string;
|
|
8
|
+
tx?: string;
|
|
9
|
+
mu?: string;
|
|
10
|
+
pr?: string;
|
|
11
|
+
fc?: string;
|
|
12
|
+
ha?: string;
|
|
13
|
+
}
|
|
14
|
+
interface SidebarSection {
|
|
15
|
+
id: string;
|
|
16
|
+
label: string;
|
|
17
|
+
content: React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
interface CraniumShellProps {
|
|
20
|
+
config: CraniumOptions;
|
|
21
|
+
/** Theme overrides. Defaults to ZEA dark theme */
|
|
22
|
+
theme?: CraniumTheme;
|
|
23
|
+
brandName?: string;
|
|
24
|
+
rightPiece?: React.ReactNode;
|
|
25
|
+
/** Sidebar sections injected by cranium-add (below dynamic pieces) */
|
|
26
|
+
sidebarSections?: SidebarSection[];
|
|
27
|
+
sidebarWidth?: number;
|
|
28
|
+
rightWidth?: number;
|
|
29
|
+
showRight?: boolean;
|
|
30
|
+
className?: string;
|
|
31
|
+
headerContent?: React.ReactNode;
|
|
32
|
+
subHeaderContent?: React.ReactNode;
|
|
33
|
+
footerContent?: React.ReactNode;
|
|
34
|
+
renderIcon?: (icon: string) => React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
declare function CraniumShell({ config, theme, brandName, rightPiece, sidebarSections, sidebarWidth: iSW, rightWidth: iRW, showRight: iR, className, headerContent, subHeaderContent, footerContent, renderIcon }: CraniumShellProps): React.JSX.Element;
|
|
37
|
+
|
|
38
|
+
export { CraniumShell, type CraniumShellProps, type CraniumTheme, type SidebarSection };
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { C as CraniumOptions } from '../types-C91Zqt3G.js';
|
|
3
|
+
|
|
4
|
+
interface CraniumTheme {
|
|
5
|
+
bg?: string;
|
|
6
|
+
b1?: string;
|
|
7
|
+
bc?: string;
|
|
8
|
+
tx?: string;
|
|
9
|
+
mu?: string;
|
|
10
|
+
pr?: string;
|
|
11
|
+
fc?: string;
|
|
12
|
+
ha?: string;
|
|
13
|
+
}
|
|
14
|
+
interface SidebarSection {
|
|
15
|
+
id: string;
|
|
16
|
+
label: string;
|
|
17
|
+
content: React.ReactNode;
|
|
18
|
+
}
|
|
19
|
+
interface CraniumShellProps {
|
|
20
|
+
config: CraniumOptions;
|
|
21
|
+
/** Theme overrides. Defaults to ZEA dark theme */
|
|
22
|
+
theme?: CraniumTheme;
|
|
23
|
+
brandName?: string;
|
|
24
|
+
rightPiece?: React.ReactNode;
|
|
25
|
+
/** Sidebar sections injected by cranium-add (below dynamic pieces) */
|
|
26
|
+
sidebarSections?: SidebarSection[];
|
|
27
|
+
sidebarWidth?: number;
|
|
28
|
+
rightWidth?: number;
|
|
29
|
+
showRight?: boolean;
|
|
30
|
+
className?: string;
|
|
31
|
+
headerContent?: React.ReactNode;
|
|
32
|
+
subHeaderContent?: React.ReactNode;
|
|
33
|
+
footerContent?: React.ReactNode;
|
|
34
|
+
renderIcon?: (icon: string) => React.ReactNode;
|
|
35
|
+
}
|
|
36
|
+
declare function CraniumShell({ config, theme, brandName, rightPiece, sidebarSections, sidebarWidth: iSW, rightWidth: iRW, showRight: iR, className, headerContent, subHeaderContent, footerContent, renderIcon }: CraniumShellProps): React.JSX.Element;
|
|
37
|
+
|
|
38
|
+
export { CraniumShell, type CraniumShellProps, type CraniumTheme, type SidebarSection };
|