@tothalex/nulljs 0.0.48 → 0.0.54

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.
Files changed (42) hide show
  1. package/package.json +25 -32
  2. package/scripts/install-server.js +0 -199
  3. package/src/commands/api.ts +0 -16
  4. package/src/commands/auth.ts +0 -54
  5. package/src/commands/create.ts +0 -43
  6. package/src/commands/deploy.ts +0 -160
  7. package/src/commands/dev/function/index.ts +0 -221
  8. package/src/commands/dev/function/utils.ts +0 -99
  9. package/src/commands/dev/index.tsx +0 -126
  10. package/src/commands/dev/logging-manager.ts +0 -87
  11. package/src/commands/dev/server/index.ts +0 -48
  12. package/src/commands/dev/server/utils.ts +0 -37
  13. package/src/commands/dev/ui/components/scroll-area.tsx +0 -141
  14. package/src/commands/dev/ui/components/tab-bar.tsx +0 -67
  15. package/src/commands/dev/ui/index.tsx +0 -71
  16. package/src/commands/dev/ui/logging-context.tsx +0 -76
  17. package/src/commands/dev/ui/tabs/functions-tab.tsx +0 -35
  18. package/src/commands/dev/ui/tabs/server-tab.tsx +0 -36
  19. package/src/commands/dev/ui/tabs/vite-tab.tsx +0 -35
  20. package/src/commands/dev/ui/use-logging.tsx +0 -34
  21. package/src/commands/dev/vite/index.ts +0 -54
  22. package/src/commands/dev/vite/utils.ts +0 -71
  23. package/src/commands/host.ts +0 -339
  24. package/src/commands/index.ts +0 -8
  25. package/src/commands/profile.ts +0 -189
  26. package/src/commands/secret.ts +0 -79
  27. package/src/index.ts +0 -346
  28. package/src/lib/api.ts +0 -189
  29. package/src/lib/bundle/external.ts +0 -23
  30. package/src/lib/bundle/function/index.ts +0 -46
  31. package/src/lib/bundle/index.ts +0 -2
  32. package/src/lib/bundle/react/index.ts +0 -2
  33. package/src/lib/bundle/react/spa.ts +0 -77
  34. package/src/lib/bundle/react/ssr/client.ts +0 -93
  35. package/src/lib/bundle/react/ssr/config.ts +0 -77
  36. package/src/lib/bundle/react/ssr/index.ts +0 -4
  37. package/src/lib/bundle/react/ssr/props.ts +0 -71
  38. package/src/lib/bundle/react/ssr/server.ts +0 -83
  39. package/src/lib/bundle/types.ts +0 -4
  40. package/src/lib/config.ts +0 -347
  41. package/src/lib/deployment.ts +0 -244
  42. package/src/lib/update-server.ts +0 -262
