@techninja/clearstack 0.2.4 → 0.2.6
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/copy.js
CHANGED
|
@@ -3,11 +3,17 @@
|
|
|
3
3
|
* @module lib/copy
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { readdirSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
6
|
+
import { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from 'node:fs';
|
|
7
7
|
import { join, resolve } from 'node:path';
|
|
8
8
|
|
|
9
9
|
const TEMPLATE_RE = /\{\{(\w+)\}\}/g;
|
|
10
10
|
|
|
11
|
+
/** Files renamed during copy (npm strips .gitignore from packages). */
|
|
12
|
+
const RENAME = { gitignore: '.gitignore' };
|
|
13
|
+
|
|
14
|
+
/** Files that merge (append missing lines) instead of overwriting. */
|
|
15
|
+
const MERGE = new Set(['.gitignore']);
|
|
16
|
+
|
|
11
17
|
/**
|
|
12
18
|
* Recursively copy a template directory, replacing {{vars}} in file contents.
|
|
13
19
|
* @param {string} templateRoot - Root templates/ directory
|
|
@@ -29,7 +35,8 @@ async function copyDir(src, dest, vars) {
|
|
|
29
35
|
mkdirSync(dest, { recursive: true });
|
|
30
36
|
for (const entry of readdirSync(src, { withFileTypes: true })) {
|
|
31
37
|
const srcPath = join(src, entry.name);
|
|
32
|
-
const
|
|
38
|
+
const destName = RENAME[entry.name] || entry.name;
|
|
39
|
+
const destPath = join(dest, destName);
|
|
33
40
|
if (entry.isDirectory()) {
|
|
34
41
|
await copyDir(srcPath, destPath, vars);
|
|
35
42
|
} else {
|
|
@@ -37,7 +44,27 @@ async function copyDir(src, dest, vars) {
|
|
|
37
44
|
const replaced = content.replace(TEMPLATE_RE, (_, key) =>
|
|
38
45
|
vars[key] !== undefined ? String(vars[key]) : `{{${key}}}`,
|
|
39
46
|
);
|
|
40
|
-
|
|
47
|
+
if (MERGE.has(destName) && existsSync(destPath)) {
|
|
48
|
+
mergeLines(destPath, replaced);
|
|
49
|
+
} else {
|
|
50
|
+
writeFileSync(destPath, replaced);
|
|
51
|
+
}
|
|
41
52
|
}
|
|
42
53
|
}
|
|
43
54
|
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Append lines from source that don't already exist in the destination file.
|
|
58
|
+
* @param {string} destPath
|
|
59
|
+
* @param {string} newContent
|
|
60
|
+
*/
|
|
61
|
+
function mergeLines(destPath, newContent) {
|
|
62
|
+
const existing = readFileSync(destPath, 'utf-8');
|
|
63
|
+
const existingLines = new Set(existing.split('\n').map((l) => l.trim()));
|
|
64
|
+
const toAdd = newContent.split('\n')
|
|
65
|
+
.filter((l) => l.trim() && !existingLines.has(l.trim()));
|
|
66
|
+
if (toAdd.length > 0) {
|
|
67
|
+
const sep = existing.endsWith('\n') ? '' : '\n';
|
|
68
|
+
writeFileSync(destPath, existing + sep + toAdd.join('\n') + '\n');
|
|
69
|
+
}
|
|
70
|
+
}
|
package/lib/package-gen.js
CHANGED
|
@@ -43,6 +43,7 @@ export async function writePackageJson(dest, vars, existing) {
|
|
|
43
43
|
|
|
44
44
|
const specDevDeps = {
|
|
45
45
|
'@techninja/clearstack': '^0.2.0',
|
|
46
|
+
'@types/node': '^22.0.0',
|
|
46
47
|
'@open-wc/testing': '^4.0.0',
|
|
47
48
|
'@web/test-runner': '^0.20.0',
|
|
48
49
|
'@web/test-runner-playwright': '^0.11.0',
|
package/lib/update.js
CHANGED
|
@@ -57,6 +57,22 @@ export async function update(pkgRoot) {
|
|
|
57
57
|
'.configs',
|
|
58
58
|
);
|
|
59
59
|
|
|
60
|
+
// Merge .gitignore (append missing lines, never remove user entries)
|
|
61
|
+
const gitignoreSrc = resolve(templateShared, 'gitignore');
|
|
62
|
+
if (existsSync(gitignoreSrc)) {
|
|
63
|
+
const destPath = resolve(process.cwd(), '.gitignore');
|
|
64
|
+
const srcLines = readFileSync(gitignoreSrc, 'utf-8').split('\n').filter((l) => l.trim());
|
|
65
|
+
const existing = existsSync(destPath) ? readFileSync(destPath, 'utf-8') : '';
|
|
66
|
+
const existingSet = new Set(existing.split('\n').map((l) => l.trim()));
|
|
67
|
+
const toAdd = srcLines.filter((l) => !existingSet.has(l.trim()));
|
|
68
|
+
if (toAdd.length > 0) {
|
|
69
|
+
const sep = existing.endsWith('\n') ? '' : '\n';
|
|
70
|
+
writeFileSync(destPath, existing + sep + toAdd.join('\n') + '\n');
|
|
71
|
+
console.log(` ✓ Merged: .gitignore (+${toAdd.length} entries)`);
|
|
72
|
+
total++;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
60
76
|
// Write spec version marker
|
|
61
77
|
const pkg = JSON.parse(readFileSync(resolve(pkgRoot, 'package.json'), 'utf-8'));
|
|
62
78
|
const versionPath = resolve(process.cwd(), 'docs/clearstack/.specversion');
|
package/package.json
CHANGED
|
@@ -26,7 +26,8 @@ export default define({
|
|
|
26
26
|
<div class="home-view">
|
|
27
27
|
<h1>{{name}}</h1>
|
|
28
28
|
<p>Your Clearstack project is ready. Start building!</p>
|
|
29
|
-
${store.ready(state) &&
|
|
29
|
+
${store.ready(state) &&
|
|
30
|
+
html`
|
|
30
31
|
<p>Count: ${state.count}</p>
|
|
31
32
|
<button class="btn btn-primary" onclick="${increment}">Increment</button>
|
|
32
33
|
<p class="hint">State persists in localStorage — refresh to verify.</p>
|