create-dothtml 6.0.8
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 +25 -0
- package/bin/create-dothtml +3 -0
- package/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +241 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +205 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +46 -0
- package/templates/vanilla-js/eslint.config.js +10 -0
- package/templates/vanilla-js/index.html +12 -0
- package/templates/vanilla-js/package.json +23 -0
- package/templates/vanilla-js/src/components/Counter.js +18 -0
- package/templates/vanilla-js/src/main.js +11 -0
- package/templates/vanilla-js/src/main.test.js +15 -0
- package/templates/vanilla-js/src/style.css +92 -0
- package/templates/vanilla-js/vite.config.js +7 -0
- package/templates/vanilla-ts/eslint.config.js +13 -0
- package/templates/vanilla-ts/index.html +12 -0
- package/templates/vanilla-ts/package.json +25 -0
- package/templates/vanilla-ts/src/components/Counter.ts +19 -0
- package/templates/vanilla-ts/src/main.test.ts +15 -0
- package/templates/vanilla-ts/src/main.ts +11 -0
- package/templates/vanilla-ts/src/style.css +92 -0
- package/templates/vanilla-ts/tsconfig.json +23 -0
- package/templates/vanilla-ts/vite.config.ts +8 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2021 Josh Sideris
|
|
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
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# create-dothtml
|
|
2
|
+
|
|
3
|
+
The official project initializer for [DOThtml](https://dothtml.org/).
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npx create-dothtml <project-name> [options]
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or using `npm init`:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm init dothtml <project-name> -- [options]
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Options
|
|
18
|
+
|
|
19
|
+
- `--js`: Use JavaScript instead of TypeScript (default).
|
|
20
|
+
- `--no-lint`: Skip adding ESLint to the project.
|
|
21
|
+
|
|
22
|
+
## Features
|
|
23
|
+
|
|
24
|
+
- **Vite-powered**: Instant dev server and fast builds.
|
|
25
|
+
- **DOThtml-friendly Linting**: By default, projects include an ESLint configuration that is specifically tuned to allow DOThtml's signature method chaining (disables `newline-per-chained-call`).
|
package/dist/index.d.mts
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
cli: () => cli
|
|
34
|
+
});
|
|
35
|
+
module.exports = __toCommonJS(index_exports);
|
|
36
|
+
var import_fs = __toESM(require("fs"));
|
|
37
|
+
var import_path = __toESM(require("path"));
|
|
38
|
+
var import_url = require("url");
|
|
39
|
+
var import_meta = {};
|
|
40
|
+
var getDirname = () => {
|
|
41
|
+
try {
|
|
42
|
+
return __dirname;
|
|
43
|
+
} catch {
|
|
44
|
+
return import_path.default.dirname((0, import_url.fileURLToPath)(import_meta.url));
|
|
45
|
+
}
|
|
46
|
+
};
|
|
47
|
+
var cc = {
|
|
48
|
+
reset: "\x1B[0m",
|
|
49
|
+
bright: "\x1B[1m",
|
|
50
|
+
dim: "\x1B[2m",
|
|
51
|
+
underscore: "\x1B[4m",
|
|
52
|
+
blink: "\x1B[5m",
|
|
53
|
+
reverse: "\x1B[7m",
|
|
54
|
+
hidden: "\x1B[8m",
|
|
55
|
+
fgBlack: "\x1B[30m",
|
|
56
|
+
fgRed: "\x1B[31m",
|
|
57
|
+
FgGreen: "\x1B[32m",
|
|
58
|
+
fgYellow: "\x1B[33m",
|
|
59
|
+
fgBlue: "\x1B[34m",
|
|
60
|
+
fgMagenta: "\x1B[35m",
|
|
61
|
+
fgCyan: "\x1B[36m",
|
|
62
|
+
fgWhite: "\x1B[37m",
|
|
63
|
+
fgBrightBlack: "\x1B[90m",
|
|
64
|
+
fgBrightRed: "\x1B[91m",
|
|
65
|
+
FgBrightGreen: "\x1B[92m",
|
|
66
|
+
fgBrightYellow: "\x1B[93m",
|
|
67
|
+
fgBrightBlue: "\x1B[94m",
|
|
68
|
+
fgBrightMagenta: "\x1B[95m",
|
|
69
|
+
fgBrightCyan: "\x1B[96m",
|
|
70
|
+
fgBrightWhite: "\x1B[97m"
|
|
71
|
+
};
|
|
72
|
+
async function cli(args) {
|
|
73
|
+
const command = args[2];
|
|
74
|
+
if (command === "generate" || command === "g") {
|
|
75
|
+
handleGenerate(args.slice(3));
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
let projectName = args[2];
|
|
79
|
+
let startIndex = 2;
|
|
80
|
+
if (projectName === "init") {
|
|
81
|
+
projectName = args[3];
|
|
82
|
+
startIndex = 3;
|
|
83
|
+
}
|
|
84
|
+
if (!projectName || projectName === "--help" || projectName === "-h") {
|
|
85
|
+
printUsage();
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const targetDir = import_path.default.resolve(process.cwd(), projectName);
|
|
89
|
+
if (import_fs.default.existsSync(targetDir)) {
|
|
90
|
+
printError(`Directory "${projectName}" already exists.`);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
console.log(`
|
|
94
|
+
Creating a new DOThtml app in ${cc.fgBrightBlue}${targetDir}${cc.reset}...`);
|
|
95
|
+
const argsList = args.slice(startIndex);
|
|
96
|
+
const isJs = argsList.includes("--js");
|
|
97
|
+
const noLint = argsList.includes("--no-lint");
|
|
98
|
+
const template = isJs ? "vanilla-js" : "vanilla-ts";
|
|
99
|
+
const currentDir = getDirname();
|
|
100
|
+
let templateDir = import_path.default.resolve(currentDir, "..", "templates", template);
|
|
101
|
+
if (!import_fs.default.existsSync(templateDir)) {
|
|
102
|
+
templateDir = import_path.default.resolve(currentDir, "templates", template);
|
|
103
|
+
if (!import_fs.default.existsSync(templateDir)) {
|
|
104
|
+
templateDir = import_path.default.resolve(process.cwd(), "templates", template);
|
|
105
|
+
if (!import_fs.default.existsSync(templateDir)) {
|
|
106
|
+
printError(`Template directory not found. Tried:
|
|
107
|
+
- ${import_path.default.resolve(currentDir, "..", "templates", template)}
|
|
108
|
+
- ${import_path.default.resolve(currentDir, "templates", template)}`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
114
|
+
import_fs.default.mkdirSync(targetDir, { recursive: true });
|
|
115
|
+
import_fs.default.cpSync(templateDir, targetDir, { recursive: true });
|
|
116
|
+
const filesToProcess = ["package.json", "index.html"];
|
|
117
|
+
for (const file of filesToProcess) {
|
|
118
|
+
const filePath = import_path.default.join(targetDir, file);
|
|
119
|
+
if (import_fs.default.existsSync(filePath)) {
|
|
120
|
+
let content = import_fs.default.readFileSync(filePath, "utf-8");
|
|
121
|
+
content = content.replace(/{{name}}/g, projectName);
|
|
122
|
+
if (file === "package.json" && noLint) {
|
|
123
|
+
const pkg = JSON.parse(content);
|
|
124
|
+
delete pkg.scripts.lint;
|
|
125
|
+
if (pkg.devDependencies) {
|
|
126
|
+
delete pkg.devDependencies.eslint;
|
|
127
|
+
delete pkg.devDependencies["@eslint/js"];
|
|
128
|
+
delete pkg.devDependencies["typescript-eslint"];
|
|
129
|
+
}
|
|
130
|
+
content = JSON.stringify(pkg, null, 2);
|
|
131
|
+
}
|
|
132
|
+
import_fs.default.writeFileSync(filePath, content);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
if (noLint) {
|
|
136
|
+
const eslintConfigPath = import_path.default.join(targetDir, "eslint.config.js");
|
|
137
|
+
if (import_fs.default.existsSync(eslintConfigPath)) {
|
|
138
|
+
import_fs.default.unlinkSync(eslintConfigPath);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
console.log(`
|
|
142
|
+
${cc.FgGreen}Success!${cc.reset} Created ${projectName} at ${targetDir}`);
|
|
143
|
+
console.log(`Inside that directory, you can run several commands:`);
|
|
144
|
+
console.log(`
|
|
145
|
+
${cc.fgBrightBlue}npm install${cc.reset}`);
|
|
146
|
+
console.log(` Installs the dependencies.`);
|
|
147
|
+
console.log(`
|
|
148
|
+
${cc.fgBrightBlue}npm run dev${cc.reset}`);
|
|
149
|
+
console.log(` Starts the development server.`);
|
|
150
|
+
console.log(`
|
|
151
|
+
${cc.fgBrightBlue}npm test${cc.reset}`);
|
|
152
|
+
console.log(` Runs the test suite using Vitest.`);
|
|
153
|
+
console.log(`
|
|
154
|
+
${cc.fgBrightBlue}npm run build${cc.reset}`);
|
|
155
|
+
console.log(` Bundles the app into static files for production.`);
|
|
156
|
+
if (!noLint) {
|
|
157
|
+
console.log(`
|
|
158
|
+
${cc.fgBrightBlue}npm run lint${cc.reset}`);
|
|
159
|
+
console.log(` Checks the code for potential errors.`);
|
|
160
|
+
}
|
|
161
|
+
console.log(`
|
|
162
|
+
We suggest that you begin by typing:`);
|
|
163
|
+
console.log(`
|
|
164
|
+
${cc.fgBrightBlue}cd${cc.reset} ${projectName}`);
|
|
165
|
+
console.log(` ${cc.fgBrightBlue}npm install${cc.reset}`);
|
|
166
|
+
console.log(` ${cc.fgBrightBlue}npm run dev${cc.reset}
|
|
167
|
+
`);
|
|
168
|
+
} catch (err) {
|
|
169
|
+
printError(`Error creating project: ${err.message}`);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
function handleGenerate(args) {
|
|
173
|
+
const type = args[0];
|
|
174
|
+
const name = args[1];
|
|
175
|
+
if (type !== "component" || !name) {
|
|
176
|
+
console.log(`
|
|
177
|
+
${cc.bright}USAGE${cc.reset}`);
|
|
178
|
+
console.log(` npx create-dothtml generate component <name>
|
|
179
|
+
`);
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const isTs = import_fs.default.existsSync(import_path.default.join(process.cwd(), "tsconfig.json"));
|
|
183
|
+
const ext = isTs ? "ts" : "js";
|
|
184
|
+
const componentsDir = import_path.default.join(process.cwd(), "src", "components");
|
|
185
|
+
if (!import_fs.default.existsSync(componentsDir)) {
|
|
186
|
+
import_fs.default.mkdirSync(componentsDir, { recursive: true });
|
|
187
|
+
}
|
|
188
|
+
const filePath = import_path.default.join(componentsDir, `${name}.${ext}`);
|
|
189
|
+
if (import_fs.default.existsSync(filePath)) {
|
|
190
|
+
printError(`Component "${name}" already exists at ${filePath}`);
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
const template = isTs ? `import { dot, IDotComponent, IDotDocument, FrameworkItems } from 'dothtml';
|
|
194
|
+
|
|
195
|
+
export class ${name} implements IDotComponent {
|
|
196
|
+
_: FrameworkItems;
|
|
197
|
+
|
|
198
|
+
build(): IDotDocument {
|
|
199
|
+
return dot.div({ class: '${name.toLowerCase()}' })
|
|
200
|
+
.h2('${name} Component')
|
|
201
|
+
.p('This is a new component created with create-dothtml.');
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
` : `import { dot } from 'dothtml';
|
|
205
|
+
|
|
206
|
+
export class ${name} {
|
|
207
|
+
build() {
|
|
208
|
+
return dot.div({ class: '${name.toLowerCase()}' })
|
|
209
|
+
.h2('${name} Component')
|
|
210
|
+
.p('This is a new component created with create-dothtml.');
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
`;
|
|
214
|
+
import_fs.default.writeFileSync(filePath, template);
|
|
215
|
+
console.log(`
|
|
216
|
+
${cc.FgGreen}Success!${cc.reset} Created component ${cc.fgBrightBlue}${name}${cc.reset} at ${filePath}
|
|
217
|
+
`);
|
|
218
|
+
}
|
|
219
|
+
function printUsage() {
|
|
220
|
+
console.log(`
|
|
221
|
+
${cc.fgBrightBlue}create-dothtml${cc.reset}`);
|
|
222
|
+
console.log(`The official project initializer for DOThtml.
|
|
223
|
+
`);
|
|
224
|
+
console.log(`${cc.bright}USAGE${cc.reset}`);
|
|
225
|
+
console.log(` npx create-dothtml ${cc.fgBrightWhite}<project-name>${cc.reset} [options]`);
|
|
226
|
+
console.log(` npx create-dothtml ${cc.fgBrightWhite}generate component <name>${cc.reset}
|
|
227
|
+
`);
|
|
228
|
+
console.log(`${cc.bright}OPTIONS${cc.reset}`);
|
|
229
|
+
console.log(` --js Use JavaScript instead of TypeScript (default)`);
|
|
230
|
+
console.log(` --no-lint Skip adding ESLint to the project`);
|
|
231
|
+
console.log(` --help Show this help message
|
|
232
|
+
`);
|
|
233
|
+
}
|
|
234
|
+
function printError(msg) {
|
|
235
|
+
console.error(`${cc.fgRed}Error: ${msg}${cc.reset}`);
|
|
236
|
+
}
|
|
237
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
238
|
+
0 && (module.exports = {
|
|
239
|
+
cli
|
|
240
|
+
});
|
|
241
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from 'url';\n\n// Helper to get __dirname in both CJS and ESM\nconst getDirname = () => {\n\ttry {\n\t\treturn __dirname;\n\t} catch {\n\t\treturn path.dirname(fileURLToPath(import.meta.url));\n\t}\n};\n\nconst cc = {\n\treset: \"\\x1b[0m\",\n\tbright: \"\\x1b[1m\",\n\tdim: \"\\x1b[2m\",\n\tunderscore: \"\\x1b[4m\",\n\tblink: \"\\x1b[5m\",\n\treverse: \"\\x1b[7m\",\n\thidden: \"\\x1b[8m\",\n\n\tfgBlack: \"\\x1b[30m\",\n\tfgRed: \"\\x1b[31m\",\n\tFgGreen: \"\\x1b[32m\",\n\tfgYellow: \"\\x1b[33m\",\n\tfgBlue: \"\\x1b[34m\",\n\tfgMagenta: \"\\x1b[35m\",\n\tfgCyan: \"\\x1b[36m\",\n\tfgWhite: \"\\x1b[37m\",\n\n\tfgBrightBlack: \"\\x1b[90m\",\n\tfgBrightRed: \"\\x1b[91m\",\n\tFgBrightGreen: \"\\x1b[92m\",\n\tfgBrightYellow: \"\\x1b[93m\",\n\tfgBrightBlue: \"\\x1b[94m\",\n\tfgBrightMagenta: \"\\x1b[95m\",\n\tfgBrightCyan: \"\\x1b[96m\",\n\tfgBrightWhite: \"\\x1b[97m\",\n}\n\nexport async function cli(args: string[]) {\n\tconst command = args[2];\n\n\tif (command === \"generate\" || command === \"g\") {\n\t\thandleGenerate(args.slice(3));\n\t\treturn;\n\t}\n\n\tlet projectName = args[2];\n\tlet startIndex = 2;\n\n\tif (projectName === \"init\") {\n\t\tprojectName = args[3];\n\t\tstartIndex = 3;\n\t}\n\n\tif (!projectName || projectName === \"--help\" || projectName === \"-h\") {\n\t\tprintUsage();\n\t\treturn;\n\t}\n\n\tconst targetDir = path.resolve(process.cwd(), projectName);\n\tif (fs.existsSync(targetDir)) {\n\t\tprintError(`Directory \"${projectName}\" already exists.`);\n\t\treturn;\n\t}\n\n\tconsole.log(`\\nCreating a new DOThtml app in ${cc.fgBrightBlue}${targetDir}${cc.reset}...`);\n\n\t// Template selection (default to TS)\n\tconst argsList = args.slice(startIndex);\n\tconst isJs = argsList.includes(\"--js\");\n\tconst noLint = argsList.includes(\"--no-lint\");\n\tconst template = isJs ? \"vanilla-js\" : \"vanilla-ts\";\n\t\n\tconst currentDir = getDirname();\n\t// When running from dist/index.js, templates is at ../templates\n\tlet templateDir = path.resolve(currentDir, \"..\", \"templates\", template);\n\n\tif (!fs.existsSync(templateDir)) {\n\t\t// Fallback for development if running directly from src\n\t\ttemplateDir = path.resolve(currentDir, \"templates\", template);\n\t\tif (!fs.existsSync(templateDir)) {\n\t\t\t// Another fallback for how tsup might bundle it\n\t\t\ttemplateDir = path.resolve(process.cwd(), \"templates\", template);\n\t\t\tif (!fs.existsSync(templateDir)) {\n\t\t\t\tprintError(`Template directory not found. Tried:\\n- ${path.resolve(currentDir, \"..\", \"templates\", template)}\\n- ${path.resolve(currentDir, \"templates\", template)}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\t// Copy template\n\t\tfs.mkdirSync(targetDir, { recursive: true });\n\t\t// @ts-ignore - cpSync is available in Node 16.7.0+\n\t\tfs.cpSync(templateDir, targetDir, { recursive: true });\n\n\t\t// Replace placeholders in package.json and index.html\n\t\tconst filesToProcess = [\"package.json\", \"index.html\"];\n\t\tfor (const file of filesToProcess) {\n\t\t\tconst filePath = path.join(targetDir, file);\n\t\t\tif (fs.existsSync(filePath)) {\n\t\t\t\tlet content = fs.readFileSync(filePath, \"utf-8\");\n\t\t\t\tcontent = content.replace(/{{name}}/g, projectName);\n\n\t\t\t\tif (file === \"package.json\" && noLint) {\n\t\t\t\t\tconst pkg = JSON.parse(content);\n\t\t\t\t\tdelete pkg.scripts.lint;\n\t\t\t\t\tif (pkg.devDependencies) {\n\t\t\t\t\t\tdelete pkg.devDependencies.eslint;\n\t\t\t\t\t\tdelete pkg.devDependencies[\"@eslint/js\"];\n\t\t\t\t\t\tdelete pkg.devDependencies[\"typescript-eslint\"];\n\t\t\t\t\t}\n\t\t\t\t\tcontent = JSON.stringify(pkg, null, 2);\n\t\t\t\t}\n\n\t\t\t\tfs.writeFileSync(filePath, content);\n\t\t\t}\n\t\t}\n\n\t\tif (noLint) {\n\t\t\tconst eslintConfigPath = path.join(targetDir, \"eslint.config.js\");\n\t\t\tif (fs.existsSync(eslintConfigPath)) {\n\t\t\t\tfs.unlinkSync(eslintConfigPath);\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(`\\n${cc.FgGreen}Success!${cc.reset} Created ${projectName} at ${targetDir}`);\n\t\tconsole.log(`Inside that directory, you can run several commands:`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm install${cc.reset}`);\n\t\tconsole.log(` Installs the dependencies.`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm run dev${cc.reset}`);\n\t\tconsole.log(` Starts the development server.`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm test${cc.reset}`);\n\t\tconsole.log(` Runs the test suite using Vitest.`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm run build${cc.reset}`);\n\t\tconsole.log(` Bundles the app into static files for production.`);\n\n\t\tif (!noLint) {\n\t\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm run lint${cc.reset}`);\n\t\t\tconsole.log(` Checks the code for potential errors.`);\n\t\t}\n\n\t\tconsole.log(`\\nWe suggest that you begin by typing:`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}cd${cc.reset} ${projectName}`);\n\t\tconsole.log(` ${cc.fgBrightBlue}npm install${cc.reset}`);\n\t\tconsole.log(` ${cc.fgBrightBlue}npm run dev${cc.reset}\\n`);\n\n\t} catch (err: any) {\n\t\tprintError(`Error creating project: ${err.message}`);\n\t}\n}\n\nfunction handleGenerate(args: string[]) {\n\tconst type = args[0];\n\tconst name = args[1];\n\n\tif (type !== \"component\" || !name) {\n\t\tconsole.log(`\\n${cc.bright}USAGE${cc.reset}`);\n\t\tconsole.log(` npx create-dothtml generate component <name>\\n`);\n\t\treturn;\n\t}\n\n\tconst isTs = fs.existsSync(path.join(process.cwd(), \"tsconfig.json\"));\n\tconst ext = isTs ? \"ts\" : \"js\";\n\tconst componentsDir = path.join(process.cwd(), \"src\", \"components\");\n\n\tif (!fs.existsSync(componentsDir)) {\n\t\tfs.mkdirSync(componentsDir, { recursive: true });\n\t}\n\n\tconst filePath = path.join(componentsDir, `${name}.${ext}`);\n\tif (fs.existsSync(filePath)) {\n\t\tprintError(`Component \"${name}\" already exists at ${filePath}`);\n\t\treturn;\n\t}\n\n\tconst template = isTs \n\t\t? `import { dot, IDotComponent, IDotDocument, FrameworkItems } from 'dothtml';\n\nexport class ${name} implements IDotComponent {\n _: FrameworkItems;\n\n build(): IDotDocument {\n return dot.div({ class: '${name.toLowerCase()}' })\n .h2('${name} Component')\n .p('This is a new component created with create-dothtml.');\n }\n}\n`\n\t\t: `import { dot } from 'dothtml';\n\nexport class ${name} {\n build() {\n return dot.div({ class: '${name.toLowerCase()}' })\n .h2('${name} Component')\n .p('This is a new component created with create-dothtml.');\n }\n}\n`;\n\n\tfs.writeFileSync(filePath, template);\n\tconsole.log(`\\n${cc.FgGreen}Success!${cc.reset} Created component ${cc.fgBrightBlue}${name}${cc.reset} at ${filePath}\\n`);\n}\n\nfunction printUsage() {\n\tconsole.log(`\\n${cc.fgBrightBlue}create-dothtml${cc.reset}`);\n\tconsole.log(`The official project initializer for DOThtml.\\n`);\n\tconsole.log(`${cc.bright}USAGE${cc.reset}`);\n\tconsole.log(` npx create-dothtml ${cc.fgBrightWhite}<project-name>${cc.reset} [options]`);\n\tconsole.log(` npx create-dothtml ${cc.fgBrightWhite}generate component <name>${cc.reset}\\n`);\n\tconsole.log(`${cc.bright}OPTIONS${cc.reset}`);\n\tconsole.log(` --js Use JavaScript instead of TypeScript (default)`);\n\tconsole.log(` --no-lint Skip adding ESLint to the project`);\n\tconsole.log(` --help Show this help message\\n`);\n}\n\nfunction printError(msg: string) {\n\tconsole.error(`${cc.fgRed}Error: ${msg}${cc.reset}`);\n}\n"],"mappings":"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","names":["path","fs"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import path from "path";
|
|
4
|
+
import { fileURLToPath } from "url";
|
|
5
|
+
var getDirname = () => {
|
|
6
|
+
try {
|
|
7
|
+
return __dirname;
|
|
8
|
+
} catch {
|
|
9
|
+
return path.dirname(fileURLToPath(import.meta.url));
|
|
10
|
+
}
|
|
11
|
+
};
|
|
12
|
+
var cc = {
|
|
13
|
+
reset: "\x1B[0m",
|
|
14
|
+
bright: "\x1B[1m",
|
|
15
|
+
dim: "\x1B[2m",
|
|
16
|
+
underscore: "\x1B[4m",
|
|
17
|
+
blink: "\x1B[5m",
|
|
18
|
+
reverse: "\x1B[7m",
|
|
19
|
+
hidden: "\x1B[8m",
|
|
20
|
+
fgBlack: "\x1B[30m",
|
|
21
|
+
fgRed: "\x1B[31m",
|
|
22
|
+
FgGreen: "\x1B[32m",
|
|
23
|
+
fgYellow: "\x1B[33m",
|
|
24
|
+
fgBlue: "\x1B[34m",
|
|
25
|
+
fgMagenta: "\x1B[35m",
|
|
26
|
+
fgCyan: "\x1B[36m",
|
|
27
|
+
fgWhite: "\x1B[37m",
|
|
28
|
+
fgBrightBlack: "\x1B[90m",
|
|
29
|
+
fgBrightRed: "\x1B[91m",
|
|
30
|
+
FgBrightGreen: "\x1B[92m",
|
|
31
|
+
fgBrightYellow: "\x1B[93m",
|
|
32
|
+
fgBrightBlue: "\x1B[94m",
|
|
33
|
+
fgBrightMagenta: "\x1B[95m",
|
|
34
|
+
fgBrightCyan: "\x1B[96m",
|
|
35
|
+
fgBrightWhite: "\x1B[97m"
|
|
36
|
+
};
|
|
37
|
+
async function cli(args) {
|
|
38
|
+
const command = args[2];
|
|
39
|
+
if (command === "generate" || command === "g") {
|
|
40
|
+
handleGenerate(args.slice(3));
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
let projectName = args[2];
|
|
44
|
+
let startIndex = 2;
|
|
45
|
+
if (projectName === "init") {
|
|
46
|
+
projectName = args[3];
|
|
47
|
+
startIndex = 3;
|
|
48
|
+
}
|
|
49
|
+
if (!projectName || projectName === "--help" || projectName === "-h") {
|
|
50
|
+
printUsage();
|
|
51
|
+
return;
|
|
52
|
+
}
|
|
53
|
+
const targetDir = path.resolve(process.cwd(), projectName);
|
|
54
|
+
if (fs.existsSync(targetDir)) {
|
|
55
|
+
printError(`Directory "${projectName}" already exists.`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
console.log(`
|
|
59
|
+
Creating a new DOThtml app in ${cc.fgBrightBlue}${targetDir}${cc.reset}...`);
|
|
60
|
+
const argsList = args.slice(startIndex);
|
|
61
|
+
const isJs = argsList.includes("--js");
|
|
62
|
+
const noLint = argsList.includes("--no-lint");
|
|
63
|
+
const template = isJs ? "vanilla-js" : "vanilla-ts";
|
|
64
|
+
const currentDir = getDirname();
|
|
65
|
+
let templateDir = path.resolve(currentDir, "..", "templates", template);
|
|
66
|
+
if (!fs.existsSync(templateDir)) {
|
|
67
|
+
templateDir = path.resolve(currentDir, "templates", template);
|
|
68
|
+
if (!fs.existsSync(templateDir)) {
|
|
69
|
+
templateDir = path.resolve(process.cwd(), "templates", template);
|
|
70
|
+
if (!fs.existsSync(templateDir)) {
|
|
71
|
+
printError(`Template directory not found. Tried:
|
|
72
|
+
- ${path.resolve(currentDir, "..", "templates", template)}
|
|
73
|
+
- ${path.resolve(currentDir, "templates", template)}`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
fs.mkdirSync(targetDir, { recursive: true });
|
|
80
|
+
fs.cpSync(templateDir, targetDir, { recursive: true });
|
|
81
|
+
const filesToProcess = ["package.json", "index.html"];
|
|
82
|
+
for (const file of filesToProcess) {
|
|
83
|
+
const filePath = path.join(targetDir, file);
|
|
84
|
+
if (fs.existsSync(filePath)) {
|
|
85
|
+
let content = fs.readFileSync(filePath, "utf-8");
|
|
86
|
+
content = content.replace(/{{name}}/g, projectName);
|
|
87
|
+
if (file === "package.json" && noLint) {
|
|
88
|
+
const pkg = JSON.parse(content);
|
|
89
|
+
delete pkg.scripts.lint;
|
|
90
|
+
if (pkg.devDependencies) {
|
|
91
|
+
delete pkg.devDependencies.eslint;
|
|
92
|
+
delete pkg.devDependencies["@eslint/js"];
|
|
93
|
+
delete pkg.devDependencies["typescript-eslint"];
|
|
94
|
+
}
|
|
95
|
+
content = JSON.stringify(pkg, null, 2);
|
|
96
|
+
}
|
|
97
|
+
fs.writeFileSync(filePath, content);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (noLint) {
|
|
101
|
+
const eslintConfigPath = path.join(targetDir, "eslint.config.js");
|
|
102
|
+
if (fs.existsSync(eslintConfigPath)) {
|
|
103
|
+
fs.unlinkSync(eslintConfigPath);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
console.log(`
|
|
107
|
+
${cc.FgGreen}Success!${cc.reset} Created ${projectName} at ${targetDir}`);
|
|
108
|
+
console.log(`Inside that directory, you can run several commands:`);
|
|
109
|
+
console.log(`
|
|
110
|
+
${cc.fgBrightBlue}npm install${cc.reset}`);
|
|
111
|
+
console.log(` Installs the dependencies.`);
|
|
112
|
+
console.log(`
|
|
113
|
+
${cc.fgBrightBlue}npm run dev${cc.reset}`);
|
|
114
|
+
console.log(` Starts the development server.`);
|
|
115
|
+
console.log(`
|
|
116
|
+
${cc.fgBrightBlue}npm test${cc.reset}`);
|
|
117
|
+
console.log(` Runs the test suite using Vitest.`);
|
|
118
|
+
console.log(`
|
|
119
|
+
${cc.fgBrightBlue}npm run build${cc.reset}`);
|
|
120
|
+
console.log(` Bundles the app into static files for production.`);
|
|
121
|
+
if (!noLint) {
|
|
122
|
+
console.log(`
|
|
123
|
+
${cc.fgBrightBlue}npm run lint${cc.reset}`);
|
|
124
|
+
console.log(` Checks the code for potential errors.`);
|
|
125
|
+
}
|
|
126
|
+
console.log(`
|
|
127
|
+
We suggest that you begin by typing:`);
|
|
128
|
+
console.log(`
|
|
129
|
+
${cc.fgBrightBlue}cd${cc.reset} ${projectName}`);
|
|
130
|
+
console.log(` ${cc.fgBrightBlue}npm install${cc.reset}`);
|
|
131
|
+
console.log(` ${cc.fgBrightBlue}npm run dev${cc.reset}
|
|
132
|
+
`);
|
|
133
|
+
} catch (err) {
|
|
134
|
+
printError(`Error creating project: ${err.message}`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
function handleGenerate(args) {
|
|
138
|
+
const type = args[0];
|
|
139
|
+
const name = args[1];
|
|
140
|
+
if (type !== "component" || !name) {
|
|
141
|
+
console.log(`
|
|
142
|
+
${cc.bright}USAGE${cc.reset}`);
|
|
143
|
+
console.log(` npx create-dothtml generate component <name>
|
|
144
|
+
`);
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const isTs = fs.existsSync(path.join(process.cwd(), "tsconfig.json"));
|
|
148
|
+
const ext = isTs ? "ts" : "js";
|
|
149
|
+
const componentsDir = path.join(process.cwd(), "src", "components");
|
|
150
|
+
if (!fs.existsSync(componentsDir)) {
|
|
151
|
+
fs.mkdirSync(componentsDir, { recursive: true });
|
|
152
|
+
}
|
|
153
|
+
const filePath = path.join(componentsDir, `${name}.${ext}`);
|
|
154
|
+
if (fs.existsSync(filePath)) {
|
|
155
|
+
printError(`Component "${name}" already exists at ${filePath}`);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const template = isTs ? `import { dot, IDotComponent, IDotDocument, FrameworkItems } from 'dothtml';
|
|
159
|
+
|
|
160
|
+
export class ${name} implements IDotComponent {
|
|
161
|
+
_: FrameworkItems;
|
|
162
|
+
|
|
163
|
+
build(): IDotDocument {
|
|
164
|
+
return dot.div({ class: '${name.toLowerCase()}' })
|
|
165
|
+
.h2('${name} Component')
|
|
166
|
+
.p('This is a new component created with create-dothtml.');
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
` : `import { dot } from 'dothtml';
|
|
170
|
+
|
|
171
|
+
export class ${name} {
|
|
172
|
+
build() {
|
|
173
|
+
return dot.div({ class: '${name.toLowerCase()}' })
|
|
174
|
+
.h2('${name} Component')
|
|
175
|
+
.p('This is a new component created with create-dothtml.');
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
`;
|
|
179
|
+
fs.writeFileSync(filePath, template);
|
|
180
|
+
console.log(`
|
|
181
|
+
${cc.FgGreen}Success!${cc.reset} Created component ${cc.fgBrightBlue}${name}${cc.reset} at ${filePath}
|
|
182
|
+
`);
|
|
183
|
+
}
|
|
184
|
+
function printUsage() {
|
|
185
|
+
console.log(`
|
|
186
|
+
${cc.fgBrightBlue}create-dothtml${cc.reset}`);
|
|
187
|
+
console.log(`The official project initializer for DOThtml.
|
|
188
|
+
`);
|
|
189
|
+
console.log(`${cc.bright}USAGE${cc.reset}`);
|
|
190
|
+
console.log(` npx create-dothtml ${cc.fgBrightWhite}<project-name>${cc.reset} [options]`);
|
|
191
|
+
console.log(` npx create-dothtml ${cc.fgBrightWhite}generate component <name>${cc.reset}
|
|
192
|
+
`);
|
|
193
|
+
console.log(`${cc.bright}OPTIONS${cc.reset}`);
|
|
194
|
+
console.log(` --js Use JavaScript instead of TypeScript (default)`);
|
|
195
|
+
console.log(` --no-lint Skip adding ESLint to the project`);
|
|
196
|
+
console.log(` --help Show this help message
|
|
197
|
+
`);
|
|
198
|
+
}
|
|
199
|
+
function printError(msg) {
|
|
200
|
+
console.error(`${cc.fgRed}Error: ${msg}${cc.reset}`);
|
|
201
|
+
}
|
|
202
|
+
export {
|
|
203
|
+
cli
|
|
204
|
+
};
|
|
205
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport { fileURLToPath } from 'url';\n\n// Helper to get __dirname in both CJS and ESM\nconst getDirname = () => {\n\ttry {\n\t\treturn __dirname;\n\t} catch {\n\t\treturn path.dirname(fileURLToPath(import.meta.url));\n\t}\n};\n\nconst cc = {\n\treset: \"\\x1b[0m\",\n\tbright: \"\\x1b[1m\",\n\tdim: \"\\x1b[2m\",\n\tunderscore: \"\\x1b[4m\",\n\tblink: \"\\x1b[5m\",\n\treverse: \"\\x1b[7m\",\n\thidden: \"\\x1b[8m\",\n\n\tfgBlack: \"\\x1b[30m\",\n\tfgRed: \"\\x1b[31m\",\n\tFgGreen: \"\\x1b[32m\",\n\tfgYellow: \"\\x1b[33m\",\n\tfgBlue: \"\\x1b[34m\",\n\tfgMagenta: \"\\x1b[35m\",\n\tfgCyan: \"\\x1b[36m\",\n\tfgWhite: \"\\x1b[37m\",\n\n\tfgBrightBlack: \"\\x1b[90m\",\n\tfgBrightRed: \"\\x1b[91m\",\n\tFgBrightGreen: \"\\x1b[92m\",\n\tfgBrightYellow: \"\\x1b[93m\",\n\tfgBrightBlue: \"\\x1b[94m\",\n\tfgBrightMagenta: \"\\x1b[95m\",\n\tfgBrightCyan: \"\\x1b[96m\",\n\tfgBrightWhite: \"\\x1b[97m\",\n}\n\nexport async function cli(args: string[]) {\n\tconst command = args[2];\n\n\tif (command === \"generate\" || command === \"g\") {\n\t\thandleGenerate(args.slice(3));\n\t\treturn;\n\t}\n\n\tlet projectName = args[2];\n\tlet startIndex = 2;\n\n\tif (projectName === \"init\") {\n\t\tprojectName = args[3];\n\t\tstartIndex = 3;\n\t}\n\n\tif (!projectName || projectName === \"--help\" || projectName === \"-h\") {\n\t\tprintUsage();\n\t\treturn;\n\t}\n\n\tconst targetDir = path.resolve(process.cwd(), projectName);\n\tif (fs.existsSync(targetDir)) {\n\t\tprintError(`Directory \"${projectName}\" already exists.`);\n\t\treturn;\n\t}\n\n\tconsole.log(`\\nCreating a new DOThtml app in ${cc.fgBrightBlue}${targetDir}${cc.reset}...`);\n\n\t// Template selection (default to TS)\n\tconst argsList = args.slice(startIndex);\n\tconst isJs = argsList.includes(\"--js\");\n\tconst noLint = argsList.includes(\"--no-lint\");\n\tconst template = isJs ? \"vanilla-js\" : \"vanilla-ts\";\n\t\n\tconst currentDir = getDirname();\n\t// When running from dist/index.js, templates is at ../templates\n\tlet templateDir = path.resolve(currentDir, \"..\", \"templates\", template);\n\n\tif (!fs.existsSync(templateDir)) {\n\t\t// Fallback for development if running directly from src\n\t\ttemplateDir = path.resolve(currentDir, \"templates\", template);\n\t\tif (!fs.existsSync(templateDir)) {\n\t\t\t// Another fallback for how tsup might bundle it\n\t\t\ttemplateDir = path.resolve(process.cwd(), \"templates\", template);\n\t\t\tif (!fs.existsSync(templateDir)) {\n\t\t\t\tprintError(`Template directory not found. Tried:\\n- ${path.resolve(currentDir, \"..\", \"templates\", template)}\\n- ${path.resolve(currentDir, \"templates\", template)}`);\n\t\t\t\treturn;\n\t\t\t}\n\t\t}\n\t}\n\n\ttry {\n\t\t// Copy template\n\t\tfs.mkdirSync(targetDir, { recursive: true });\n\t\t// @ts-ignore - cpSync is available in Node 16.7.0+\n\t\tfs.cpSync(templateDir, targetDir, { recursive: true });\n\n\t\t// Replace placeholders in package.json and index.html\n\t\tconst filesToProcess = [\"package.json\", \"index.html\"];\n\t\tfor (const file of filesToProcess) {\n\t\t\tconst filePath = path.join(targetDir, file);\n\t\t\tif (fs.existsSync(filePath)) {\n\t\t\t\tlet content = fs.readFileSync(filePath, \"utf-8\");\n\t\t\t\tcontent = content.replace(/{{name}}/g, projectName);\n\n\t\t\t\tif (file === \"package.json\" && noLint) {\n\t\t\t\t\tconst pkg = JSON.parse(content);\n\t\t\t\t\tdelete pkg.scripts.lint;\n\t\t\t\t\tif (pkg.devDependencies) {\n\t\t\t\t\t\tdelete pkg.devDependencies.eslint;\n\t\t\t\t\t\tdelete pkg.devDependencies[\"@eslint/js\"];\n\t\t\t\t\t\tdelete pkg.devDependencies[\"typescript-eslint\"];\n\t\t\t\t\t}\n\t\t\t\t\tcontent = JSON.stringify(pkg, null, 2);\n\t\t\t\t}\n\n\t\t\t\tfs.writeFileSync(filePath, content);\n\t\t\t}\n\t\t}\n\n\t\tif (noLint) {\n\t\t\tconst eslintConfigPath = path.join(targetDir, \"eslint.config.js\");\n\t\t\tif (fs.existsSync(eslintConfigPath)) {\n\t\t\t\tfs.unlinkSync(eslintConfigPath);\n\t\t\t}\n\t\t}\n\n\t\tconsole.log(`\\n${cc.FgGreen}Success!${cc.reset} Created ${projectName} at ${targetDir}`);\n\t\tconsole.log(`Inside that directory, you can run several commands:`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm install${cc.reset}`);\n\t\tconsole.log(` Installs the dependencies.`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm run dev${cc.reset}`);\n\t\tconsole.log(` Starts the development server.`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm test${cc.reset}`);\n\t\tconsole.log(` Runs the test suite using Vitest.`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm run build${cc.reset}`);\n\t\tconsole.log(` Bundles the app into static files for production.`);\n\n\t\tif (!noLint) {\n\t\t\tconsole.log(`\\n ${cc.fgBrightBlue}npm run lint${cc.reset}`);\n\t\t\tconsole.log(` Checks the code for potential errors.`);\n\t\t}\n\n\t\tconsole.log(`\\nWe suggest that you begin by typing:`);\n\t\tconsole.log(`\\n ${cc.fgBrightBlue}cd${cc.reset} ${projectName}`);\n\t\tconsole.log(` ${cc.fgBrightBlue}npm install${cc.reset}`);\n\t\tconsole.log(` ${cc.fgBrightBlue}npm run dev${cc.reset}\\n`);\n\n\t} catch (err: any) {\n\t\tprintError(`Error creating project: ${err.message}`);\n\t}\n}\n\nfunction handleGenerate(args: string[]) {\n\tconst type = args[0];\n\tconst name = args[1];\n\n\tif (type !== \"component\" || !name) {\n\t\tconsole.log(`\\n${cc.bright}USAGE${cc.reset}`);\n\t\tconsole.log(` npx create-dothtml generate component <name>\\n`);\n\t\treturn;\n\t}\n\n\tconst isTs = fs.existsSync(path.join(process.cwd(), \"tsconfig.json\"));\n\tconst ext = isTs ? \"ts\" : \"js\";\n\tconst componentsDir = path.join(process.cwd(), \"src\", \"components\");\n\n\tif (!fs.existsSync(componentsDir)) {\n\t\tfs.mkdirSync(componentsDir, { recursive: true });\n\t}\n\n\tconst filePath = path.join(componentsDir, `${name}.${ext}`);\n\tif (fs.existsSync(filePath)) {\n\t\tprintError(`Component \"${name}\" already exists at ${filePath}`);\n\t\treturn;\n\t}\n\n\tconst template = isTs \n\t\t? `import { dot, IDotComponent, IDotDocument, FrameworkItems } from 'dothtml';\n\nexport class ${name} implements IDotComponent {\n _: FrameworkItems;\n\n build(): IDotDocument {\n return dot.div({ class: '${name.toLowerCase()}' })\n .h2('${name} Component')\n .p('This is a new component created with create-dothtml.');\n }\n}\n`\n\t\t: `import { dot } from 'dothtml';\n\nexport class ${name} {\n build() {\n return dot.div({ class: '${name.toLowerCase()}' })\n .h2('${name} Component')\n .p('This is a new component created with create-dothtml.');\n }\n}\n`;\n\n\tfs.writeFileSync(filePath, template);\n\tconsole.log(`\\n${cc.FgGreen}Success!${cc.reset} Created component ${cc.fgBrightBlue}${name}${cc.reset} at ${filePath}\\n`);\n}\n\nfunction printUsage() {\n\tconsole.log(`\\n${cc.fgBrightBlue}create-dothtml${cc.reset}`);\n\tconsole.log(`The official project initializer for DOThtml.\\n`);\n\tconsole.log(`${cc.bright}USAGE${cc.reset}`);\n\tconsole.log(` npx create-dothtml ${cc.fgBrightWhite}<project-name>${cc.reset} [options]`);\n\tconsole.log(` npx create-dothtml ${cc.fgBrightWhite}generate component <name>${cc.reset}\\n`);\n\tconsole.log(`${cc.bright}OPTIONS${cc.reset}`);\n\tconsole.log(` --js Use JavaScript instead of TypeScript (default)`);\n\tconsole.log(` --no-lint Skip adding ESLint to the project`);\n\tconsole.log(` --help Show this help message\\n`);\n}\n\nfunction printError(msg: string) {\n\tconsole.error(`${cc.fgRed}Error: ${msg}${cc.reset}`);\n}\n"],"mappings":"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","names":[]}
|
package/package.json
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-dothtml",
|
|
3
|
+
"version": "6.0.8",
|
|
4
|
+
"private": false,
|
|
5
|
+
"description": "The official project initializer for DOThtml.",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"module": "dist/index.mjs",
|
|
8
|
+
"types": "dist/index.d.ts",
|
|
9
|
+
"bin": {
|
|
10
|
+
"create-dothtml": "bin/create-dothtml"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"templates",
|
|
15
|
+
"bin"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsup src/index.ts --format cjs,esm --dts --clean",
|
|
19
|
+
"dev": "tsup src/index.ts --format cjs,esm --watch --dts",
|
|
20
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
21
|
+
},
|
|
22
|
+
"repository": {
|
|
23
|
+
"type": "git",
|
|
24
|
+
"url": "https://github.com/JSideris/DOThtml.git",
|
|
25
|
+
"directory": "packages/create-dothtml"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://dothtml.org/",
|
|
28
|
+
"bugs": {
|
|
29
|
+
"url": "https://github.com/JSideris/DOThtml/issues"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"dothtml",
|
|
33
|
+
"framework",
|
|
34
|
+
"web",
|
|
35
|
+
"cli",
|
|
36
|
+
"create-dothtml",
|
|
37
|
+
"vite"
|
|
38
|
+
],
|
|
39
|
+
"author": "Joshua Sideris",
|
|
40
|
+
"license": "ISC",
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@types/node": "^18.19.130",
|
|
43
|
+
"tsup": "^8.5.1",
|
|
44
|
+
"typescript": "^5.9.3"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{name}}</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.js"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"test": "vitest",
|
|
11
|
+
"lint": "eslint ."
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"dothtml": "^6.0.8"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@eslint/js": "^9.0.0",
|
|
18
|
+
"eslint": "^9.0.0",
|
|
19
|
+
"jsdom": "^24.0.0",
|
|
20
|
+
"vite": "^6.0.0",
|
|
21
|
+
"vitest": "^1.0.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { dot } from 'dothtml';
|
|
2
|
+
|
|
3
|
+
export class Counter {
|
|
4
|
+
count = dot.state(0);
|
|
5
|
+
|
|
6
|
+
build() {
|
|
7
|
+
return dot.div({ class: 'card' })
|
|
8
|
+
.h2('Interactive Counter')
|
|
9
|
+
.p('The count is: ', this.count)
|
|
10
|
+
.button({
|
|
11
|
+
onClick: () => this.count.value++
|
|
12
|
+
}, 'Increment')
|
|
13
|
+
.button({
|
|
14
|
+
onClick: () => this.count.value--,
|
|
15
|
+
style: 'margin-left: 10px'
|
|
16
|
+
}, 'Decrement');
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { dot } from 'dothtml';
|
|
2
|
+
import './style.css';
|
|
3
|
+
import { Counter } from './components/Counter';
|
|
4
|
+
|
|
5
|
+
dot('#app')
|
|
6
|
+
.h1('Welcome to DOThtml!')
|
|
7
|
+
.p('The fastest, lightest way to build reactive web apps.')
|
|
8
|
+
.mount(new Counter())
|
|
9
|
+
.p({ style: 'margin-top: 2rem; opacity: 0.8;' },
|
|
10
|
+
'Edit ', dot.code('src/main.js'), ' to get started!'
|
|
11
|
+
);
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
+
import { dot } from 'dothtml'
|
|
3
|
+
|
|
4
|
+
describe('DOThtml rendering', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
document.body.innerHTML = '<div id="app"></div>'
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('renders a heading', () => {
|
|
10
|
+
dot('#app').h1('Hello DOThtml!')
|
|
11
|
+
const h1 = document.querySelector('h1')
|
|
12
|
+
expect(h1).not.toBeNull()
|
|
13
|
+
expect(h1.textContent).toBe('Hello DOThtml!')
|
|
14
|
+
})
|
|
15
|
+
})
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
display: flex;
|
|
19
|
+
place-items: center;
|
|
20
|
+
min-width: 320px;
|
|
21
|
+
min-height: 100vh;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#app {
|
|
25
|
+
max-width: 1280px;
|
|
26
|
+
margin: 0 auto;
|
|
27
|
+
padding: 2rem;
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.card {
|
|
32
|
+
padding: 2em;
|
|
33
|
+
background: rgba(255, 255, 255, 0.1);
|
|
34
|
+
border-radius: 16px;
|
|
35
|
+
backdrop-filter: blur(10px);
|
|
36
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
37
|
+
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h1 {
|
|
41
|
+
font-size: 3.2em;
|
|
42
|
+
line-height: 1.1;
|
|
43
|
+
margin-bottom: 0.5em;
|
|
44
|
+
background: linear-gradient(to right, #fff, #a5b4fc);
|
|
45
|
+
-webkit-background-clip: text;
|
|
46
|
+
-webkit-text-fill-color: transparent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
button {
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
border: 1px solid transparent;
|
|
52
|
+
padding: 0.6em 1.2em;
|
|
53
|
+
font-size: 1em;
|
|
54
|
+
font-weight: 500;
|
|
55
|
+
font-family: inherit;
|
|
56
|
+
background-color: #1a1a1a;
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
transition: border-color 0.25s, transform 0.1s;
|
|
59
|
+
color: white;
|
|
60
|
+
}
|
|
61
|
+
button:hover {
|
|
62
|
+
border-color: #646cff;
|
|
63
|
+
transform: scale(1.05);
|
|
64
|
+
}
|
|
65
|
+
button:active {
|
|
66
|
+
transform: scale(0.95);
|
|
67
|
+
}
|
|
68
|
+
button:focus,
|
|
69
|
+
button:focus-visible {
|
|
70
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@media (prefers-color-scheme: light) {
|
|
74
|
+
:root {
|
|
75
|
+
color: #213547;
|
|
76
|
+
background: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%);
|
|
77
|
+
}
|
|
78
|
+
.card {
|
|
79
|
+
background: rgba(255, 255, 255, 0.7);
|
|
80
|
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
81
|
+
}
|
|
82
|
+
h1 {
|
|
83
|
+
background: linear-gradient(to right, #4f46e5, #9333ea);
|
|
84
|
+
-webkit-background-clip: text;
|
|
85
|
+
-webkit-text-fill-color: transparent;
|
|
86
|
+
}
|
|
87
|
+
button {
|
|
88
|
+
background-color: #f9f9f9;
|
|
89
|
+
color: #213547;
|
|
90
|
+
border: 1px solid #ddd;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import js from "@eslint/js";
|
|
2
|
+
import tseslint from "typescript-eslint";
|
|
3
|
+
|
|
4
|
+
export default tseslint.config(
|
|
5
|
+
js.configs.recommended,
|
|
6
|
+
...tseslint.configs.recommended,
|
|
7
|
+
{
|
|
8
|
+
rules: {
|
|
9
|
+
"newline-per-chained-call": "off",
|
|
10
|
+
"@typescript-eslint/no-explicit-any": "off",
|
|
11
|
+
},
|
|
12
|
+
}
|
|
13
|
+
);
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>{{name}}</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="app"></div>
|
|
10
|
+
<script type="module" src="/src/main.ts"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "{{name}}",
|
|
3
|
+
"private": true,
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"dev": "vite",
|
|
8
|
+
"build": "tsc && vite build",
|
|
9
|
+
"preview": "vite preview",
|
|
10
|
+
"test": "vitest",
|
|
11
|
+
"lint": "eslint ."
|
|
12
|
+
},
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"dothtml": "^6.0.8"
|
|
15
|
+
},
|
|
16
|
+
"devDependencies": {
|
|
17
|
+
"@eslint/js": "^9.0.0",
|
|
18
|
+
"eslint": "^9.0.0",
|
|
19
|
+
"jsdom": "^24.0.0",
|
|
20
|
+
"typescript": "^5.0.0",
|
|
21
|
+
"typescript-eslint": "^8.0.0",
|
|
22
|
+
"vite": "^6.0.0",
|
|
23
|
+
"vitest": "^1.0.0"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { dot, IDotComponent, IDotDocument, FrameworkItems } from 'dothtml';
|
|
2
|
+
|
|
3
|
+
export class Counter implements IDotComponent {
|
|
4
|
+
count = dot.state(0);
|
|
5
|
+
_: FrameworkItems;
|
|
6
|
+
|
|
7
|
+
build(): IDotDocument {
|
|
8
|
+
return dot.div({ class: 'card' })
|
|
9
|
+
.h2('Interactive Counter')
|
|
10
|
+
.p('The count is: ', this.count)
|
|
11
|
+
.button({
|
|
12
|
+
onClick: () => this.count.value++
|
|
13
|
+
}, 'Increment')
|
|
14
|
+
.button({
|
|
15
|
+
onClick: () => this.count.value--,
|
|
16
|
+
style: 'margin-left: 10px'
|
|
17
|
+
}, 'Decrement');
|
|
18
|
+
}
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
+
import { dot } from 'dothtml'
|
|
3
|
+
|
|
4
|
+
describe('DOThtml rendering', () => {
|
|
5
|
+
beforeEach(() => {
|
|
6
|
+
document.body.innerHTML = '<div id="app"></div>'
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
it('renders a heading', () => {
|
|
10
|
+
dot('#app').h1('Hello DOThtml!')
|
|
11
|
+
const h1 = document.querySelector('h1')
|
|
12
|
+
expect(h1).not.toBeNull()
|
|
13
|
+
expect(h1?.textContent).toBe('Hello DOThtml!')
|
|
14
|
+
})
|
|
15
|
+
})
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { dot } from 'dothtml';
|
|
2
|
+
import './style.css';
|
|
3
|
+
import { Counter } from './components/Counter';
|
|
4
|
+
|
|
5
|
+
dot('#app')
|
|
6
|
+
.h1('Welcome to DOThtml!')
|
|
7
|
+
.p('The fastest, lightest way to build reactive web apps.')
|
|
8
|
+
.mount(new Counter())
|
|
9
|
+
.p({ style: 'margin-top: 2rem; opacity: 0.8;' },
|
|
10
|
+
'Edit ', dot.code('src/main.ts'), ' to get started!'
|
|
11
|
+
);
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
font-family: 'Inter', system-ui, Avenir, Helvetica, Arial, sans-serif;
|
|
3
|
+
line-height: 1.5;
|
|
4
|
+
font-weight: 400;
|
|
5
|
+
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
color: rgba(255, 255, 255, 0.87);
|
|
8
|
+
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|
9
|
+
|
|
10
|
+
font-synthesis: none;
|
|
11
|
+
text-rendering: optimizeLegibility;
|
|
12
|
+
-webkit-font-smoothing: antialiased;
|
|
13
|
+
-moz-osx-font-smoothing: grayscale;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
body {
|
|
17
|
+
margin: 0;
|
|
18
|
+
display: flex;
|
|
19
|
+
place-items: center;
|
|
20
|
+
min-width: 320px;
|
|
21
|
+
min-height: 100vh;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
#app {
|
|
25
|
+
max-width: 1280px;
|
|
26
|
+
margin: 0 auto;
|
|
27
|
+
padding: 2rem;
|
|
28
|
+
text-align: center;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.card {
|
|
32
|
+
padding: 2em;
|
|
33
|
+
background: rgba(255, 255, 255, 0.1);
|
|
34
|
+
border-radius: 16px;
|
|
35
|
+
backdrop-filter: blur(10px);
|
|
36
|
+
border: 1px solid rgba(255, 255, 255, 0.2);
|
|
37
|
+
box-shadow: 0 8px 32px 0 rgba(31, 38, 135, 0.37);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h1 {
|
|
41
|
+
font-size: 3.2em;
|
|
42
|
+
line-height: 1.1;
|
|
43
|
+
margin-bottom: 0.5em;
|
|
44
|
+
background: linear-gradient(to right, #fff, #a5b4fc);
|
|
45
|
+
-webkit-background-clip: text;
|
|
46
|
+
-webkit-text-fill-color: transparent;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
button {
|
|
50
|
+
border-radius: 8px;
|
|
51
|
+
border: 1px solid transparent;
|
|
52
|
+
padding: 0.6em 1.2em;
|
|
53
|
+
font-size: 1em;
|
|
54
|
+
font-weight: 500;
|
|
55
|
+
font-family: inherit;
|
|
56
|
+
background-color: #1a1a1a;
|
|
57
|
+
cursor: pointer;
|
|
58
|
+
transition: border-color 0.25s, transform 0.1s;
|
|
59
|
+
color: white;
|
|
60
|
+
}
|
|
61
|
+
button:hover {
|
|
62
|
+
border-color: #646cff;
|
|
63
|
+
transform: scale(1.05);
|
|
64
|
+
}
|
|
65
|
+
button:active {
|
|
66
|
+
transform: scale(0.95);
|
|
67
|
+
}
|
|
68
|
+
button:focus,
|
|
69
|
+
button:focus-visible {
|
|
70
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
@media (prefers-color-scheme: light) {
|
|
74
|
+
:root {
|
|
75
|
+
color: #213547;
|
|
76
|
+
background: linear-gradient(135deg, #fdfbfb 0%, #ebedee 100%);
|
|
77
|
+
}
|
|
78
|
+
.card {
|
|
79
|
+
background: rgba(255, 255, 255, 0.7);
|
|
80
|
+
border: 1px solid rgba(0, 0, 0, 0.1);
|
|
81
|
+
}
|
|
82
|
+
h1 {
|
|
83
|
+
background: linear-gradient(to right, #4f46e5, #9333ea);
|
|
84
|
+
-webkit-background-clip: text;
|
|
85
|
+
-webkit-text-fill-color: transparent;
|
|
86
|
+
}
|
|
87
|
+
button {
|
|
88
|
+
background-color: #f9f9f9;
|
|
89
|
+
color: #213547;
|
|
90
|
+
border: 1px solid #ddd;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ESNext",
|
|
4
|
+
"useDefineForClassFields": true,
|
|
5
|
+
"module": "ESNext",
|
|
6
|
+
"lib": ["ESNext", "DOM", "DOM.Iterable"],
|
|
7
|
+
"skipLibCheck": true,
|
|
8
|
+
|
|
9
|
+
/* Bundler mode */
|
|
10
|
+
"moduleResolution": "bundler",
|
|
11
|
+
"allowImportingTsExtensions": true,
|
|
12
|
+
"resolveJsonModule": true,
|
|
13
|
+
"isolatedModules": true,
|
|
14
|
+
"noEmit": true,
|
|
15
|
+
|
|
16
|
+
/* Linting */
|
|
17
|
+
"strict": true,
|
|
18
|
+
"noUnusedLocals": true,
|
|
19
|
+
"noUnusedParameters": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true
|
|
21
|
+
},
|
|
22
|
+
"include": ["src"]
|
|
23
|
+
}
|