@oss-ma/tpl 1.0.2 → 1.0.5

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.
@@ -15,27 +15,48 @@ const TEXT_EXT = new Set([
15
15
  ".scss",
16
16
  ".txt",
17
17
  ".env",
18
- ".gitignore",
19
18
  ".editorconfig",
20
19
  ".gitattributes",
21
20
  ".cjs",
22
21
  ".mjs"
23
22
  ]);
24
- /**
25
- * Dotfiles that MUST be copied if present in template root.
26
- * Some Windows + tooling edge cases can hide them from readdir.
27
- */
28
- const MUST_COPY_DOTFILES = [".gitignore", ".editorconfig", ".gitattributes"];
23
+ // Files that ship without dot, but must be generated as dotfiles.
24
+ const DOTFILE_MAP = {
25
+ "gitignore": ".gitignore",
26
+ "editorconfig": ".editorconfig",
27
+ "gitattributes": ".gitattributes",
28
+ "prettierrc.json": ".prettierrc.json",
29
+ "env": ".env",
30
+ "env.example": ".env.example",
31
+ "nvmrc": ".nvmrc",
32
+ "node-version": ".node-version",
33
+ };
34
+ function mapDestName(name) {
35
+ if (name.startsWith("."))
36
+ return name;
37
+ return DOTFILE_MAP[name] ?? name;
38
+ }
29
39
  function isTextFile(filePath) {
30
40
  const ext = path.extname(filePath).toLowerCase();
31
41
  if (TEXT_EXT.has(ext))
32
42
  return true;
33
43
  const base = path.basename(filePath);
44
+ // Special cases without extension
34
45
  if (base === "Dockerfile")
35
46
  return true;
47
+ if (base === "gitignore")
48
+ return true;
49
+ if (base === "editorconfig")
50
+ return true;
51
+ if (base === "gitattributes")
52
+ return true;
53
+ if (base === "nvmrc")
54
+ return true;
55
+ if (base === "node-version")
56
+ return true;
36
57
  return false;
37
58
  }
38
- async function copyOneFile(srcPath, destPath, vars) {
59
+ async function copyOne(srcPath, destPath, vars) {
39
60
  await fs.ensureDir(path.dirname(destPath));
40
61
  if (isTextFile(srcPath)) {
41
62
  const raw = await fs.readFile(srcPath, "utf8");
@@ -48,28 +69,17 @@ async function copyOneFile(srcPath, destPath, vars) {
48
69
  }
49
70
  export async function copyAndRenderDir(srcDir, destDir, vars) {
50
71
  await fs.ensureDir(destDir);
51
- // 0) Fail-safe: explicitly copy must-have dotfiles if they exist in this directory
52
- // (especially important for template root where .gitignore lives)
53
- for (const dot of MUST_COPY_DOTFILES) {
54
- const srcDot = path.join(srcDir, dot);
55
- const destDot = path.join(destDir, dot);
56
- if (await fs.pathExists(srcDot)) {
57
- await copyOneFile(srcDot, destDot, vars);
58
- }
59
- }
60
72
  const entries = await fs.readdir(srcDir, { withFileTypes: true });
61
73
  for (const entry of entries) {
62
- // Skip the dotfiles already handled explicitly above (avoid duplicate work)
63
- if (MUST_COPY_DOTFILES.includes(entry.name))
64
- continue;
65
74
  const srcPath = path.join(srcDir, entry.name);
66
- const destPath = path.join(destDir, entry.name);
75
+ const destName = mapDestName(entry.name);
76
+ const destPath = path.join(destDir, destName);
67
77
  if (entry.isDirectory()) {
68
78
  await copyAndRenderDir(srcPath, destPath, vars);
69
79
  continue;
70
80
  }
71
81
  if (!entry.isFile())
72
82
  continue;
73
- await copyOneFile(srcPath, destPath, vars);
83
+ await copyOne(srcPath, destPath, vars);
74
84
  }
75
85
  }
package/package.json CHANGED
@@ -1,12 +1,15 @@
1
1
  {
2
2
  "name": "@oss-ma/tpl",
3
- "version": "1.0.2",
3
+ "version": "1.0.5",
4
4
  "description": "Generate, enforce and maintain clean project architectures",
5
5
  "type": "module",
6
6
  "bin": {
7
7
  "tpl": "./dist/index.js"
8
8
  },
9
- "files": ["dist", "resources"],
9
+ "files": [
10
+ "dist",
11
+ "resources"
12
+ ],
10
13
  "engines": {
11
14
  "node": ">=18"
12
15
  },
@@ -30,4 +33,4 @@
30
33
  "tsx": "^4.16.2",
31
34
  "typescript": "^5.5.4"
32
35
  }
33
- }
36
+ }
@@ -0,0 +1,8 @@
1
+ node_modules
2
+ dist
3
+ coverage
4
+ .env
5
+ .env.*
6
+ .DS_Store
7
+ .vscode
8
+ .idea