create-aziz-app 3.1.1 → 3.1.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/bin/create-aziz-app.js +9 -58
- package/package.json +1 -1
- package/template/README.md +402 -667
- package/template/app/layout.js +18 -20
- package/template/app/page.js +33 -56
- package/template/scripts/lib/js-transform.js +57 -3
package/template/app/layout.js
CHANGED
|
@@ -1,20 +1,18 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
<
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
description: 'Built with Aziz.js'
|
|
20
|
-
};
|
|
1
|
+
// Root layout — wraps every page (like Next.js app/layout.js)
|
|
2
|
+
export default function Layout({ children }) {
|
|
3
|
+
return (
|
|
4
|
+
<div style={{ display: 'flex', flexDirection: 'column', minHeight: '100vh' }}>
|
|
5
|
+
<main style={{ flex: 1 }}>
|
|
6
|
+
{children}
|
|
7
|
+
</main>
|
|
8
|
+
<footer>
|
|
9
|
+
Built with Aziz.js
|
|
10
|
+
</footer>
|
|
11
|
+
</div>
|
|
12
|
+
);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const metadata = {
|
|
16
|
+
title: 'My App',
|
|
17
|
+
description: 'Built with Aziz.js'
|
|
18
|
+
};
|
package/template/app/page.js
CHANGED
|
@@ -1,56 +1,33 @@
|
|
|
1
|
-
// Home page — route: /
|
|
2
|
-
export default function Page() {
|
|
3
|
-
const [count, setCount] = useState(0);
|
|
4
|
-
|
|
5
|
-
return (
|
|
6
|
-
<div style={{ padding: '
|
|
7
|
-
<h1>Welcome to Aziz.js</h1>
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
</
|
|
26
|
-
<
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
Contact →
|
|
35
|
-
</button>
|
|
36
|
-
<button class="btn btn-primary" onClick={() => navigate('/test')}>
|
|
37
|
-
Go to Test →
|
|
38
|
-
</button>
|
|
39
|
-
</div>
|
|
40
|
-
</div>
|
|
41
|
-
|
|
42
|
-
<div class="card">
|
|
43
|
-
<h2>Import Anything</h2>
|
|
44
|
-
<p>
|
|
45
|
-
Use <code>import</code> statements just like Next.js.
|
|
46
|
-
The dev server resolves bare imports from <code>node_modules</code> automatically.
|
|
47
|
-
</p>
|
|
48
|
-
<pre style={{ background: '#282c34', color: '#61dafb', padding: '16px', borderRadius: '8px', overflow: 'auto', fontSize: '13px' }}>
|
|
49
|
-
{`import mongoose from 'mongoose';
|
|
50
|
-
import connectDB from '@/lib/db';
|
|
51
|
-
import User from '@/models/User';`}
|
|
52
|
-
</pre>
|
|
53
|
-
</div>
|
|
54
|
-
</div>
|
|
55
|
-
);
|
|
56
|
-
}
|
|
1
|
+
// Home page — route: /
|
|
2
|
+
export default function Page() {
|
|
3
|
+
const [count, setCount] = useState(0);
|
|
4
|
+
|
|
5
|
+
return (
|
|
6
|
+
<div style={{ padding: '48px 32px', maxWidth: '720px', margin: '0 auto' }}>
|
|
7
|
+
<h1>Welcome to Aziz.js</h1>
|
|
8
|
+
<p>
|
|
9
|
+
Your app is running. Edit <code>app/page.js</code> and save —
|
|
10
|
+
the browser refreshes automatically.
|
|
11
|
+
</p>
|
|
12
|
+
|
|
13
|
+
<div class="card">
|
|
14
|
+
<h2>Interactive state</h2>
|
|
15
|
+
<p>A tiny slice of state, exactly like React's <code>useState</code>.</p>
|
|
16
|
+
<div class="count-display">{count}</div>
|
|
17
|
+
<div class="counter-actions">
|
|
18
|
+
<button class="btn btn-danger" onClick={() => setCount(c => c - 1)}>−</button>
|
|
19
|
+
<button class="btn btn-primary" onClick={() => setCount(c => c + 1)}>+</button>
|
|
20
|
+
<button class="btn btn-grey" onClick={() => setCount(0)}>Reset</button>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
|
|
24
|
+
<div class="card">
|
|
25
|
+
<h2>Add a page</h2>
|
|
26
|
+
<p>
|
|
27
|
+
Each <code>page.js</code> inside <code>app/</code> is a route.
|
|
28
|
+
Create <code>app/about/page.js</code> and it becomes <code>/about</code>.
|
|
29
|
+
</p>
|
|
30
|
+
</div>
|
|
31
|
+
</div>
|
|
32
|
+
);
|
|
33
|
+
}
|
|
@@ -53,6 +53,55 @@ function transformJSX(code, filename) {
|
|
|
53
53
|
//
|
|
54
54
|
// Runs on the whole module (not line-by-line) so multi-line
|
|
55
55
|
// import statements are handled correctly.
|
|
56
|
+
//
|
|
57
|
+
// Only keywords sitting in CODE position are rewritten. A `from`
|
|
58
|
+
// or `import` inside a string literal / template literal / comment
|
|
59
|
+
// is prose (e.g. documentation text in JSX) and must be left alone
|
|
60
|
+
// — rewriting it corrupts the module and the page fails to load.
|
|
61
|
+
|
|
62
|
+
// Uint8Array marking every character that is in code position
|
|
63
|
+
// (outside string literals, template literals and comments).
|
|
64
|
+
function codePositions(code) {
|
|
65
|
+
const n = code.length;
|
|
66
|
+
const isCode = new Uint8Array(n);
|
|
67
|
+
const stack = []; // '{' for blocks, 'tpl' for ${ … } in templates
|
|
68
|
+
let mode = 'code'; // code | ' | " | ` | // | /*
|
|
69
|
+
let i = 0;
|
|
70
|
+
|
|
71
|
+
while (i < n) {
|
|
72
|
+
const c = code[i];
|
|
73
|
+
|
|
74
|
+
if (mode === 'code') {
|
|
75
|
+
isCode[i] = 1;
|
|
76
|
+
if (c === '\\') { i += 2; continue; }
|
|
77
|
+
if (c === "'" || c === '"' || c === '`') mode = c;
|
|
78
|
+
else if (c === '/' && code[i + 1] === '/') mode = '//';
|
|
79
|
+
else if (c === '/' && code[i + 1] === '*') mode = '/*';
|
|
80
|
+
else if (c === '{') stack.push('{');
|
|
81
|
+
else if (c === '}') { if (stack.pop() === 'tpl') mode = '`'; }
|
|
82
|
+
i++;
|
|
83
|
+
} else if (mode === "'" || mode === '"' || mode === '`') {
|
|
84
|
+
if (c === '\\') { i += 2; continue; }
|
|
85
|
+
if (c === mode) mode = 'code';
|
|
86
|
+
else if (mode === '`' && c === '$' && code[i + 1] === '{') {
|
|
87
|
+
stack.push('tpl');
|
|
88
|
+
mode = 'code';
|
|
89
|
+
isCode[i] = 1;
|
|
90
|
+
isCode[i + 1] = 1;
|
|
91
|
+
i += 2;
|
|
92
|
+
continue;
|
|
93
|
+
}
|
|
94
|
+
i++;
|
|
95
|
+
} else if (mode === '//') {
|
|
96
|
+
if (c === '\n') mode = 'code';
|
|
97
|
+
i++;
|
|
98
|
+
} else { // block comment
|
|
99
|
+
if (c === '*' && code[i + 1] === '/') { mode = 'code'; i += 2; continue; }
|
|
100
|
+
i++;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return isCode;
|
|
104
|
+
}
|
|
56
105
|
|
|
57
106
|
function isRelativeOrAbsolute(spec) {
|
|
58
107
|
return spec.startsWith('/') ||
|
|
@@ -72,21 +121,26 @@ function mapSpecifier(spec) {
|
|
|
72
121
|
}
|
|
73
122
|
|
|
74
123
|
function rewriteImports(code) {
|
|
124
|
+
const isCode = codePositions(code);
|
|
125
|
+
|
|
75
126
|
// from 'specifier' (covers `import ... from`, `export ... from`)
|
|
76
|
-
code = code.replace(/(\bfrom\s*)(['"])([^'"\n]+)\2/g, (m, from, q, spec) => {
|
|
127
|
+
code = code.replace(/(\bfrom\s*)(['"])([^'"\n]+)\2/g, (m, from, q, spec, offset) => {
|
|
128
|
+
if (!isCode[offset]) return m;
|
|
77
129
|
const mapped = mapSpecifier(spec);
|
|
78
130
|
return mapped === spec ? m : `${from}${q}${mapped}${q}`;
|
|
79
131
|
});
|
|
80
132
|
|
|
81
133
|
// side-effect imports: import 'specifier';
|
|
82
134
|
// (requires the quote right after `import`, so `import(` is not matched)
|
|
83
|
-
code = code.replace(/(\bimport\s+)(['"])([^'"\n]+)\2/g, (m, kw, q, spec) => {
|
|
135
|
+
code = code.replace(/(\bimport\s+)(['"])([^'"\n]+)\2/g, (m, kw, q, spec, offset) => {
|
|
136
|
+
if (!isCode[offset]) return m;
|
|
84
137
|
const mapped = mapSpecifier(spec);
|
|
85
138
|
return mapped === spec ? m : `${kw}${q}${mapped}${q}`;
|
|
86
139
|
});
|
|
87
140
|
|
|
88
141
|
// dynamic imports: import('specifier')
|
|
89
|
-
code = code.replace(/(\bimport\s*\(\s*)(['"])([^'"\n]+)\2(\s*\))/g, (m, pre, q, spec, post) => {
|
|
142
|
+
code = code.replace(/(\bimport\s*\(\s*)(['"])([^'"\n]+)\2(\s*\))/g, (m, pre, q, spec, post, offset) => {
|
|
143
|
+
if (!isCode[offset]) return m;
|
|
90
144
|
const mapped = mapSpecifier(spec);
|
|
91
145
|
return mapped === spec ? m : `${pre}${q}${mapped}${q}${post}`;
|
|
92
146
|
});
|