@@ -1,93 +0,0 @@
1
- import { basename, extname } from 'path'
2
- import type { InlineConfig, Plugin, UserConfig } from 'vite'
3
- import react from '@vitejs/plugin-react'
4
- import tailwindcss from '@tailwindcss/vite'
5
-
6
- import type { PluginOptions } from '../../types'
7
-
8
- const jsClientSsr = ({ filePath }: PluginOptions): Plugin => {
9
- const entry = basename(filePath, extname(filePath))
10
- const virtualPrefix = `virtual:ssr/${entry}.tsx`
11
-
12
- return {
13
- name: 'nulljs-ssr-client-plugin',
14
- apply: 'build',
15
- config: async (config: UserConfig, { command }) => {
16
- if (command !== 'build') {
17
- return config
18
- }
19
-
20
- return {
21
- build: {
22
- rollupOptions: {
23
- input: {
24
- [entry]: virtualPrefix
25
- },
26
- external: ['cloud'],
27
- output: {
28
- entryFileNames: '[name].js'
29
- }
30
- }
31
- },
32
- plugins: [react()]
33
- }
34
- },
35
-
36
- resolveId: (id: string) => {
37
- if (id === virtualPrefix) {
38
- return id
39
- }
40
- return null
41
- },
42
-
43
- load: (id: string) => {
44
- if (id === virtualPrefix) {
45
- const script = `
46
- import { StrictMode } from 'react'
47
- import { hydrateRoot } from "react-dom/client";
48
- import { Page } from "${filePath.replace(/\\/g, '\\\\')}";
49
-
50
- const domNode = document.getElementById("root");
51
- if (domNode) {
52
- const initialProps = window.__INITIAL_PROPS__ || {};
53
-
54
- hydrateRoot(
55
- domNode,
56
- <StrictMode>
57
- <Page {...initialProps} />
58
- </StrictMode>,
59
- )
60
- }`
61
-
62
- return script
63
- }
64
- return null
65
- },
66
-
67
- generateBundle(_, bundle) {
68
- Object.keys(bundle).forEach((fileName) => {
69
- const chunk = bundle[fileName]
70
- if (chunk.type === 'chunk') {
71
- chunk.code = chunk.code.replace(/import\s+.*?\s+from\s+['"]cloud['"];?\s*/g, '')
72
- chunk.code = chunk.code.replace('import"cloud";', '')
73
- chunk.code = chunk.code.replace(/require\(['"]cloud['"]\);?\s*/g, '')
74
- }
75
- })
76
- }
77
- }
78
- }
79
-
80
- export const ssrClientConfig = (filePath: string): InlineConfig => {
81
- return {
82
- logLevel: 'error',
83
- plugins: [
84
- jsClientSsr({
85
- filePath
86
- }),
87
- tailwindcss()
88
- ],
89
- build: {
90
- outDir: '/tmp'
91
- }
92
- }
93
- }
@@ -1,77 +0,0 @@
1
- import path from 'path'
2
- import type { InlineConfig, Plugin, UserConfig } from 'vite'
3
- import { external } from '../../external'
4
-
5
- import type { PluginOptions } from '../../types'
6
-
7
- const jsConfigSsr = ({ filePath }: PluginOptions): Plugin => {
8
- const entry = path.basename(filePath, path.extname(filePath))
9
- const virtualPrefix = `virtual:ssr/${entry}.ts`
10
-
11
- return {
12
- name: 'nulljs-ssr-props-plugin',
13
- apply: 'build',
14
- config: async (config: UserConfig, { command }) => {
15
- if (command !== 'build') {
16
- return config
17
- }
18
-
19
- return {
20
- build: {
21
- ssr: true,
22
- rollupOptions: {
23
- input: {
24
- [entry]: virtualPrefix
25
- },
26
- external: [...external, 'react', 'react/jsx-runtime'],
27
- output: {
28
- entryFileNames: '[name].js'
29
- },
30
- preserveEntrySignatures: 'strict'
31
- }
32
- }
33
- }
34
- },
35
-
36
- resolveId: (id: string) => {
37
- if (id === virtualPrefix) {
38
- return id
39
- }
40
- return null
41
- },
42
-
43
- load: (id: string) => {
44
- if (id === virtualPrefix) {
45
- const script = `
46
- import { config } from "${filePath.replace(/\\/g, '\\\\')}";
47
-
48
- export default config;
49
- `
50
-
51
- return script
52
- }
53
- return null
54
- },
55
-
56
- transform: (code, id) => {
57
- if (id === filePath) {
58
- const configMatch = code.match(/export const config = \{[^}]*\};/)
59
- return configMatch ? { code: configMatch[0], map: null } : null
60
- }
61
- }
62
- }
63
- }
64
-
65
- export const ssrConfigConfig = (filePath: string): InlineConfig => {
66
- return {
67
- logLevel: 'error',
68
- plugins: [
69
- jsConfigSsr({
70
- filePath
71
- })
72
- ],
73
- build: {
74
- outDir: '/tmp'
75
- }
76
- }
77
- }
@@ -1,4 +0,0 @@
1
- export * from './client'
2
- export * from './server'
3
- export * from './config'
4
- export * from './props'
@@ -1,71 +0,0 @@
1
- import path from 'path'
2
- import type { InlineConfig, Plugin, UserConfig } from 'vite'
3
- import react from '@vitejs/plugin-react-swc'
4
-
5
- import type { PluginOptions } from '../../types'
6
- import { external } from '../../external'
7
-
8
- const jsPagesSsr = ({ filePath }: PluginOptions): Plugin => {
9
- const entry = path.basename(filePath, path.extname(filePath))
10
- const virtualPrefix = `virtual:ssr/${entry}.ts`
11
-
12
- return {
13
- name: 'nulljs-ssr-server-plugin',
14
- apply: 'build',
15
- config: async (config: UserConfig, { command }) => {
16
- if (command !== 'build') {
17
- return config
18
- }
19
-
20
- return {
21
- build: {
22
- ssr: true,
23
- rollupOptions: {
24
- input: {
25
- [entry]: virtualPrefix
26
- },
27
- external,
28
- output: {
29
- entryFileNames: '[name].js'
30
- },
31
- preserveEntrySignatures: 'strict'
32
- }
33
- }
34
- }
35
- },
36
-
37
- resolveId: (id: string) => {
38
- if (id === virtualPrefix) {
39
- return id
40
- }
41
- return null
42
- },
43
-
44
- load: (id: string) => {
45
- if (id === virtualPrefix) {
46
- const script = `
47
- import { props } from "${filePath.replace(/\\/g, '\\\\')}";
48
-
49
- export { props }
50
- `
51
-
52
- return script
53
- }
54
- return null
55
- }
56
- }
57
- }
58
-
59
- export const ssrPropsConfig = (filePath: string): InlineConfig => {
60
- return {
61
- logLevel: 'error',
62
- plugins: [
63
- jsPagesSsr({
64
- filePath
65
- })
66
- ],
67
- build: {
68
- outDir: '/tmp'
69
- }
70
- }
71
- }
@@ -1,83 +0,0 @@
1
- import path from 'path'
2
- import type { InlineConfig, Plugin, UserConfig } from 'vite'
3
- import react from '@vitejs/plugin-react-swc'
4
-
5
- import type { PluginOptions } from '../../types'
6
- import { external } from '../../external'
7
-
8
- const jsPagesSsr = ({ filePath }: PluginOptions): Plugin => {
9
- const entry = path.basename(filePath, path.extname(filePath))
10
- const virtualPrefix = `virtual:ssr/${entry}.tsx`
11
-
12
- return {
13
- name: 'nulljs-ssr-server-plugin',
14
- apply: 'build',
15
- config: async (config: UserConfig, { command }) => {
16
- if (command !== 'build') {
17
- return config
18
- }
19
-
20
- return {
21
- build: {
22
- ssr: true,
23
- rollupOptions: {
24
- input: {
25
- [entry]: virtualPrefix
26
- },
27
- external,
28
- output: {
29
- format: 'iife',
30
- entryFileNames: '[name].js'
31
- }
32
- }
33
- },
34
- ssr: {
35
- target: 'webworker',
36
- noExternal: true
37
- },
38
- plugins: [react()]
39
- }
40
- },
41
-
42
- resolveId: (id: string) => {
43
- if (id === virtualPrefix) {
44
- return id
45
- }
46
- return null
47
- },
48
-
49
- load: (id: string) => {
50
- if (id === virtualPrefix) {
51
- const script = `
52
- import "fast-text-encoding";
53
- import React from "react";
54
- import { renderToString } from "react-dom/server";
55
- import { Page } from "${filePath.replace(/\\/g, '\\\\')}";
56
-
57
- export const Index = (props) => {
58
- const p = props ? JSON.parse(props) : {};
59
-
60
- return renderToString(<Page {...p} />);
61
- }
62
- `
63
-
64
- return script
65
- }
66
- return null
67
- }
68
- }
69
- }
70
-
71
- export const ssrServerConfig = (filePath: string): InlineConfig => {
72
- return {
73
- logLevel: 'error',
74
- plugins: [
75
- jsPagesSsr({
76
- filePath
77
- })
78
- ],
79
- build: {
80
- outDir: '/tmp'
81
- }
82
- }
83
- }
@@ -1,4 +0,0 @@
1
- export type PluginOptions = {
2
- readonly filePath: string
3
- readonly outDir?: string
4
- }
package/src/lib/config.ts DELETED
@@ -1,347 +0,0 @@
1
- import {
2
- readFileSync,
3
- writeFileSync,
4
- existsSync,
5
- mkdirSync,
6
- readdirSync,
7
- unlinkSync
8
- } from 'node:fs'
9
- import { join, dirname } from 'node:path'
10
- import chalk from 'chalk'
11
-
12
- type NulljsConfig = {
13
- key?: {
14
- private: string
15
- public: string
16
- }
17
- api?: string
18
- dev?: {
19
- apiPort?: number
20
- gatewayPort?: number
21
- }
22
- }
23
-
24
- const findProjectRoot = (startPath: string = process.cwd()): string => {
25
- let currentPath = startPath
26
- while (currentPath !== dirname(currentPath)) {
27
- if (existsSync(join(currentPath, 'package.json'))) {
28
- return currentPath
29
- }
30
- currentPath = dirname(currentPath)
31
- }
32
- return startPath
33
- }
34
-
35
- export const configPath = join(findProjectRoot(), '.nulljs', 'config.json')
36
- export const profilesDir = join(findProjectRoot(), '.nulljs', 'profiles')
37
- export const activeProfilePath = join(findProjectRoot(), '.nulljs', 'active-profile')
38
-
39
- export const loadConfig = (): NulljsConfig => {
40
- if (!existsSync(configPath)) {
41
- return {}
42
- }
43
-
44
- try {
45
- const configContent = readFileSync(configPath, 'utf8')
46
- return JSON.parse(configContent) as NulljsConfig
47
- } catch (error) {
48
- console.error('Failed to parse config file:', error)
49
- return {}
50
- }
51
- }
52
-
53
- export const saveConfig = (config: NulljsConfig): void => {
54
- try {
55
- // Ensure the directory exists
56
- const configDir = dirname(configPath)
57
- if (!existsSync(configDir)) {
58
- mkdirSync(configDir, { recursive: true })
59
- }
60
-
61
- const configContent = JSON.stringify(config, null, 2)
62
- writeFileSync(configPath, configContent, 'utf8')
63
- } catch (error) {
64
- console.error('Failed to save config file:', error)
65
- throw error
66
- }
67
- }
68
-
69
- export const updateConfig = (partialConfig: Partial<NulljsConfig>): void => {
70
- const currentConfig = loadConfig()
71
- const updatedConfig = { ...currentConfig, ...partialConfig }
72
-
73
- saveConfig(updatedConfig)
74
- }
75
-
76
- // Profile-related functions (must be defined before other functions use them)
77
- export const getActiveProfile = (): string | null => {
78
- if (!existsSync(activeProfilePath)) {
79
- return null
80
- }
81
- try {
82
- return readFileSync(activeProfilePath, 'utf8').trim()
83
- } catch {
84
- return null
85
- }
86
- }
87
-
88
- export const setActiveProfile = (profileName: string): void => {
89
- const configDir = dirname(activeProfilePath)
90
- if (!existsSync(configDir)) {
91
- mkdirSync(configDir, { recursive: true })
92
- }
93
- writeFileSync(activeProfilePath, profileName, 'utf8')
94
- }
95
-
96
- export const getProfilePath = (profileName: string): string => {
97
- return join(profilesDir, `${profileName}.json`)
98
- }
99
-
100
- export const loadProfile = (profileName: string): NulljsConfig => {
101
- const profilePath = getProfilePath(profileName)
102
- if (!existsSync(profilePath)) {
103
- return {}
104
- }
105
-
106
- try {
107
- const profileContent = readFileSync(profilePath, 'utf8')
108
- return JSON.parse(profileContent) as NulljsConfig
109
- } catch (error) {
110
- console.error(`Failed to parse profile '${profileName}':`, error)
111
- return {}
112
- }
113
- }
114
-
115
- export const saveProfile = (profileName: string, config: NulljsConfig): void => {
116
- try {
117
- if (!existsSync(profilesDir)) {
118
- mkdirSync(profilesDir, { recursive: true })
119
- }
120
-
121
- const profilePath = getProfilePath(profileName)
122
- const configContent = JSON.stringify(config, null, 2)
123
- writeFileSync(profilePath, configContent, 'utf8')
124
- } catch (error) {
125
- console.error(`Failed to save profile '${profileName}':`, error)
126
- throw error
127
- }
128
- }
129
-
130
- export const profileExists = (profileName: string): boolean => {
131
- return existsSync(getProfilePath(profileName))
132
- }
133
-
134
- export const loadConfigWithProfile = (): NulljsConfig => {
135
- const activeProfile = getActiveProfile()
136
-
137
- if (activeProfile && profileExists(activeProfile)) {
138
- return loadProfile(activeProfile)
139
- }
140
-
141
- return loadConfig()
142
- }
143
-
144
- export const saveConfigWithProfile = (config: NulljsConfig, profileName?: string): void => {
145
- if (profileName) {
146
- saveProfile(profileName, config)
147
- setActiveProfile(profileName)
148
- } else {
149
- const activeProfile = getActiveProfile()
150
- if (activeProfile && profileExists(activeProfile)) {
151
- saveProfile(activeProfile, config)
152
- } else {
153
- saveConfig(config)
154
- }
155
- }
156
- }
157
-
158
- export const updateConfigWithProfile = (
159
- partialConfig: Partial<NulljsConfig>,
160
- profileName?: string
161
- ): void => {
162
- if (profileName) {
163
- const currentConfig = loadProfile(profileName)
164
- const updatedConfig = { ...currentConfig, ...partialConfig }
165
- saveProfile(profileName, updatedConfig)
166
- setActiveProfile(profileName)
167
- } else {
168
- const activeProfile = getActiveProfile()
169
- if (activeProfile && profileExists(activeProfile)) {
170
- const currentConfig = loadProfile(activeProfile)
171
- const updatedConfig = { ...currentConfig, ...partialConfig }
172
- saveProfile(activeProfile, updatedConfig)
173
- } else {
174
- updateConfig(partialConfig)
175
- }
176
- }
177
- }
178
-
179
- // Functions that use profile-related functions
180
- export const saveKeys = (privateKey: string, publicKey: string, profileName?: string): void => {
181
- updateConfigWithProfile(
182
- {
183
- key: {
184
- private: privateKey,
185
- public: publicKey
186
- }
187
- },
188
- profileName
189
- )
190
- }
191
-
192
- export const saveApiUrl = (apiUrl: string, profileName?: string): void => {
193
- updateConfigWithProfile({ api: apiUrl }, profileName)
194
- }
195
-
196
- export const loadPrivateKey = async () => {
197
- let base64Key = process.env.NULLJS_PRIVATE_KEY
198
-
199
- if (!base64Key) {
200
- const config = loadConfigWithProfile()
201
- if (!config.key?.private) {
202
- throw new Error('Private key not found in config file or environment variable')
203
- }
204
- base64Key = config.key.private
205
- }
206
-
207
- const keyBuffer = Uint8Array.from(atob(base64Key), (c) => c.charCodeAt(0))
208
-
209
- return await crypto.subtle.importKey(
210
- 'pkcs8',
211
- keyBuffer,
212
- {
213
- name: 'Ed25519',
214
- namedCurve: 'Ed25519'
215
- },
216
- false,
217
- ['sign']
218
- )
219
- }
220
-
221
- export const getApiUrl = (): string => {
222
- const config = loadConfigWithProfile()
223
- return config.api || 'http://localhost:3000/api'
224
- }
225
-
226
- export const API = getApiUrl()
227
-
228
- export type DevConfig = {
229
- apiPort: number
230
- gatewayPort: number
231
- publicKey: string | undefined
232
- }
233
-
234
- export const getDevConfig = () => {
235
- const config = loadConfigWithProfile()
236
- return {
237
- apiPort: config.dev?.apiPort || 3000,
238
- gatewayPort: config.dev?.gatewayPort || 3001,
239
- publicKey: config.key?.public
240
- }
241
- }
242
-
243
- export const getProjectRoot = () => findProjectRoot()
244
-
245
- export const getCloudPath = () => join(findProjectRoot(), '.nulljs')
246
-
247
- export const listProfiles = (): string[] => {
248
- if (!existsSync(profilesDir)) {
249
- return []
250
- }
251
-
252
- try {
253
- return readdirSync(profilesDir)
254
- .filter((file) => file.endsWith('.json'))
255
- .map((file) => file.replace('.json', ''))
256
- } catch {
257
- return []
258
- }
259
- }
260
-
261
- export const deleteProfile = (profileName: string): boolean => {
262
- const profilePath = getProfilePath(profileName)
263
- if (!existsSync(profilePath)) {
264
- return false
265
- }
266
-
267
- try {
268
- unlinkSync(profilePath)
269
-
270
- const activeProfile = getActiveProfile()
271
- if (activeProfile === profileName) {
272
- if (existsSync(activeProfilePath)) {
273
- unlinkSync(activeProfilePath)
274
- }
275
- }
276
-
277
- return true
278
- } catch {
279
- return false
280
- }
281
- }
282
-
283
- export const requireActiveProfile = (): { profileName: string; config: NulljsConfig } => {
284
- const activeProfile = getActiveProfile()
285
-
286
- if (!activeProfile) {
287
- console.error(chalk.red('❌ No active profile selected.'))
288
- console.error(chalk.gray(' Create a profile: nulljs profile create <name>'))
289
- console.error(chalk.gray(' Or switch to existing: nulljs profile use <name>'))
290
- process.exit(1)
291
- }
292
-
293
- if (!profileExists(activeProfile)) {
294
- console.error(chalk.red(`❌ Active profile '${activeProfile}' does not exist.`))
295
- console.error(chalk.gray(' Available profiles:'))
296
- const profiles = listProfiles()
297
- if (profiles.length > 0) {
298
- profiles.forEach((profile) => console.error(chalk.gray(` - ${profile}`)))
299
- console.error(chalk.gray(' Switch to an existing profile: nulljs profile use <name>'))
300
- } else {
301
- console.error(chalk.gray(' Create your first profile: nulljs profile create <name>'))
302
- }
303
- process.exit(1)
304
- }
305
-
306
- const config = loadProfile(activeProfile)
307
- return { profileName: activeProfile, config }
308
- }
309
-
310
- export const requireProfileConfiguration = (
311
- requiredFields: Array<'api' | 'key' | 'dev'> = ['api', 'key']
312
- ): { profileName: string; config: NulljsConfig } => {
313
- const { profileName, config } = requireActiveProfile()
314
-
315
- const missing: string[] = []
316
-
317
- if (requiredFields.includes('api') && !config.api) {
318
- missing.push('API URL')
319
- }
320
-
321
- if (requiredFields.includes('key') && (!config.key?.private || !config.key?.public)) {
322
- missing.push('authentication keys')
323
- }
324
-
325
- if (requiredFields.includes('dev') && !config.dev) {
326
- missing.push('dev configuration')
327
- }
328
-
329
- if (missing.length > 0) {
330
- console.error(chalk.red(`❌ Profile '${profileName}' is missing required configuration:`))
331
- missing.forEach((field) => console.error(chalk.yellow(` - ${field}`)))
332
- console.error('')
333
- console.error(chalk.gray(' Configure your profile:'))
334
- if (missing.includes('API URL')) {
335
- console.error(chalk.gray(' nulljs api <url>'))
336
- }
337
- if (missing.includes('authentication keys')) {
338
- console.error(chalk.gray(' nulljs auth'))
339
- }
340
- if (missing.includes('dev configuration')) {
341
- console.error(chalk.gray(' Check your .nulljs/profiles/<profile>.json file'))
342
- }
343
- process.exit(1)
344
- }
345
-
346
- return { profileName, config }
347
- }