@techninja/clearstack 0.2.7 → 0.2.16
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/lib/check.js +1 -1
- package/lib/package-gen.js +5 -3
- package/package.json +5 -2
- package/templates/fullstack/src/server.js +4 -4
- package/templates/shared/.configs/eslint.config.js +1 -1
- package/templates/shared/.configs/jsconfig.json +1 -1
- package/templates/shared/.env +1 -1
- package/templates/shared/.github/workflows/spec.yml +2 -2
- package/templates/shared/gitignore +2 -2
- package/templates/shared/scripts/build-icons.js +2 -2
- package/templates/shared/scripts/setup.js +14 -0
- package/templates/shared/scripts/test.js +37 -0
- package/templates/shared/scripts/vendor-deps.js +2 -2
- package/templates/shared/src/public/index.html +26 -0
- package/templates/shared/public/index.html +0 -26
package/lib/check.js
CHANGED
|
@@ -20,7 +20,7 @@ function loadConfig(projectDir) {
|
|
|
20
20
|
docsMax: parseInt(env.SPEC_DOCS_MAX_LINES) || 500,
|
|
21
21
|
codeExt: (env.SPEC_CODE_EXTENSIONS || '.js,.css').split(','),
|
|
22
22
|
docsExt: (env.SPEC_DOCS_EXTENSIONS || '.md').split(','),
|
|
23
|
-
ignore: (env.SPEC_IGNORE_DIRS || 'node_modules,public/vendor,.git,.configs').split(','),
|
|
23
|
+
ignore: (env.SPEC_IGNORE_DIRS || 'node_modules,src/public/vendor,.git,.configs').split(','),
|
|
24
24
|
};
|
|
25
25
|
}
|
|
26
26
|
|
package/lib/package-gen.js
CHANGED
|
@@ -20,9 +20,11 @@ export async function writePackageJson(dest, vars, existing) {
|
|
|
20
20
|
...(isFullstack ? {
|
|
21
21
|
start: 'node src/server.js',
|
|
22
22
|
dev: 'node --watch --env-file=.env src/server.js',
|
|
23
|
-
} : {
|
|
24
|
-
|
|
25
|
-
|
|
23
|
+
} : {
|
|
24
|
+
dev: 'npx serve src',
|
|
25
|
+
}),
|
|
26
|
+
postinstall: 'node scripts/setup.js',
|
|
27
|
+
test: 'node scripts/test.js',
|
|
26
28
|
spec: 'clearstack',
|
|
27
29
|
};
|
|
28
30
|
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techninja/clearstack",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.16",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A no-build web component framework specification — scaffold, validate, and evolve spec-compliant projects",
|
|
6
6
|
"bin": {
|
|
7
|
-
"clearstack": "
|
|
7
|
+
"clearstack": "bin/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"files": [
|
|
10
10
|
"bin/",
|
|
@@ -28,6 +28,9 @@
|
|
|
28
28
|
"release": "node scripts/release.js",
|
|
29
29
|
"prepublishOnly": "node scripts/sync-docs.js"
|
|
30
30
|
},
|
|
31
|
+
"publishConfig": {
|
|
32
|
+
"access": "public"
|
|
33
|
+
},
|
|
31
34
|
"keywords": [
|
|
32
35
|
"web-components",
|
|
33
36
|
"no-build",
|
|
@@ -10,16 +10,16 @@ import { eventsRouter } from './api/events.js';
|
|
|
10
10
|
const app = express();
|
|
11
11
|
|
|
12
12
|
app.use(express.json());
|
|
13
|
-
app.use(express.static('public'));
|
|
14
|
-
app.use('/src', express.static('src'));
|
|
15
13
|
|
|
16
14
|
app.use('/api', eventsRouter);
|
|
17
15
|
app.use('/api', entityRouter);
|
|
18
16
|
|
|
17
|
+
app.use(express.static('src'));
|
|
18
|
+
|
|
19
19
|
// SPA fallback
|
|
20
20
|
app.use((req, res, next) => {
|
|
21
|
-
if (req.method === 'GET' && !req.path.includes('.')) {
|
|
22
|
-
return res.sendFile('index.html', { root: 'public' });
|
|
21
|
+
if (req.method === 'GET' && !req.path.includes('.') && !req.path.startsWith('/api')) {
|
|
22
|
+
return res.sendFile('index.html', { root: 'src/public' });
|
|
23
23
|
}
|
|
24
24
|
next();
|
|
25
25
|
});
|
package/templates/shared/.env
CHANGED
|
@@ -12,7 +12,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
12
12
|
|
|
13
13
|
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
14
14
|
const ICONS_DIR = resolve(ROOT, 'node_modules/lucide-static/icons');
|
|
15
|
-
const OUT = resolve(ROOT, 'public/icons.json');
|
|
15
|
+
const OUT = resolve(ROOT, 'src/public/icons.json');
|
|
16
16
|
|
|
17
17
|
/** Icons used in the app — lucide name → app name */
|
|
18
18
|
const ICON_MAP = {
|
|
@@ -83,4 +83,4 @@ for (const [lucideName, appName] of Object.entries(ICON_MAP)) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
writeFileSync(OUT, JSON.stringify(icons, null, 2));
|
|
86
|
-
console.log(`✓ Built ${count} icons → public/icons.json`);
|
|
86
|
+
console.log(`✓ Built ${count} icons → src/public/icons.json`);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Post-install setup — vendors dependencies and builds icon sprite.
|
|
5
|
+
* @module scripts/setup
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { dirname, resolve } from 'node:path';
|
|
9
|
+
import { fileURLToPath } from 'node:url';
|
|
10
|
+
|
|
11
|
+
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
12
|
+
|
|
13
|
+
await import(resolve(ROOT, 'scripts/vendor-deps.js'));
|
|
14
|
+
await import(resolve(ROOT, 'scripts/build-icons.js'));
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Test runner — finds and executes all .test.js files.
|
|
5
|
+
* @module scripts/test
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { execSync } from 'node:child_process';
|
|
9
|
+
import { dirname, resolve } from 'node:path';
|
|
10
|
+
import { fileURLToPath } from 'node:url';
|
|
11
|
+
import { readdirSync, statSync } from 'node:fs';
|
|
12
|
+
|
|
13
|
+
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
14
|
+
|
|
15
|
+
/** @param {string} dir @returns {string[]} */
|
|
16
|
+
function findTests(dir) {
|
|
17
|
+
const results = [];
|
|
18
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
19
|
+
const full = resolve(dir, entry.name);
|
|
20
|
+
if (entry.name === 'node_modules' || entry.name === 'public') continue;
|
|
21
|
+
if (entry.isDirectory()) results.push(...findTests(full));
|
|
22
|
+
else if (entry.name.endsWith('.test.js')) results.push(full);
|
|
23
|
+
}
|
|
24
|
+
return results;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const files = findTests(ROOT);
|
|
28
|
+
if (files.length === 0) {
|
|
29
|
+
console.log('No test files found.');
|
|
30
|
+
process.exit(0);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
try {
|
|
34
|
+
execSync(`node --test ${files.join(' ')}`, { cwd: ROOT, stdio: 'inherit' });
|
|
35
|
+
} catch {
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
@@ -10,7 +10,7 @@ import { resolve, dirname } from 'node:path';
|
|
|
10
10
|
import { fileURLToPath } from 'node:url';
|
|
11
11
|
|
|
12
12
|
const ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
13
|
-
const VENDOR_DIR = resolve(ROOT, 'public/vendor');
|
|
13
|
+
const VENDOR_DIR = resolve(ROOT, 'src/public/vendor');
|
|
14
14
|
|
|
15
15
|
/** @type {{ name: string, src: string }[]} */
|
|
16
16
|
const DEPS = [{ name: 'hybrids', src: 'node_modules/hybrids/src' }];
|
|
@@ -21,5 +21,5 @@ for (const dep of DEPS) {
|
|
|
21
21
|
const src = resolve(ROOT, dep.src);
|
|
22
22
|
const dest = resolve(VENDOR_DIR, dep.name);
|
|
23
23
|
cpSync(src, dest, { recursive: true });
|
|
24
|
-
console.log(`✓ Vendored: ${dep.name} → public/vendor/${dep.name}/`);
|
|
24
|
+
console.log(`✓ Vendored: ${dep.name} → src/public/vendor/${dep.name}/`);
|
|
25
25
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
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
|
+
<link rel="stylesheet" href="/styles/reset.css">
|
|
8
|
+
<link rel="stylesheet" href="/styles/tokens.css">
|
|
9
|
+
<link rel="stylesheet" href="/styles/shared.css">
|
|
10
|
+
<link rel="stylesheet" href="/styles/buttons.css">
|
|
11
|
+
<link rel="stylesheet" href="/styles/forms.css">
|
|
12
|
+
<link rel="stylesheet" href="/styles/components.css">
|
|
13
|
+
|
|
14
|
+
<script type="importmap">
|
|
15
|
+
{
|
|
16
|
+
"imports": {
|
|
17
|
+
"hybrids": "/public/vendor/hybrids/index.js"
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
</script>
|
|
21
|
+
</head>
|
|
22
|
+
<body>
|
|
23
|
+
<app-router></app-router>
|
|
24
|
+
<script type="module" src="/router/index.js"></script>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
@@ -1,26 +0,0 @@
|
|
|
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
|
-
<link rel="stylesheet" href="/src/styles/reset.css">
|
|
8
|
-
<link rel="stylesheet" href="/src/styles/tokens.css">
|
|
9
|
-
<link rel="stylesheet" href="/src/styles/shared.css">
|
|
10
|
-
<link rel="stylesheet" href="/src/styles/buttons.css">
|
|
11
|
-
<link rel="stylesheet" href="/src/styles/forms.css">
|
|
12
|
-
<link rel="stylesheet" href="/src/styles/components.css">
|
|
13
|
-
|
|
14
|
-
<script type="importmap">
|
|
15
|
-
{
|
|
16
|
-
"imports": {
|
|
17
|
-
"hybrids": "/vendor/hybrids/index.js"
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
</script>
|
|
21
|
-
</head>
|
|
22
|
-
<body>
|
|
23
|
-
<app-router></app-router>
|
|
24
|
-
<script type="module" src="/src/router/index.js"></script>
|
|
25
|
-
</body>
|
|
26
|
-
</html>
|