@bariskuran/create-base 0.0.0-stage → 0.0.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/LICENSE +21 -0
- package/README.md +14 -2
- package/bin/create-base.cjs +275 -0
- package/package.json +16 -4
- package/template/.env +5 -0
- package/template/.gitattributes +2 -0
- package/template/.node-version +1 -0
- package/template/.nvmrc +1 -0
- package/template/.prettierrc.json +7 -0
- package/template/LICENSE +21 -0
- package/template/README.md +0 -0
- package/template/builder.cjs +144 -0
- package/template/eslint.config.mjs +116 -0
- package/template/index.html +29 -0
- package/template/jsconfig.json +38 -0
- package/template/package.json +49 -0
- package/template/public/favicon.svg +12 -0
- package/template/public/logo192.png +0 -0
- package/template/public/og-cover.jpg +0 -0
- package/template/src/App.jsx +8 -0
- package/template/src/components/Layout/NavigationContext.jsx +5 -0
- package/template/src/components/Layout/index.jsx +17 -0
- package/template/src/components/SuspenceFallback/index.jsx +16 -0
- package/template/src/global/ICONS_LIBRARY.js +31 -0
- package/template/src/global/PROJECT_SETTINGS.jsx +169 -0
- package/template/src/global/SITEMAP.js +26 -0
- package/template/src/global/TEXT_LIBRARY.js +6 -0
- package/template/src/imageCatalog/_placeholder/index.js +65 -0
- package/template/src/imageCatalog/_placeholder/large.webp +0 -0
- package/template/src/imageCatalog/_placeholder/small.webp +0 -0
- package/template/src/imageCatalog/_placeholder/thumb.webp +0 -0
- package/template/src/imageCatalog/_placeholder/ultra.webp +0 -0
- package/template/src/imageCatalog/index.js +3 -0
- package/template/src/main.jsx +3 -0
- package/template/src/views/home/_route.js +11 -0
- package/template/src/views/home/_styled.js +6 -0
- package/template/src/views/home/index.jsx +5 -0
- package/template/vite.config.mjs +112 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Baris Kuran
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @bariskuran/create-base
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Create a project from the Base starter template:
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
npm create @bariskuran/base
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
The setup asks for a workspace folder name, project name, title, description, URL, developer name, and contact details. It creates the project, installs dependencies with Yarn, and then you can start it with `yarn start`.
|
|
10
|
+
|
|
11
|
+
You can also run the initializer directly:
|
|
12
|
+
|
|
13
|
+
```sh
|
|
14
|
+
npx @bariskuran/create-base
|
|
15
|
+
```
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const fs = require("node:fs");
|
|
3
|
+
const path = require("node:path");
|
|
4
|
+
const { spawnSync } = require("node:child_process");
|
|
5
|
+
const readline = require("node:readline/promises");
|
|
6
|
+
const { stdin, stdout } = require("node:process");
|
|
7
|
+
|
|
8
|
+
const TEMPLATE_DIR = path.join(__dirname, "..", "template");
|
|
9
|
+
const RESERVED_NAMES = /^(con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\..*)?$/i;
|
|
10
|
+
|
|
11
|
+
function isValidWorkspaceName(value) {
|
|
12
|
+
return (
|
|
13
|
+
value.length > 0 &&
|
|
14
|
+
value.length <= 100 &&
|
|
15
|
+
/^[a-z0-9]+(?:-[a-z0-9]+)*$/.test(value) &&
|
|
16
|
+
!RESERVED_NAMES.test(value)
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function isValidProjectName(value) {
|
|
21
|
+
return (
|
|
22
|
+
value.length <= 214 &&
|
|
23
|
+
/^(?:@[a-z0-9][a-z0-9._~-]*\/)?[a-z0-9][a-z0-9._~-]*$/.test(value) &&
|
|
24
|
+
!value.includes("..") &&
|
|
25
|
+
!value.startsWith(".") &&
|
|
26
|
+
!value.startsWith("_")
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
async function askRequired(rl, prompt, validate, errorMessage) {
|
|
31
|
+
while (true) {
|
|
32
|
+
const value = (await rl.question(prompt)).trim();
|
|
33
|
+
if (value && validate(value)) return value;
|
|
34
|
+
console.log(errorMessage);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
async function askYesNo(rl, prompt) {
|
|
39
|
+
while (true) {
|
|
40
|
+
const value = (await rl.question(prompt)).trim().toLowerCase();
|
|
41
|
+
if (["y", "yes"].includes(value)) return true;
|
|
42
|
+
if (["n", "no", ""].includes(value)) return false;
|
|
43
|
+
console.log("Please answer yes or no.");
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async function askConflictPolicy(rl) {
|
|
48
|
+
while (true) {
|
|
49
|
+
const answer = (await rl.question(
|
|
50
|
+
"For later conflicts, should I prompt you each time or reuse this choice? [prompt/reuse]: ",
|
|
51
|
+
))
|
|
52
|
+
.trim()
|
|
53
|
+
.toLowerCase();
|
|
54
|
+
|
|
55
|
+
if (["prompt", "p"].includes(answer)) return "prompt";
|
|
56
|
+
if (["reuse", "r"].includes(answer)) return "reuse";
|
|
57
|
+
console.log("Please enter 'prompt' or 'reuse'.");
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
async function collectAnswers(rl) {
|
|
62
|
+
console.log("Create a new Base project. Press Ctrl+C to cancel.\n");
|
|
63
|
+
|
|
64
|
+
const workspaceName = await askRequired(
|
|
65
|
+
rl,
|
|
66
|
+
"Workspace folder name (lowercase letters, numbers, and hyphens): ",
|
|
67
|
+
isValidWorkspaceName,
|
|
68
|
+
"Use 1–100 lowercase ASCII letters or numbers, separated by single hyphens. Avoid reserved system names.",
|
|
69
|
+
);
|
|
70
|
+
const projectName = await askRequired(
|
|
71
|
+
rl,
|
|
72
|
+
"Project/package name: ",
|
|
73
|
+
isValidProjectName,
|
|
74
|
+
"Enter a valid npm package name using lowercase letters, numbers, dots, underscores, or hyphens (an optional scope is allowed).",
|
|
75
|
+
);
|
|
76
|
+
const projectTitle = await askRequired(rl, "Project title: ", () => true, "Enter a project title.");
|
|
77
|
+
const projectDescription = await askRequired(
|
|
78
|
+
rl,
|
|
79
|
+
"Project description: ",
|
|
80
|
+
() => true,
|
|
81
|
+
"Enter a project description.",
|
|
82
|
+
);
|
|
83
|
+
const projectUrl = await askRequired(
|
|
84
|
+
rl,
|
|
85
|
+
"Project URL (https://...): ",
|
|
86
|
+
(value) => {
|
|
87
|
+
try {
|
|
88
|
+
return ["http:", "https:"].includes(new URL(value).protocol);
|
|
89
|
+
} catch {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
},
|
|
93
|
+
"Enter a valid http or https URL.",
|
|
94
|
+
);
|
|
95
|
+
const developerName = await askRequired(rl, "Developer name: ", () => true, "Enter a developer name.");
|
|
96
|
+
const developerContact = await askRequired(
|
|
97
|
+
rl,
|
|
98
|
+
"Developer contact (email, website, or other contact): ",
|
|
99
|
+
() => true,
|
|
100
|
+
"Enter developer contact information.",
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return { workspaceName, projectName, projectTitle, projectDescription, projectUrl, developerName, developerContact };
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
function replaceEnvValue(envText, key, value) {
|
|
107
|
+
const encoded = JSON.stringify(value);
|
|
108
|
+
const matcher = new RegExp(`^${key}=.*$`, "m");
|
|
109
|
+
if (!matcher.test(envText)) throw new Error(`The template is missing ${key} in its .env file.`);
|
|
110
|
+
return envText.replace(matcher, `${key}=${encoded}`);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
async function writeCustomizedFiles(targetDir, answers) {
|
|
114
|
+
if (!answers.skipped.has("package.json")) {
|
|
115
|
+
const packagePath = path.join(targetDir, "package.json");
|
|
116
|
+
const packageJson = JSON.parse(await fs.promises.readFile(packagePath, "utf8"));
|
|
117
|
+
packageJson.name = answers.projectName;
|
|
118
|
+
packageJson.description = answers.projectDescription;
|
|
119
|
+
packageJson.author = `${answers.developerName} <${answers.developerContact}>`;
|
|
120
|
+
await fs.promises.writeFile(packagePath, `${JSON.stringify(packageJson, null, 4)}\n`);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (!answers.skipped.has(".env")) {
|
|
124
|
+
const envPath = path.join(targetDir, ".env");
|
|
125
|
+
let envText = await fs.promises.readFile(envPath, "utf8");
|
|
126
|
+
envText = replaceEnvValue(envText, "VITE_SITE_TITLE", answers.projectTitle);
|
|
127
|
+
envText = replaceEnvValue(envText, "VITE_SITE_DESCRIPTION", answers.projectDescription);
|
|
128
|
+
envText = replaceEnvValue(envText, "VITE_SITE_URL", answers.projectUrl);
|
|
129
|
+
envText = replaceEnvValue(envText, "VITE_DEVELOPER_NAME", answers.developerName);
|
|
130
|
+
await fs.promises.writeFile(envPath, envText);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
if (!answers.skipped.has("LICENSE")) {
|
|
134
|
+
const licensePath = path.join(targetDir, "LICENSE");
|
|
135
|
+
const licenseText = await fs.promises.readFile(licensePath, "utf8");
|
|
136
|
+
const currentYear = new Date().getFullYear();
|
|
137
|
+
const personalizedLicense = licenseText
|
|
138
|
+
.replaceAll("[YEAR]", String(currentYear))
|
|
139
|
+
.replaceAll("[DEVELOPER_NAME]", answers.developerName)
|
|
140
|
+
.replaceAll("[DEVELOPER_CONTACT]", answers.developerContact);
|
|
141
|
+
await fs.promises.writeFile(licensePath, personalizedLicense);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function promptOverwrite(relativePath) {
|
|
146
|
+
return `\n\"${relativePath}\" already exists. Do you want to overwrite it? [y/N]: `;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
async function copyTemplate(rl, targetDir) {
|
|
150
|
+
let policy = null;
|
|
151
|
+
let rememberedOverwrite = false;
|
|
152
|
+
const skipped = new Set();
|
|
153
|
+
|
|
154
|
+
async function resolveConflict(relativePath) {
|
|
155
|
+
let overwrite;
|
|
156
|
+
if (policy === "reuse") {
|
|
157
|
+
overwrite = rememberedOverwrite;
|
|
158
|
+
} else {
|
|
159
|
+
overwrite = await askYesNo(rl, promptOverwrite(relativePath));
|
|
160
|
+
if (policy === null) {
|
|
161
|
+
rememberedOverwrite = overwrite;
|
|
162
|
+
policy = await askConflictPolicy(rl);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return overwrite;
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
async function copyNode(sourcePath, destinationPath, relativePath) {
|
|
169
|
+
const sourceStat = await fs.promises.lstat(sourcePath);
|
|
170
|
+
let destinationStat = null;
|
|
171
|
+
try {
|
|
172
|
+
destinationStat = await fs.promises.lstat(destinationPath);
|
|
173
|
+
} catch (error) {
|
|
174
|
+
if (error.code !== "ENOENT") throw error;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
if (destinationStat) {
|
|
178
|
+
const sameType = sourceStat.isDirectory() === destinationStat.isDirectory();
|
|
179
|
+
if (sameType && sourceStat.isDirectory()) {
|
|
180
|
+
// Merge directories so unrelated user files remain untouched.
|
|
181
|
+
} else if (!(await resolveConflict(relativePath))) {
|
|
182
|
+
skipped.add(relativePath);
|
|
183
|
+
return;
|
|
184
|
+
} else {
|
|
185
|
+
await fs.promises.rm(destinationPath, { recursive: true, force: true });
|
|
186
|
+
destinationStat = null;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (sourceStat.isDirectory()) {
|
|
191
|
+
await fs.promises.mkdir(destinationPath, { recursive: true });
|
|
192
|
+
const children = await fs.promises.readdir(sourcePath);
|
|
193
|
+
for (const child of children) {
|
|
194
|
+
if (child === ".DS_Store") continue;
|
|
195
|
+
await copyNode(
|
|
196
|
+
path.join(sourcePath, child),
|
|
197
|
+
path.join(destinationPath, child),
|
|
198
|
+
path.posix.join(relativePath, child),
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
if (sourceStat.isSymbolicLink()) throw new Error(`The template contains an unsupported symbolic link: ${relativePath}`);
|
|
205
|
+
await fs.promises.mkdir(path.dirname(destinationPath), { recursive: true });
|
|
206
|
+
await fs.promises.copyFile(sourcePath, destinationPath);
|
|
207
|
+
await fs.promises.chmod(destinationPath, sourceStat.mode);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const children = await fs.promises.readdir(TEMPLATE_DIR);
|
|
211
|
+
for (const child of children) {
|
|
212
|
+
if (child === ".DS_Store") continue;
|
|
213
|
+
await copyNode(path.join(TEMPLATE_DIR, child), path.join(targetDir, child), child);
|
|
214
|
+
}
|
|
215
|
+
return skipped;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
async function installDependencies(targetDir) {
|
|
219
|
+
console.log("\nInstalling dependencies with Yarn...");
|
|
220
|
+
const result = spawnSync("yarn", ["install"], { cwd: targetDir, stdio: "inherit", shell: process.platform === "win32" });
|
|
221
|
+
if (result.error || result.status !== 0) {
|
|
222
|
+
console.error("\nProject files were created, but Yarn could not complete the installation.");
|
|
223
|
+
console.error("Install Yarn if needed, then run 'yarn install' from the project folder.");
|
|
224
|
+
return false;
|
|
225
|
+
}
|
|
226
|
+
return true;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
async function main() {
|
|
230
|
+
if (!fs.existsSync(TEMPLATE_DIR)) throw new Error("The project template could not be found in this installation.");
|
|
231
|
+
|
|
232
|
+
const rl = readline.createInterface({ input: stdin, output: stdout });
|
|
233
|
+
try {
|
|
234
|
+
const answers = await collectAnswers(rl);
|
|
235
|
+
const targetDir = path.resolve(process.cwd(), answers.workspaceName);
|
|
236
|
+
const existing = await fs.promises.lstat(targetDir).catch((error) => {
|
|
237
|
+
if (error.code === "ENOENT") return null;
|
|
238
|
+
throw error;
|
|
239
|
+
});
|
|
240
|
+
|
|
241
|
+
if (existing && !existing.isDirectory()) {
|
|
242
|
+
throw new Error(`A file already exists at "${answers.workspaceName}". Choose a different workspace folder name.`);
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
if (existing) {
|
|
246
|
+
const proceed = await askYesNo(
|
|
247
|
+
rl,
|
|
248
|
+
`The workspace folder "${answers.workspaceName}" already exists. Should I add the project files to it? [y/N]: `,
|
|
249
|
+
);
|
|
250
|
+
if (!proceed) {
|
|
251
|
+
console.log("Project creation cancelled.");
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
await fs.promises.mkdir(targetDir, { recursive: true });
|
|
257
|
+
answers.skipped = await copyTemplate(rl, targetDir);
|
|
258
|
+
await writeCustomizedFiles(targetDir, answers);
|
|
259
|
+
rl.close();
|
|
260
|
+
|
|
261
|
+
const installed = await installDependencies(targetDir);
|
|
262
|
+
if (installed) {
|
|
263
|
+
console.log("\nSetup complete. Start your project with 'yarn start'.");
|
|
264
|
+
} else {
|
|
265
|
+
console.log(`\nProject files are ready in "${answers.workspaceName}".`);
|
|
266
|
+
}
|
|
267
|
+
} finally {
|
|
268
|
+
rl.close();
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
main().catch((error) => {
|
|
273
|
+
console.error(`\nProject creation failed: ${error.message}`);
|
|
274
|
+
process.exitCode = 1;
|
|
275
|
+
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bariskuran/create-base",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Create a project with @bariskuran/base.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Baris Kuran",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-base": "bin/create-base.cjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"bin/create-base.cjs",
|
|
12
|
+
"template",
|
|
13
|
+
"README.md"
|
|
14
|
+
],
|
|
15
|
+
"engines": {
|
|
16
|
+
"node": ">=23.0.0"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/template/.env
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
23.0.0
|
package/template/.nvmrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
23.0.0
|
package/template/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [YEAR] [DEVELOPER_NAME] / [DEVELOPER_CONTACT]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
File without changes
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
/* eslint-disable no-undef */
|
|
2
|
+
const { execFileSync, execSync } = require("child_process");
|
|
3
|
+
const path = require("path");
|
|
4
|
+
|
|
5
|
+
const MODE = process.argv[2]; // useGitBase | useLocalBase | buildLocal | buildRegistry
|
|
6
|
+
const PKG_NAME = "@bariskuran/base";
|
|
7
|
+
const BASE_SPEC = process.env.BASE_SPEC || `${PKG_NAME}@0.0.2`;
|
|
8
|
+
|
|
9
|
+
function run(cmd) {
|
|
10
|
+
execSync(cmd, { stdio: "inherit" });
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
function runNodeScript(scriptPath) {
|
|
14
|
+
execFileSync(process.execPath, [scriptPath], { stdio: "inherit" });
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function runVite(args) {
|
|
18
|
+
execFileSync(process.execPath, [path.join("node_modules", "vite", "bin", "vite.js"), ...args], {
|
|
19
|
+
stdio: "inherit",
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
function runSilent(cmd) {
|
|
24
|
+
try {
|
|
25
|
+
execSync(cmd, { stdio: "ignore" });
|
|
26
|
+
return true;
|
|
27
|
+
} catch {
|
|
28
|
+
return false;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function startViteDev() {
|
|
33
|
+
runVite([]);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function buildVite() {
|
|
37
|
+
runVite(["build"]);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
function formatRouteFiles() {
|
|
41
|
+
execFileSync(
|
|
42
|
+
process.execPath,
|
|
43
|
+
[path.join("node_modules", "prettier", "bin", "prettier.cjs"), "--write", "src/views/**/route.js"],
|
|
44
|
+
{ stdio: "inherit" },
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function generateRouteMetadata() {
|
|
49
|
+
runNodeScript("routes_auto_fill.cjs");
|
|
50
|
+
formatRouteFiles();
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function ensureGitBaseInstalled() {
|
|
54
|
+
runSilent(`yarn unlink "${PKG_NAME}"`);
|
|
55
|
+
run(`yarn add "${BASE_SPEC}"`);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function switchToLocalLink() {
|
|
59
|
+
runSilent(`yarn remove "${PKG_NAME}"`);
|
|
60
|
+
run(`yarn link "${PKG_NAME}"`);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function usageAndExit() {
|
|
64
|
+
process.exit(1);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
function assertSupportedNode() {
|
|
68
|
+
const [major] = process.versions.node.split(".").map(Number);
|
|
69
|
+
const isSupported = major >= 23;
|
|
70
|
+
|
|
71
|
+
if (!isSupported) {
|
|
72
|
+
console.error(
|
|
73
|
+
`Node ${process.versions.node} is too old for this project. Use Node >=23.0.0, then rerun this command.`,
|
|
74
|
+
);
|
|
75
|
+
process.exit(1);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if (!MODE) usageAndExit();
|
|
80
|
+
|
|
81
|
+
assertSupportedNode();
|
|
82
|
+
|
|
83
|
+
if (MODE === "useGitBase") {
|
|
84
|
+
console.log(`🔁 Using GIT/registry base: ${BASE_SPEC}`);
|
|
85
|
+
ensureGitBaseInstalled();
|
|
86
|
+
console.log("🚀 Starting Vite dev server…");
|
|
87
|
+
startViteDev();
|
|
88
|
+
process.exit(0);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
if (MODE === "useLocalBase") {
|
|
92
|
+
console.log("🔁 Switching to LOCAL linked base…");
|
|
93
|
+
switchToLocalLink();
|
|
94
|
+
console.log("🚀 Starting Vite dev server…");
|
|
95
|
+
startViteDev();
|
|
96
|
+
process.exit(0);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (MODE === "buildLocal") {
|
|
100
|
+
console.log("🏗️ Build with LOCAL linked base.");
|
|
101
|
+
|
|
102
|
+
let buildSucceeded = false;
|
|
103
|
+
try {
|
|
104
|
+
switchToLocalLink();
|
|
105
|
+
console.log("🧭 Generating route metadata…");
|
|
106
|
+
generateRouteMetadata();
|
|
107
|
+
console.log("📦 Running vite build…");
|
|
108
|
+
buildVite();
|
|
109
|
+
buildSucceeded = true;
|
|
110
|
+
console.log("✅ Build completed.");
|
|
111
|
+
} finally {
|
|
112
|
+
if (!buildSucceeded) {
|
|
113
|
+
console.log("⚠️ Build failed; keeping current dependency state.");
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
process.exit(buildSucceeded ? 0 : 1);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
if (MODE === "buildRegistry") {
|
|
121
|
+
console.log(`🏗️ Build with GIT/registry base: ${BASE_SPEC}`);
|
|
122
|
+
|
|
123
|
+
let buildSucceeded = false;
|
|
124
|
+
try {
|
|
125
|
+
ensureGitBaseInstalled();
|
|
126
|
+
console.log("🧭 Generating route metadata…");
|
|
127
|
+
generateRouteMetadata();
|
|
128
|
+
console.log("📦 Running vite build…");
|
|
129
|
+
buildVite();
|
|
130
|
+
buildSucceeded = true;
|
|
131
|
+
console.log("✅ Build completed.");
|
|
132
|
+
} finally {
|
|
133
|
+
if (buildSucceeded) {
|
|
134
|
+
console.log("🔁 Switching back to LOCAL linked base…");
|
|
135
|
+
switchToLocalLink();
|
|
136
|
+
console.log("✅ Local link enabled.");
|
|
137
|
+
} else {
|
|
138
|
+
console.log("⚠️ Build failed; keeping current dependency state (no auto relink).");
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
process.exit(buildSucceeded ? 0 : 1);
|
|
143
|
+
}
|
|
144
|
+
usageAndExit();
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { fixupConfigRules, fixupPluginRules } from "@eslint/compat";
|
|
2
|
+
import globals from "globals";
|
|
3
|
+
import js from "@eslint/js";
|
|
4
|
+
import { FlatCompat } from "@eslint/eslintrc";
|
|
5
|
+
|
|
6
|
+
import react from "eslint-plugin-react";
|
|
7
|
+
import reactHooks from "eslint-plugin-react-hooks";
|
|
8
|
+
import path from "node:path";
|
|
9
|
+
import { fileURLToPath } from "node:url";
|
|
10
|
+
|
|
11
|
+
const compat = new FlatCompat({
|
|
12
|
+
baseDirectory: path.dirname(fileURLToPath(import.meta.url)),
|
|
13
|
+
recommendedConfig: js.configs.recommended,
|
|
14
|
+
allConfig: js.configs.all,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
export default [
|
|
18
|
+
{
|
|
19
|
+
ignores: ["**/dist", "**/.eslintrc.cjs", "**/_notlar.js"],
|
|
20
|
+
},
|
|
21
|
+
...fixupConfigRules(
|
|
22
|
+
compat.extends(
|
|
23
|
+
"eslint:recommended",
|
|
24
|
+
"plugin:react/recommended",
|
|
25
|
+
"plugin:react/jsx-runtime",
|
|
26
|
+
"plugin:react-hooks/recommended",
|
|
27
|
+
),
|
|
28
|
+
),
|
|
29
|
+
{
|
|
30
|
+
files: ["**/*.{js,jsx}"],
|
|
31
|
+
plugins: {
|
|
32
|
+
react: fixupPluginRules(react),
|
|
33
|
+
"react-hooks": fixupPluginRules(reactHooks),
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
languageOptions: {
|
|
37
|
+
globals: {
|
|
38
|
+
...globals.browser,
|
|
39
|
+
process: true,
|
|
40
|
+
},
|
|
41
|
+
|
|
42
|
+
ecmaVersion: "latest",
|
|
43
|
+
sourceType: "module",
|
|
44
|
+
},
|
|
45
|
+
|
|
46
|
+
settings: {
|
|
47
|
+
react: {
|
|
48
|
+
version: "^18.3.1",
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
|
|
52
|
+
rules: {
|
|
53
|
+
"react-hooks/refs": "off",
|
|
54
|
+
"react/no-children-prop": "off",
|
|
55
|
+
"react/no-unescaped-entities": "off",
|
|
56
|
+
"no-unreachable": "warn",
|
|
57
|
+
"no-var": "error",
|
|
58
|
+
"no-undef": "error",
|
|
59
|
+
"no-unused-vars": "warn",
|
|
60
|
+
"react-hooks/exhaustive-deps": "off",
|
|
61
|
+
|
|
62
|
+
"react/jsx-no-undef": [
|
|
63
|
+
"error",
|
|
64
|
+
{
|
|
65
|
+
allowGlobals: true,
|
|
66
|
+
},
|
|
67
|
+
],
|
|
68
|
+
|
|
69
|
+
"react/jsx-curly-brace-presence": [
|
|
70
|
+
"error",
|
|
71
|
+
{
|
|
72
|
+
children: "ignore",
|
|
73
|
+
props: "never",
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
|
|
77
|
+
"react/jsx-no-bind": [
|
|
78
|
+
"error",
|
|
79
|
+
{
|
|
80
|
+
allowArrowFunctions: true,
|
|
81
|
+
},
|
|
82
|
+
],
|
|
83
|
+
|
|
84
|
+
"react/jsx-no-literals": "off",
|
|
85
|
+
"react/jsx-no-target-blank": "off",
|
|
86
|
+
"react/no-deprecated": "off",
|
|
87
|
+
"react/prop-types": "off",
|
|
88
|
+
"prettier/prettier": "off",
|
|
89
|
+
"require-await": "error",
|
|
90
|
+
"space-before-function-paren": "off",
|
|
91
|
+
"no-prototype-builtins": "warn",
|
|
92
|
+
"react/jsx-runtime": "off",
|
|
93
|
+
"react/jsx-filename-extension": [0],
|
|
94
|
+
},
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
files: ["**/.eslintrc.{js,cjs}"],
|
|
98
|
+
|
|
99
|
+
languageOptions: {
|
|
100
|
+
globals: {
|
|
101
|
+
...globals.node,
|
|
102
|
+
process: true,
|
|
103
|
+
},
|
|
104
|
+
|
|
105
|
+
ecmaVersion: 5,
|
|
106
|
+
sourceType: "commonjs",
|
|
107
|
+
},
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
files: ["**/*.js"],
|
|
111
|
+
rules: {
|
|
112
|
+
// ❌ JSX is forbidden in .js files
|
|
113
|
+
"react/jsx-filename-extension": ["error", { extensions: [".jsx"] }],
|
|
114
|
+
},
|
|
115
|
+
},
|
|
116
|
+
];
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta property="og:type" content="website" />
|
|
5
|
+
<meta charset="utf-8" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no" />
|
|
7
|
+
<meta name="author" content="%VITE_DEVELOPER_NAME%" />
|
|
8
|
+
|
|
9
|
+
<title>%VITE_SITE_TITLE%</title>
|
|
10
|
+
<meta property="og:title" content="%VITE_SITE_TITLE%" />
|
|
11
|
+
<meta name="description" content="%VITE_SITE_DESCRIPTION%" />
|
|
12
|
+
<meta property="og:description" content="%VITE_SITE_DESCRIPTION%" />
|
|
13
|
+
|
|
14
|
+
<meta property="og:image" content="%VITE_SITE_URL%/og-cover.jpg?v=2" />
|
|
15
|
+
<meta property="og:image:width" content="1200" />
|
|
16
|
+
<meta property="og:image:height" content="630" />
|
|
17
|
+
|
|
18
|
+
<meta name="twitter:card" content="summary_large_image" />
|
|
19
|
+
|
|
20
|
+
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
|
21
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
22
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
23
|
+
</head>
|
|
24
|
+
|
|
25
|
+
<body>
|
|
26
|
+
<div id="root"></div>
|
|
27
|
+
<script type="module" src="/src/main.jsx"></script>
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
6
|
+
"jsx": "react-jsx",
|
|
7
|
+
"moduleResolution": "bundler",
|
|
8
|
+
"allowJs": true,
|
|
9
|
+
"checkJs": false,
|
|
10
|
+
"strict": false,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true,
|
|
14
|
+
"resolveJsonModule": true,
|
|
15
|
+
"isolatedModules": true,
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"paths": {
|
|
18
|
+
"base": ["./node_modules/@bariskuran/base"],
|
|
19
|
+
"global": ["./src/global"],
|
|
20
|
+
"global/*": ["./src/global/*"],
|
|
21
|
+
"components": ["./src/components"],
|
|
22
|
+
"components/*": ["./src/components/*"],
|
|
23
|
+
"images": ["./src/images"],
|
|
24
|
+
"images/*": ["./src/images/*"],
|
|
25
|
+
"views": ["./src/views"],
|
|
26
|
+
"views/*": ["./src/views/*"],
|
|
27
|
+
"hooks": ["./src/hooks"],
|
|
28
|
+
"hooks/*": ["./src/hooks/*"],
|
|
29
|
+
"functions": ["./src/functions"],
|
|
30
|
+
"functions/*": ["./src/functions/*"],
|
|
31
|
+
"assets": ["./src/assets"],
|
|
32
|
+
"assets/*": ["./src/assets/*"]
|
|
33
|
+
},
|
|
34
|
+
"typeRoots": ["./node_modules/@types"]
|
|
35
|
+
},
|
|
36
|
+
"include": ["src/**/*"],
|
|
37
|
+
"exclude": ["node_modules", "dist"]
|
|
38
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "[PROJECT_NAME]",
|
|
3
|
+
"description": "[PROJECT_DESCRIPTION]",
|
|
4
|
+
"author": "[DEVELOPER_NAME] <[DEVELOPER_CONTACT]>",
|
|
5
|
+
"private": false,
|
|
6
|
+
"version": "0.1.0",
|
|
7
|
+
"license": "MIT",
|
|
8
|
+
"engines": {
|
|
9
|
+
"node": ">=23.0.0"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"start:original": "vite",
|
|
13
|
+
"build:original": "vite build",
|
|
14
|
+
"start": "node builder.cjs useGitBase",
|
|
15
|
+
"start:local": "node builder.cjs useLocalBase",
|
|
16
|
+
"build": "node builder.cjs buildRegistry",
|
|
17
|
+
"build:local": "node builder.cjs buildLocal",
|
|
18
|
+
"autoFill": "node routes_auto_fill.cjs && prettier --write \"src/views/**/route.js\"",
|
|
19
|
+
"images:index": "node node_modules/@bariskuran/base/src/libs/createImageCatalog/tools/base-image-index.cjs"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"antd": "^6.3.0",
|
|
23
|
+
"react": "19.2.3",
|
|
24
|
+
"react-dom": "19.2.3",
|
|
25
|
+
"react-router-dom": "7.12.0",
|
|
26
|
+
"styled-components": "^6.3.8",
|
|
27
|
+
"@bariskuran/base": "0.0.2"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@eslint/compat": "2.0.1",
|
|
31
|
+
"@eslint/eslintrc": "3.3.0",
|
|
32
|
+
"@eslint/js": "9.39.2",
|
|
33
|
+
"@vitejs/plugin-react": "5.1.2",
|
|
34
|
+
"eslint": "9.39.2",
|
|
35
|
+
"eslint-plugin-import": "2.32.0",
|
|
36
|
+
"eslint-plugin-react": "7.37.5",
|
|
37
|
+
"eslint-plugin-react-hooks": "7.0.1",
|
|
38
|
+
"globals": "17.0.0",
|
|
39
|
+
"prettier": "3.8.1",
|
|
40
|
+
"react-syntax-highlighter": "16.1.0",
|
|
41
|
+
"vite": "7.3.1",
|
|
42
|
+
"vite-plugin-eslint": "1.8.1"
|
|
43
|
+
},
|
|
44
|
+
"resolutions": {
|
|
45
|
+
"browserslist": "4.28.1",
|
|
46
|
+
"caniuse-lite": "1.0.30001765"
|
|
47
|
+
},
|
|
48
|
+
"proxy": "http://localhost:3000"
|
|
49
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 64 64">
|
|
3
|
+
<!-- Generator: Adobe Illustrator 30.8.2, SVG Export Plug-In . SVG Version: 2.1.4 Build 7) -->
|
|
4
|
+
<defs>
|
|
5
|
+
<style>
|
|
6
|
+
.st0 {
|
|
7
|
+
fill: #2c2a29;
|
|
8
|
+
}
|
|
9
|
+
</style>
|
|
10
|
+
</defs>
|
|
11
|
+
<circle class="st0" cx="32" cy="32" r="26.06"/>
|
|
12
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Base, createImageCatalog } from "base";
|
|
2
|
+
import { PROJECT_SETTINGS } from "global/PROJECT_SETTINGS";
|
|
3
|
+
import imageCatalog from "./imageCatalog";
|
|
4
|
+
|
|
5
|
+
createImageCatalog(imageCatalog);
|
|
6
|
+
|
|
7
|
+
const App = () => <Base projectSettings={PROJECT_SETTINGS} />;
|
|
8
|
+
export default App;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Outlet, ScrollBar, Suspense } from "base";
|
|
2
|
+
import { NavigationContext } from "./NavigationContext";
|
|
3
|
+
import { SuspenceFallback } from "../SuspenceFallback";
|
|
4
|
+
|
|
5
|
+
export const Layout = () => {
|
|
6
|
+
/* Return */
|
|
7
|
+
return (
|
|
8
|
+
<span style={{ display: "contents" }}>
|
|
9
|
+
<ScrollBar.primary body maxLength={40} fillMode />
|
|
10
|
+
<NavigationContext.Provider value={{}}>
|
|
11
|
+
<Suspense fallback={<SuspenceFallback />}>
|
|
12
|
+
<Outlet />
|
|
13
|
+
</Suspense>
|
|
14
|
+
</NavigationContext.Provider>
|
|
15
|
+
</span>
|
|
16
|
+
);
|
|
17
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { styled, t } from "base";
|
|
2
|
+
|
|
3
|
+
const S = {
|
|
4
|
+
suspenseContainer: styled.div`
|
|
5
|
+
width: 100%;
|
|
6
|
+
min-height: 100vh;
|
|
7
|
+
background: black;
|
|
8
|
+
color: white;
|
|
9
|
+
display: flex;
|
|
10
|
+
position: relative;
|
|
11
|
+
align-items: center;
|
|
12
|
+
justify-content: center;
|
|
13
|
+
`,
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
export const SuspenceFallback = () => <S.suspenseContainer>{t("loading")}</S.suspenseContainer>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Icon library definition used by the Base Design System.
|
|
3
|
+
*
|
|
4
|
+
* Each icon entry is defined as a tuple with **three fixed positions**:
|
|
5
|
+
*
|
|
6
|
+
* `[0] viewBox` SVG viewBox value. **Consistency rule:** width **or** height MUST be max `20`
|
|
7
|
+
* `[1] svgPath` SVG `<path d="...">` definition. No `<svg>` wrapper
|
|
8
|
+
* `[2] searchKeywords` (optional) Keywords used **only for search / filtering** in development tools.
|
|
9
|
+
* - Used by `localhost:3000/baseDesignSystem/icons` explorer
|
|
10
|
+
*
|
|
11
|
+
* ```js
|
|
12
|
+
* import { Icon } from "base";
|
|
13
|
+
* <Icon icon="arrowDown" width={16} />
|
|
14
|
+
* ```
|
|
15
|
+
*
|
|
16
|
+
* ### `<Icon />` Props
|
|
17
|
+
*
|
|
18
|
+
* @param {string} icon - Icon name (key of ICONS_LIBRARY)
|
|
19
|
+
* @param {number} [width=10] - Icon width (height auto-calculated unless `useHeight` is true)
|
|
20
|
+
* @param {string} [color] - Icon color (defaults to theme foreground color)
|
|
21
|
+
* @param {string} [onHoverColor] - Color applied on hover
|
|
22
|
+
* @param {Object} [style] - Inline style object
|
|
23
|
+
* @param {boolean} [useHeight=false] - Uses height instead of width for scaling
|
|
24
|
+
*/
|
|
25
|
+
export const ICONS_LIBRARY = {
|
|
26
|
+
// example: [
|
|
27
|
+
// "20 20",
|
|
28
|
+
// "d",
|
|
29
|
+
// ["logo"],
|
|
30
|
+
// ],
|
|
31
|
+
};
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import { ICONS_LIBRARY } from "./ICONS_LIBRARY";
|
|
2
|
+
import { css } from "base";
|
|
3
|
+
import { TEXT_LIBRARY } from "./TEXT_LIBRARY";
|
|
4
|
+
import { SuspenceFallback } from "components/SuspenceFallback";
|
|
5
|
+
import { Layout } from "components/Layout";
|
|
6
|
+
import { SITEMAP } from "./SITEMAP";
|
|
7
|
+
|
|
8
|
+
export const PROJECT_SETTINGS = {
|
|
9
|
+
SuspenseFallback: <SuspenceFallback />,
|
|
10
|
+
/** Text Library */
|
|
11
|
+
textLibrary: TEXT_LIBRARY,
|
|
12
|
+
|
|
13
|
+
/** RRD Settings */
|
|
14
|
+
rrdSettings: {
|
|
15
|
+
Layout: Layout,
|
|
16
|
+
SITEMAP: SITEMAP,
|
|
17
|
+
overridePrepareRoutes: null,
|
|
18
|
+
},
|
|
19
|
+
|
|
20
|
+
// languageSettings
|
|
21
|
+
languageSettings: {
|
|
22
|
+
defaultLanguage: "tr",
|
|
23
|
+
ignoreClientLanguage: true,
|
|
24
|
+
languageList: ["tr", "en"],
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
// baseDateSettings
|
|
28
|
+
baseDateSettings: {
|
|
29
|
+
disable: false,
|
|
30
|
+
defaultFormat: "|DD|-|MM|-|YYYY|",
|
|
31
|
+
defaultTimeZone: "UTC",
|
|
32
|
+
firstDayOfWeek: 1, // monday
|
|
33
|
+
},
|
|
34
|
+
|
|
35
|
+
// iconsLibrary
|
|
36
|
+
iconsLibrary: ICONS_LIBRARY,
|
|
37
|
+
|
|
38
|
+
// idleManagerSettings
|
|
39
|
+
idleManagerSettings: {
|
|
40
|
+
enabled: true,
|
|
41
|
+
allowedIdleTime: 30, // mins
|
|
42
|
+
onIdle: () => {
|
|
43
|
+
console.log("onIdle");
|
|
44
|
+
},
|
|
45
|
+
onActive: () => {
|
|
46
|
+
console.log("onActive");
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
|
|
50
|
+
// notifierManager Settings
|
|
51
|
+
notifierSettings: {
|
|
52
|
+
killAfter: 5, // secs
|
|
53
|
+
// disableNotifier: true,
|
|
54
|
+
// disableAutoKill: true,
|
|
55
|
+
closingDelay: 0.5, // secs
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
// Suspence Settings
|
|
59
|
+
otherSuspenseProps: {},
|
|
60
|
+
|
|
61
|
+
// baseFetch Settings
|
|
62
|
+
baseFetchSettings: {
|
|
63
|
+
disableApiLoading: false,
|
|
64
|
+
disableAuth: true,
|
|
65
|
+
getTokenFrom: () => {},
|
|
66
|
+
token: null,
|
|
67
|
+
cacheTime: 10, // mins
|
|
68
|
+
},
|
|
69
|
+
|
|
70
|
+
// styledComponents Settings
|
|
71
|
+
styledSettings: {
|
|
72
|
+
// breakpoints,
|
|
73
|
+
//maxAspRatio,
|
|
74
|
+
//minAspRatio,
|
|
75
|
+
//remSettings,
|
|
76
|
+
fonts: {
|
|
77
|
+
primaryFont: css`
|
|
78
|
+
@import url("https://fonts.googleapis.com/css2?family=Montserrat:wght@300;400;500;700&display=swap");
|
|
79
|
+
font-family: "Montserrat", sans-serif !important;
|
|
80
|
+
font-size: 14rem;
|
|
81
|
+
font-weight: 400;
|
|
82
|
+
line-height: 1.75;
|
|
83
|
+
`,
|
|
84
|
+
openSans: css`
|
|
85
|
+
@import url("https://fonts.googleapis.com/css2?family=Open+Sans:wght@300;400;500;700&display=swap");
|
|
86
|
+
font-family: "Open Sans", sans-serif !important;
|
|
87
|
+
font-size: 14rem;
|
|
88
|
+
font-weight: 400;
|
|
89
|
+
line-height: 1.75;
|
|
90
|
+
`,
|
|
91
|
+
},
|
|
92
|
+
globalStyle: css`
|
|
93
|
+
html,
|
|
94
|
+
body {
|
|
95
|
+
margin: 0;
|
|
96
|
+
height: auto;
|
|
97
|
+
min-height: 100vh;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
#root {
|
|
101
|
+
width: 100%;
|
|
102
|
+
height: auto;
|
|
103
|
+
min-height: 100vh;
|
|
104
|
+
overflow: unset;
|
|
105
|
+
display: flex;
|
|
106
|
+
flex-direction: column;
|
|
107
|
+
align-items: flex-start;
|
|
108
|
+
justify-content: flex-start;
|
|
109
|
+
}
|
|
110
|
+
`,
|
|
111
|
+
themes: {
|
|
112
|
+
light: {
|
|
113
|
+
_props: {
|
|
114
|
+
isDefault: true,
|
|
115
|
+
label: { tr: "Açık Tonlar", en: "Light Theme" },
|
|
116
|
+
},
|
|
117
|
+
background: "#E0E0E0",
|
|
118
|
+
foreground: "#17181c",
|
|
119
|
+
grey: "#3A3A3A",
|
|
120
|
+
primary: "#ff6f00",
|
|
121
|
+
secondary: "#305664",
|
|
122
|
+
error: "#803939",
|
|
123
|
+
success: "#146314",
|
|
124
|
+
warning: "#7C5A07",
|
|
125
|
+
},
|
|
126
|
+
dark: {
|
|
127
|
+
_props: {
|
|
128
|
+
label: { tr: "Koyu Tonlar", en: "Dark Theme" },
|
|
129
|
+
},
|
|
130
|
+
background: "#17181c",
|
|
131
|
+
foreground: "#E0E0E0",
|
|
132
|
+
primary: "#ffbf00",
|
|
133
|
+
secondary: "#305A7A",
|
|
134
|
+
},
|
|
135
|
+
},
|
|
136
|
+
makeAntdTheme: (t) => ({
|
|
137
|
+
token: {
|
|
138
|
+
colorPrimary: t.primary,
|
|
139
|
+
colorSuccess: t.success,
|
|
140
|
+
colorWarning: t.warning,
|
|
141
|
+
colorError: t.error,
|
|
142
|
+
|
|
143
|
+
colorText: t.foreground,
|
|
144
|
+
colorTextBase: t.foreground,
|
|
145
|
+
|
|
146
|
+
colorBgBase: t.background,
|
|
147
|
+
colorBgContainer: t.background,
|
|
148
|
+
colorBorder: t.grey,
|
|
149
|
+
},
|
|
150
|
+
}),
|
|
151
|
+
},
|
|
152
|
+
|
|
153
|
+
// BaseForm Settings
|
|
154
|
+
baseFormSettings: {
|
|
155
|
+
HelperComponent: null,
|
|
156
|
+
helperMode: "auto", // auto, enabled, disabled -- default is auto
|
|
157
|
+
},
|
|
158
|
+
|
|
159
|
+
// Validation Rules
|
|
160
|
+
validationRules: {},
|
|
161
|
+
|
|
162
|
+
// Default Variants
|
|
163
|
+
defaultVariants: {},
|
|
164
|
+
|
|
165
|
+
// adminSettings
|
|
166
|
+
adminSettings: {
|
|
167
|
+
showInternalDs: true, // allows to show internal ds in development. // to enable it externally, set .env VITE_ENABLE_DESIGN_SYSTEM=true
|
|
168
|
+
},
|
|
169
|
+
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import Home from "views/home/_route";
|
|
2
|
+
|
|
3
|
+
export const SITEMAP = [Home];
|
|
4
|
+
|
|
5
|
+
const flattenRoutes = (routes) =>
|
|
6
|
+
routes.flatMap((route) => {
|
|
7
|
+
const childRoutes = route.children ? flattenRoutes(route.children) : [];
|
|
8
|
+
return route.handle?.id ? [route, ...childRoutes] : childRoutes;
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
const createRouteMapById = (routes) =>
|
|
12
|
+
flattenRoutes(routes).reduce((acc, route) => {
|
|
13
|
+
if (!acc[route.handle.id]) acc[route.handle.id] = route;
|
|
14
|
+
return acc;
|
|
15
|
+
}, {});
|
|
16
|
+
|
|
17
|
+
export const ROUTE_BY_ID = createRouteMapById(SITEMAP);
|
|
18
|
+
|
|
19
|
+
export const ROUTE_HANDLE_BY_ID = Object.fromEntries(
|
|
20
|
+
Object.entries(ROUTE_BY_ID).map(([id, route]) => [id, route.handle]),
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
export const getRouteHandlesByIds = (ids) => {
|
|
24
|
+
if (!ids) return null;
|
|
25
|
+
return ids.map((id) => ROUTE_HANDLE_BY_ID[id]).filter(Boolean);
|
|
26
|
+
};
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
// Auto Generated by `yarn images:index`
|
|
2
|
+
import thumb from "./thumb.webp";
|
|
3
|
+
import small from "./small.webp";
|
|
4
|
+
import large from "./large.webp";
|
|
5
|
+
import ultra from "./ultra.webp";
|
|
6
|
+
|
|
7
|
+
const image = {
|
|
8
|
+
alt: "",
|
|
9
|
+
keywords: [],
|
|
10
|
+
|
|
11
|
+
// Auto Generated by `yarn images:index`
|
|
12
|
+
shape: "portrait",
|
|
13
|
+
imageSet: {
|
|
14
|
+
"thumb": {
|
|
15
|
+
key: "thumb",
|
|
16
|
+
src: thumb,
|
|
17
|
+
naturalWidth: 320,
|
|
18
|
+
naturalHeight: 213,
|
|
19
|
+
aRatio: 1.5,
|
|
20
|
+
type: "image/webp",
|
|
21
|
+
sizeBytes: 780,
|
|
22
|
+
sizeKBytes: 0.76,
|
|
23
|
+
sizeMBytes: 0.001,
|
|
24
|
+
shape: "landscape",
|
|
25
|
+
},
|
|
26
|
+
"small": {
|
|
27
|
+
key: "small",
|
|
28
|
+
src: small,
|
|
29
|
+
naturalWidth: 640,
|
|
30
|
+
naturalHeight: 1137,
|
|
31
|
+
aRatio: 0.6,
|
|
32
|
+
type: "image/webp",
|
|
33
|
+
sizeBytes: 2640,
|
|
34
|
+
sizeKBytes: 2.58,
|
|
35
|
+
sizeMBytes: 0.003,
|
|
36
|
+
shape: "portrait",
|
|
37
|
+
},
|
|
38
|
+
"large": {
|
|
39
|
+
key: "large",
|
|
40
|
+
src: large,
|
|
41
|
+
naturalWidth: 1138,
|
|
42
|
+
naturalHeight: 2024,
|
|
43
|
+
aRatio: 0.6,
|
|
44
|
+
type: "image/webp",
|
|
45
|
+
sizeBytes: 6614,
|
|
46
|
+
sizeKBytes: 6.46,
|
|
47
|
+
sizeMBytes: 0.006,
|
|
48
|
+
shape: "portrait",
|
|
49
|
+
},
|
|
50
|
+
"ultra": {
|
|
51
|
+
key: "ultra",
|
|
52
|
+
src: ultra,
|
|
53
|
+
naturalWidth: 2699,
|
|
54
|
+
naturalHeight: 4048,
|
|
55
|
+
aRatio: 0.7,
|
|
56
|
+
type: "image/webp",
|
|
57
|
+
sizeBytes: 25572,
|
|
58
|
+
sizeKBytes: 24.97,
|
|
59
|
+
sizeMBytes: 0.024,
|
|
60
|
+
shape: "portrait",
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
export default image;
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { lazy } from "base";
|
|
2
|
+
const Component = lazy(() => import("./index.jsx"));
|
|
3
|
+
|
|
4
|
+
const title = {
|
|
5
|
+
tr: "",
|
|
6
|
+
en: "",
|
|
7
|
+
};
|
|
8
|
+
const path = { tr: "/", en: "/" };
|
|
9
|
+
|
|
10
|
+
const route = { Component, path, handle: { isHome: true, title, path } };
|
|
11
|
+
export default route;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/* global console */
|
|
2
|
+
|
|
3
|
+
// vite.config.mjs
|
|
4
|
+
import { defineConfig } from "vite";
|
|
5
|
+
import react from "@vitejs/plugin-react";
|
|
6
|
+
import eslint from "vite-plugin-eslint";
|
|
7
|
+
import { bariskuranBaseAliases, bariskuranBaseResolvePlugin } from "@bariskuran/base/vite";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import path from "path";
|
|
10
|
+
|
|
11
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
+
const __dirname = path.dirname(__filename);
|
|
13
|
+
const baseSourceRoot = path.resolve(__dirname, "../base/src");
|
|
14
|
+
|
|
15
|
+
const isBaseModule = (id = "") => id.startsWith(baseSourceRoot);
|
|
16
|
+
const isImage = (name = "") => /\.(avif|gif|jpe?g|png|svg|webp)$/i.test(name);
|
|
17
|
+
|
|
18
|
+
const getAssetSourceNames = (asset) => [
|
|
19
|
+
...(asset.originalFileNames || []),
|
|
20
|
+
...(asset.names || []),
|
|
21
|
+
asset.name || "",
|
|
22
|
+
];
|
|
23
|
+
|
|
24
|
+
export default defineConfig(({ command }) => ({
|
|
25
|
+
test: {
|
|
26
|
+
environment: "jsdom",
|
|
27
|
+
setupFiles: "./vitest.setup.js",
|
|
28
|
+
globals: true,
|
|
29
|
+
restoreMocks: true,
|
|
30
|
+
clearMocks: true,
|
|
31
|
+
mockReset: true,
|
|
32
|
+
},
|
|
33
|
+
|
|
34
|
+
resolve: {
|
|
35
|
+
dedupe: ["react", "react-dom", "react-router-dom", "styled-components"],
|
|
36
|
+
extensions: [".mjs", ".js", ".jsx", ".json"],
|
|
37
|
+
alias: {
|
|
38
|
+
base: "@bariskuran/base",
|
|
39
|
+
...bariskuranBaseAliases(),
|
|
40
|
+
src: "/src",
|
|
41
|
+
global: "/src/global",
|
|
42
|
+
components: "/src/components",
|
|
43
|
+
images: "/src/images",
|
|
44
|
+
views: "/src/views",
|
|
45
|
+
hooks: "/src/hooks",
|
|
46
|
+
functions: "/src/functions",
|
|
47
|
+
assets: "/src/assets",
|
|
48
|
+
},
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
server: {
|
|
52
|
+
host: true, // networkte erişilebilir hale getirir
|
|
53
|
+
port: 3000,
|
|
54
|
+
sourcemapIgnoreList: false, // Tüm dosyaları source map'te göster
|
|
55
|
+
},
|
|
56
|
+
|
|
57
|
+
// Development için detaylı source map
|
|
58
|
+
css: {
|
|
59
|
+
devSourcemap: true,
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
plugins: [
|
|
63
|
+
bariskuranBaseResolvePlugin(),
|
|
64
|
+
react({
|
|
65
|
+
jsxRuntime: "automatic",
|
|
66
|
+
}),
|
|
67
|
+
eslint({
|
|
68
|
+
include: [`${path.resolve(__dirname, "")}/**/*.{js,jsx}`],
|
|
69
|
+
}),
|
|
70
|
+
],
|
|
71
|
+
|
|
72
|
+
optimizeDeps: {
|
|
73
|
+
force: true,
|
|
74
|
+
exclude: ["_backUp/*"],
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
// Inline maps are useful in development but add the full source map to every
|
|
78
|
+
// production JavaScript file.
|
|
79
|
+
esbuild: {
|
|
80
|
+
jsx: "automatic",
|
|
81
|
+
sourcemap: command === "serve" ? "inline" : false,
|
|
82
|
+
},
|
|
83
|
+
|
|
84
|
+
build: {
|
|
85
|
+
sourcemap: true, // Build için source map
|
|
86
|
+
minify: "esbuild",
|
|
87
|
+
rollupOptions: {
|
|
88
|
+
output: {
|
|
89
|
+
entryFileNames: "chunks/[name]-[hash].js",
|
|
90
|
+
chunkFileNames: (chunk) => {
|
|
91
|
+
const moduleIds = chunk.moduleIds || [];
|
|
92
|
+
const isBaseChunk = moduleIds.length > 0 && moduleIds.every(isBaseModule);
|
|
93
|
+
|
|
94
|
+
return isBaseChunk ? "base/[name]-[hash].js" : "chunks/[name]-[hash].js";
|
|
95
|
+
},
|
|
96
|
+
assetFileNames: (asset) => {
|
|
97
|
+
const sourceNames = getAssetSourceNames(asset);
|
|
98
|
+
|
|
99
|
+
if (sourceNames.some(isBaseModule)) {
|
|
100
|
+
return "base/[name]-[hash][extname]";
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (sourceNames.some(isImage)) {
|
|
104
|
+
return "images/[name]-[hash][extname]";
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return "chunks/[name]-[hash][extname]";
|
|
108
|
+
},
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
}));
|