vaderjs 1.4.1-lv56aadeg5 → 1.4.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.
@@ -0,0 +1,461 @@
1
+ import fs from 'fs'
2
+ import * as Bun from 'bun'
3
+ import { Glob } from 'bun'
4
+ import Router from 'vaderjs/router'
5
+ globalThis.runOnce = []
6
+ let config = await import(process.cwd() + '/vader.config.ts').then((module) => module.default)
7
+ /**
8
+ * @description This function is used to compile the client code
9
+ * @returns {Promise<void>}
10
+ */
11
+ export async function Compile(){
12
+ console.log('\x1b[36mwait \x1b[0m - compiling (client and server)')
13
+ if(fs.existsSync(process.cwd() + '/build')){
14
+ fs.rmdirSync(process.cwd() + '/build', { recursive: true })
15
+ }
16
+ let isUsingProvider = config?.host?.provider
17
+ let compileStart = Date.now()
18
+ const glob = new Glob("/**/*.{ts,tsx,js,jsx}", {
19
+ absolute: true,
20
+ });
21
+ if(!await Bun.file(process.cwd() + '/vader.config.ts').exists()){
22
+ throw new Error('vader.config.ts does not exist')
23
+ }
24
+
25
+ globalThis.config = config
26
+ let jsConfigEists = await Bun.file(process.cwd() + '/jsconfig.json').exists()
27
+ if(!jsConfigEists){
28
+ await Bun.write(process.cwd() + '/jsconfig.json', `{
29
+
30
+ "compilerOptions": {
31
+ "jsx":"react",
32
+ "jsxFactory": "Element"
33
+ }
34
+
35
+ }`)
36
+
37
+ }else{
38
+ let contents = JSON.parse(fs.readFileSync(process.cwd() + '/jsconfig.json', 'utf8'))
39
+ contents.compilerOptions.jsx = 'react'
40
+ contents.compilerOptions.jsxFactory = 'Element'
41
+ fs.writeFileSync(process.cwd() + '/jsconfig.json', JSON.stringify(contents))
42
+ }
43
+ let obj = {
44
+ outdir: config?.compilerOptions?.outDir || process.cwd() + '/build',
45
+ target: config?.compilerOptions?.target || 'browser',
46
+ external: config?.compilerOptions?.external || ['vaderjs/client', '*.module.css'],
47
+
48
+ }
49
+ if(config?.mode === 'development'){
50
+ obj.sourcemap = 'inline'
51
+ }
52
+
53
+
54
+
55
+
56
+ let imports = []
57
+ function grabFunctions(contents, filePath){
58
+ let functions = []
59
+
60
+ for(var i = 0; i < contents.split('\n').length; i++){
61
+ if(contents.split('\n')[i].includes('export') && contents.split('\n')[i].includes('function')){
62
+ let name = contents.split('\n')[i].split('function')[1].split('(')[0].trim()
63
+ let fullFunction = ''
64
+ let j = i
65
+ for(j = i; j < contents.split('\n').length; j++){
66
+ fullFunction += contents.split('\n')[j]
67
+ if(contents.split('\n')[j].includes('}') && !contents.split('\n')[j + 1].includes(')')){
68
+
69
+ break;
70
+ }
71
+ }
72
+ functions.push({functionName: name, fullFunction, filePath})
73
+ }
74
+ }
75
+ return functions
76
+
77
+ }
78
+
79
+ let variables = []
80
+ function grabVariables(contents, filePath){
81
+ for(var i = 0; i < contents.split('\n').length; i++){
82
+ if(contents.split('\n')[i].includes('let') || contents.split('\n')[i].includes('var') || contents.split('\n')[i].includes('const')){
83
+ let isUseState = contents.split('\n')[i].includes('useState')
84
+ if(isUseState){
85
+ let name = contents.split('\n')[i].split('=')[0].split('[', 2)[1].split(',')[0].trim()
86
+ variables.push(name)
87
+ }
88
+
89
+ let isReducer = contents.split('\n')[i].includes('useReducer')
90
+ if(isReducer){
91
+ let name = contents.split('\n')[i].split('=')[0].split('[', 2)[1].split(',')[0].trim()
92
+ variables.push(name)
93
+ }else if(!isUseState || !isReducer || !contents.split('\n')[i].includes('import') || !contents.split('\n')[i].includes('[')
94
+ && !contents.split('\n')[i].includes('import')
95
+ ){
96
+ let variable = ''
97
+ let j = i
98
+ let bracketCount = 0
99
+ for(j = i; j < contents.split('\n').length; j++){
100
+ variable += contents.split('\n')[j]
101
+ if(contents.split('\n')[j].includes('{')){
102
+ bracketCount++
103
+ }
104
+ if(contents.split('\n')[j].includes('}')){
105
+ bracketCount--
106
+ }
107
+ if(bracketCount === 0){
108
+ break;
109
+ }
110
+ }
111
+
112
+ let name = variable.split('=')[0].split('let')[1] ? variable.split('=')[0].split('let')[1].trim() : variable.split('=')[0].split('var')[1] ? variable.split('=')[0].split('var')[1].trim() : variable.split('=')[0].split('const')[1] ? variable.split('=')[0].split('const')[1].trim() : null
113
+ if(name.includes("[")){
114
+ continue
115
+ }
116
+ let value = variable.split('=')[1] ? variable.split('=')[1].trim() : null
117
+ variables.push({name, value, file: filePath})
118
+ }
119
+ }
120
+ }
121
+ globalThis.variables = variables
122
+ return variables
123
+
124
+ }
125
+
126
+
127
+ function cssToObj(data){
128
+ let obj = {}
129
+ let lines = data.split('\n')
130
+ for(var i = 0; i < lines.length; i++){
131
+ if(lines[i].includes(':')){
132
+ let key = lines[i].split(':')[0].trim().replace('.', '')
133
+ // turn kebab case to camel case
134
+ if(key.includes('-')){
135
+ key = key.split('-').map((word, index) => {
136
+ if(index > 0){
137
+ return word.charAt(0).toUpperCase() + word.slice(1)
138
+ }else{
139
+ return word
140
+ }
141
+ }).join('')
142
+ }
143
+ let value = lines[i].split(':')[1].trim()
144
+ obj[key] = value
145
+ }
146
+ }
147
+ return obj
148
+
149
+ }
150
+ async function main(contents, filePath){
151
+ let copy = contents
152
+
153
+ for (var i in contents.split('\n')){
154
+ let line = contents.split('\n')[i]
155
+ let newLine = ''
156
+ let old;
157
+ let file;
158
+ let varType;
159
+ let mimeTypes = ['.png', '.jpg', '.jpeg', '.gif', '.svg', '.json', '.webm', '.mp4', '.avi', '.webp', '.css','.module.css']
160
+ switch(true){
161
+
162
+ case line.includes('function'):
163
+ let props = line.split('function')[1].split('(')[1].split(')')[0].split(',')
164
+ props = props.map((prop) => {
165
+ prop = prop.trim().replace('{', '').replace('}', '')
166
+ if(prop.includes('_') && !prop.match(new RegExp('A-Za-z')) || prop.includes('-') && !prop.match(new RegExp('A-Za-z'))){
167
+ return prop.replaceAll('_', ' ').replaceAll('-', ' ').split(' ').map((word, index) => {
168
+ if(index > 0){
169
+ return word.charAt(0).toUpperCase() + word.slice(1)
170
+ }else{
171
+ return word
172
+ }
173
+ }).join('')
174
+ }
175
+ return prop.trim().replace('{', '').replace('}', '')
176
+ } )
177
+ props = props.filter((prop) => prop !== '')
178
+ // turn prop to an object to fix cannot destructure property of undefined in client
179
+ let newProps = {}
180
+ props.forEach((prop) => {
181
+ newProps[prop] = ''
182
+ })
183
+ if(line && props.length > 0){
184
+ let randomLetters = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z']
185
+ let randoMPropName = randomLetters.sort(() => Math.random() - 0.5).join('')
186
+ randoMPropName = randoMPropName.replaceAll('/\d/g', '')
187
+ let isAsync = line.includes('async') ? 'async' : ''
188
+ let newLine = ` ${line.includes('export') ? 'export' : ''} ${isAsync} function ${line.split('function')[1].split('(')[0].trim()}(${randoMPropName}= ${JSON.stringify(newProps)}){\n let {${props.join(',')}} = ${randoMPropName}\n
189
+ `
190
+ old = line
191
+ copy = copy.replace(old, newLine)
192
+
193
+
194
+ }
195
+ break;
196
+ case line.includes('useFile') && mimeTypes.some((type) => line.includes(type))
197
+ && !line.includes('import')
198
+ :
199
+ let file = line.split('useFile(')[1].split(')')[0].replace(/'/g, '').replace(/"/g, '').replace(';', '')
200
+ file = process.cwd() + '/' + file.replaceAll('../','').replace(/\\/g, '/')
201
+
202
+ let stats = fs.statSync(file)
203
+ let fileType = 'application/octet-stream'; // Default to generic binary data
204
+
205
+ // Determine file type based on extension
206
+ if (file.includes('.png')) {
207
+ fileType = 'image/png';
208
+ } else if (file.includes('.jpg') || file.includes('.jpeg')) {
209
+ fileType = 'image/jpeg';
210
+ } else if (file.includes('.svg')) {
211
+ fileType = 'image/svg+xml';
212
+ } else if (file.includes('.webp')) {
213
+ fileType = 'image/webp';
214
+ } else if (file.includes('.mp4')) {
215
+ fileType = 'video/mp4';
216
+ } else if (file.includes('.avi')) {
217
+ fileType = 'video/x-msvideo';
218
+ }else if (file.includes('.gif')) {
219
+ fileType = 'image/gif';
220
+ }else if (file.includes('.json')) {
221
+ fileType = 'application/json';
222
+ }
223
+ else if (file.includes('.css')) {
224
+ fileType = 'text/css';
225
+ }
226
+ else if (file.includes('.webm')) {
227
+ fileType = 'video/webm';
228
+ }
229
+
230
+ let fcontents = fs.readFileSync(file, fileType.includes('image') ? 'base64' : 'utf8')
231
+ let fileName = line.split('useFile(')[1].split(')')[0].replace(/'/g, '').replace(/"/g, '').replace(';', '').split('/').pop()
232
+ file = file.replace(process.cwd(), '').replace(/\\/g, '/')
233
+ let fileobj = {
234
+ name: fileName,
235
+ size: Math.round(stats.size / 1024) + 'kb',
236
+ type: fileType,
237
+ dataUrl: fileType.includes('image') ? `data:${fileType};base64,${fcontents}` : '',
238
+ fileUrl: file,
239
+ filesize: Math.round(stats.size / 1024) + 'kb',
240
+ lastModified:{
241
+ date: stats.mtime,
242
+ time: stats.mtime.getTime(),
243
+ parsed: new Date(stats.mtime).toDateString()
244
+ },
245
+ arrayBuffer: new Uint8Array(fcontents),
246
+ blob:'',
247
+ text: fcontents,
248
+ json: (fileType === 'application/json' || file.includes('.module.css')) ? cssToObj(fcontents) : null,
249
+ mimetype: fileType,
250
+ extension: file.split('.').pop(),
251
+ formData: null
252
+ }
253
+ newLine = `${JSON.stringify(fileobj)}`
254
+ old = line.split('useFile(')[1].split(')')[0]
255
+ if(line.includes('let') || line.includes('const') || line.includes('var')){
256
+ old = line
257
+ // let/var/const {} or name = value
258
+ newLine = `let ${line.split('=')[0].split(' ').slice(1).join(' ')} = ${JSON.stringify(fileobj)}`
259
+ variables.push({name: `${line.split('=')[0].split(' ').slice(1).join(' ')}`, value: `${JSON.stringify(fileobj)}`, file: filePath})
260
+
261
+ }
262
+ copy = copy.replace(old, newLine)
263
+ break;
264
+ case !line.includes('import') && line.includes('useState') && !line.includes('let useState'):
265
+ let varType = line.split('[', 1)[0];
266
+ let before = line.split('useState(')[1].split(',')[0];
267
+ let key = line.split('[')[1].split(',')[0];
268
+ let setKey = line.split('[')[1].split(',')[1].split(']')[0];
269
+ newLine = `${varType} [${key},${setKey}]= this.useState("${key}", ${before}`;
270
+ old = line;
271
+ copy = copy.replace(old, newLine);
272
+ break;
273
+ case line.includes('useEffect') && !line.includes('var useEffect') && !line.includes('import'):
274
+ newLine = line.replace('useEffect', 'this.useEffect')
275
+ old = line
276
+ copy = copy.replace(old, newLine)
277
+ break;
278
+
279
+
280
+
281
+ case line.includes('import') && line.includes('module.css'):
282
+ file = line.split('from')[1].trim().replace(/'/g, '').replace(/"/g, '').replace(';', '')
283
+ let cssKey = line.split('import')[1].split('from')[0].trim()
284
+ file = process.cwd() + '/' + file.replaceAll('./','').replace(/\\/g, '/')
285
+ contents = fs.readFileSync(file, 'utf8')
286
+ let obj = cssToObj(contents)
287
+ let newObj = JSON.stringify(obj)
288
+ newLine = `let ${cssKey} = ${newObj}`
289
+ old = line
290
+
291
+ copy = copy.replace(old, '')
292
+ copy = newLine + '\n' + copy
293
+ break;
294
+ case line.includes('useRef') && !line.includes('var useRef') && !line.includes('import'):
295
+
296
+ let refVar = line.split("=")[0].trim().split(" ")[1];
297
+
298
+ let ref = line.split("useRef")[1].split("(")[1]
299
+ // if nothing in ref append null
300
+ if(ref === ')'){
301
+ ref = 'null)'
302
+ }
303
+ newLine = `let ${refVar} = useRef("${refVar}", ${ref}`
304
+ old = line
305
+ copy = copy.replace(old, newLine)
306
+ break;
307
+ case line.includes('useReducer') && !line.includes('var useReducer') && !line.includes('import'):
308
+ line = line.replaceAll(/\s+/g, " ");
309
+
310
+ let varTypereducer = line.split("=")[0].trim().split("[")[0].trim();
311
+
312
+ let keyreducer = line
313
+ .split("=")[0]
314
+ .trim()
315
+ .split("[")[1]
316
+ .trim()
317
+ .split(",")[0]
318
+ .trim();
319
+
320
+ let setKeyreducer = line
321
+ .split("=")[0]
322
+ .trim()
323
+ .split(",")[1]
324
+ .trim()
325
+ .replace("]", "");
326
+
327
+ let reducer = line.split("=")[1].split("useReducer(")[1];
328
+ let newStatereducer = `${varTypereducer} [${keyreducer}, ${setKeyreducer}] = this.useReducer('${keyreducer}', ${
329
+ line.includes("=>") ? reducer + "=>{" : reducer
330
+ }`;
331
+ old = line;
332
+ copy = copy.replace(old, newStatereducer);
333
+ break;
334
+
335
+ case line.includes('vaderjs/client') && line.includes('import') || line.includes('vaderjs') && line.includes('import'):
336
+ let b4 = line
337
+ let isUsingProvider = config?.host?.provider
338
+ let replacement = isUsingProvider === 'cloudflare' ? 'remove' : '/src/client.js'
339
+ if(replacement === 'remove'){
340
+ copy = copy.replace(b4, '')
341
+ break;
342
+ }
343
+ let after = line.replace('vaderjs/client', replacement).replace('vaderjs', replacement)
344
+ copy = copy.replace(b4, after)
345
+ break;
346
+
347
+ }
348
+ }
349
+ if(!contents.includes('import Element')){
350
+
351
+ }
352
+ return copy
353
+ }
354
+
355
+
356
+
357
+ async function gen(){
358
+ return new Promise(async (resolve, reject) => {
359
+ const gg = new Glob("/pages/**/*.{ts,tsx,js,jsx}", {
360
+ absolute: true,
361
+ ignore: ["**/node_modules/**"]
362
+ });
363
+
364
+ let array = await Array.fromAsync(gg.scan())
365
+ array = array.map((file) => {
366
+ file = file.replaceAll('\\', '/')
367
+ file ='./' + file
368
+ return file
369
+ })
370
+
371
+ for(var file of array){
372
+ let data = new Bun.Transpiler({
373
+ loader: "tsx",
374
+ tsconfig: {
375
+ 'compilerOptions':{
376
+ 'jsx':'react',
377
+ 'jsxFactory': 'this.Element'
378
+ }
379
+ },
380
+ define:{
381
+
382
+ 'jsxDev':JSON.stringify('this.Element'),
383
+ 'jsx': JSON.stringify('this.Element'),
384
+ }
385
+ }).transformSync(await Bun.file(process.cwd() + file).text())
386
+ let variables = grabVariables(data, file)
387
+ let contents = await main(data, file)
388
+
389
+ variables.forEach((variable) => {
390
+ contents.split('\n').forEach((line, index) => {
391
+ if(line.includes(variable) && !line.includes('import') && !line.includes('let') && !line.includes('var') && !line.includes('const')
392
+ && !line.includes(variable + '()') &&
393
+ !line.includes('.' + variable) &&
394
+ // not an occurence like variable1, variable2, variable3 or variabless
395
+ !line.match(new RegExp(variable + '[0-9]')) && !line.match(new RegExp(variable + '(w+)'))
396
+ && !line.includes(variable + ':')
397
+ ){
398
+ let newLine = line.replaceAll(variable, variable + '()')
399
+ contents = contents.replace(line, newLine)
400
+ }
401
+ });
402
+ })
403
+
404
+ file = file.split('/pages')[1]
405
+ if(isUsingProvider){
406
+ switch(true){
407
+ case isUsingProvider === 'cloudflare':
408
+ fs.mkdirSync(process.cwd() + '/build/pages/' + file.split('/').slice(0, -1).join('/'), { recursive: true })
409
+ file = '/build/pages/' + file.replace('.tsx', '.js').replace('.ts', '.js').replace('.jsx', '.js')
410
+ break;
411
+ default:
412
+ file = '/build/' + file.replace('./', '').replace('.tsx', '.js').replace('.ts', '.js').replace('.jsx', '.js')
413
+ }
414
+ }
415
+ fs.writeFileSync(process.cwd() + file, contents)
416
+
417
+
418
+ }
419
+
420
+
421
+
422
+
423
+ if(!fs.existsSync(process.cwd() + '/build/src/client.js')){
424
+ await Bun.write(process.cwd() + '/build/src/client.js', await Bun.file(process.cwd() + '/node_modules/vaderjs/client/runtime/index.js').text())
425
+ await Bun.write(process.cwd() + '/build/src/router.js', await Bun.file(process.cwd() + '/node_modules/vaderjs/client/runtime/router.js').text())
426
+ }
427
+
428
+
429
+ resolve()
430
+ })
431
+
432
+ }
433
+
434
+ await gen()
435
+
436
+ let compileEnd = Date.now()
437
+ console.log(`\x1b[32m%s\x1b[0m`, 'success', '-', `compiled in ${compileEnd - compileStart}ms`)
438
+
439
+ }
440
+
441
+ if(process.env.hmr || process.env.mode === "production"){
442
+
443
+ await Compile()
444
+ let hasInitialized = []
445
+ if(!process.env.wasLastRun){
446
+ console.group('\x1b[32m%s\x1b[0m', 'ready', '\x1b[0m', '-', `started ${config?.mode} at http://localhost:${config?.env?.PORT || 3000}`)
447
+ }
448
+ if(process.env.mode !== "production"){
449
+ Router.init()
450
+ }
451
+ for(var i in config?.plugins){
452
+ let plugin = config.plugins[i]
453
+ if(plugin?.name.includes('SSG') && config?.env?.SSR){
454
+ hasInitialized.push(plugin)
455
+ continue
456
+ }
457
+ if(plugin.init){
458
+ hasInitialized.push(plugin.init())
459
+ }
460
+ }
461
+ }
@@ -0,0 +1,74 @@
1
+ let {watchDir} = await import(process.cwd() + '/node_modules/vaderjs/binaries/watcher/hmr.js').then((res) => res)
2
+ let { Compile } = await import(process.cwd() + '/node_modules/vaderjs/binaries/compiler/main.js').then((res) => res).catch(() => {})
3
+
4
+ let config = await import(process.cwd() + '/vader.config.ts').then((res) => res.default).catch(() => {})
5
+
6
+ let Router = await import(process.cwd() + '/node_modules/vaderjs/router/index.ts').then((res) => res.default).catch(() => {})
7
+ globalThis.Vader = {
8
+ version: '1.4.2'
9
+ }
10
+ const colours = {
11
+ reset: "\x1b[0m",
12
+ bright: "\x1b[1m",
13
+ dim: "\x1b[2m",
14
+ underscore: "\x1b[4m",
15
+ blink: "\x1b[5m",
16
+ reverse: "\x1b[7m",
17
+ hidden: "\x1b[8m",
18
+
19
+ fg: {
20
+ black: "\x1b[30m",
21
+ red: "\x1b[31m",
22
+ green: "\x1b[32m",
23
+ yellow: "\x1b[33m",
24
+ blue: "\x1b[34m",
25
+ magenta: "\x1b[35m",
26
+ cyan: "\x1b[36m",
27
+ white: "\x1b[37m",
28
+ gray: "\x1b[90m",
29
+ crimson: "\x1b[38m" // Scarlet
30
+ },
31
+ bg: {
32
+ black: "\x1b[40m",
33
+ red: "\x1b[41m",
34
+ green: "\x1b[42m",
35
+ yellow: "\x1b[43m",
36
+ blue: "\x1b[44m",
37
+ magenta: "\x1b[45m",
38
+ cyan: "\x1b[46m",
39
+ white: "\x1b[47m",
40
+ gray: "\x1b[100m",
41
+ crimson: "\x1b[48m"
42
+ }
43
+ };
44
+ function log(){
45
+ console.log(`
46
+ Vaderjs v${globalThis.Vader.version} 🚀
47
+ Command: ${colours.fg.green} ${mode}${colours.reset}
48
+ ${colours.fg.cyan}SSR Enabled: ${colours.fg.green} ${config?.env?.SSR}${colours.reset}
49
+ ${colours.fg.cyan}Prerendering Enabled: ${colours.fg.green} ${config?.plugins?.find((plugin) => plugin.name.includes('SSG'))
50
+ && !config?.plugins?.find((plugin) => plugin.type === 'SSR') ? 'true' : 'false'}${colours.reset}
51
+ `)
52
+ }
53
+ let mode = process.argv[2]
54
+ switch(mode){
55
+ case 'build':
56
+ log()
57
+ await Compile()
58
+ process.exit(0)
59
+ case 'start':
60
+ log()
61
+ process.env.mode = "production"
62
+ Router.init()
63
+ break
64
+ default:
65
+
66
+ log()
67
+ console.log('\x1b[33m%s\x1b[0m', 'Initializing...')
68
+
69
+ watchDir(process.cwd(), mode, config, colours)
70
+
71
+ break;
72
+ }
73
+
74
+
@@ -0,0 +1,36 @@
1
+ import { watch } from 'fs'
2
+ globalThis.hasLogged = false
3
+ export function watchDir(cwd, _){
4
+ process.chdir(cwd)
5
+ let p = Bun.spawn(['bun', "run", process.cwd() + '/node_modules/vaderjs/binaries/compiler/main.js'], {
6
+ cwd: process.cwd(),
7
+ env: {
8
+ hmr: true
9
+ },
10
+ stdout: 'inherit',
11
+ })
12
+ let paths = ['src', 'pages', 'public', 'routes', 'vader.config.ts']
13
+ for(var i in paths){
14
+ let path = paths[i]
15
+ watch(process.cwd() + '/' + path, { recursive: true, absolute:true }, (event, filename) => {
16
+ if(filename && !filename.includes('node_modules') && !globalThis.hasLogged){
17
+ console.log(`\x1b[36mwait \x1b[0m - compiling (client and server)`)
18
+ globalThis.hasLogged = true
19
+ p.kill(0)
20
+ p = Bun.spawn(['bun', "run", process.cwd() + '/node_modules/vaderjs/binaries/compiler/main.js'], {
21
+ cwd: process.cwd(),
22
+ env: {
23
+ hmr: true,
24
+ wasLastRun: true
25
+ },
26
+ stdout: 'inherit',
27
+ })
28
+ setTimeout(() => {
29
+ globalThis.hasLogged = false
30
+ }, 1000)
31
+ }
32
+ })
33
+ }
34
+
35
+
36
+ }