create-gen-app 0.3.6 → 0.5.0
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/README.md +5 -2
- package/esm/template/extract.js +15 -9
- package/esm/template/replace.js +4 -1
- package/licenses-templates/CLOSED.txt +20 -0
- package/package.json +2 -2
- package/template/extract.js +15 -9
- package/template/replace.js +4 -1
- package/types.d.ts +1 -1
package/README.md
CHANGED
|
@@ -114,10 +114,11 @@ export const author = "____fullName____";
|
|
|
114
114
|
|
|
115
115
|
### Custom Questions
|
|
116
116
|
|
|
117
|
-
Create a `.
|
|
117
|
+
Create a `.boilerplate.json`:
|
|
118
118
|
|
|
119
119
|
```json
|
|
120
120
|
{
|
|
121
|
+
"type": "module",
|
|
121
122
|
"questions": [
|
|
122
123
|
{
|
|
123
124
|
"name": "____fullName____",
|
|
@@ -135,7 +136,9 @@ Create a `.questions.json`:
|
|
|
135
136
|
}
|
|
136
137
|
```
|
|
137
138
|
|
|
138
|
-
Or `.
|
|
139
|
+
Or `.boilerplate.js` for dynamic logic. Question names can use `____var____` or plain `VAR`; they'll be normalized automatically.
|
|
140
|
+
|
|
141
|
+
Note: `.boilerplate.json`, `.boilerplate.js`, and `.boilerplates.json` files are automatically excluded from the generated output.
|
|
139
142
|
|
|
140
143
|
### License Templates
|
|
141
144
|
|
package/esm/template/extract.js
CHANGED
|
@@ -18,8 +18,10 @@ export async function extractVariables(templateDir) {
|
|
|
18
18
|
const projectQuestions = await loadProjectQuestions(templateDir);
|
|
19
19
|
await walkDirectory(templateDir, async (filePath) => {
|
|
20
20
|
const relativePath = path.relative(templateDir, filePath);
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// Skip boilerplate configuration files from variable extraction
|
|
22
|
+
if (relativePath === '.boilerplate.json' ||
|
|
23
|
+
relativePath === '.boilerplate.js' ||
|
|
24
|
+
relativePath === '.boilerplates.json') {
|
|
23
25
|
return;
|
|
24
26
|
}
|
|
25
27
|
const matches = relativePath.matchAll(VARIABLE_PATTERN);
|
|
@@ -101,33 +103,37 @@ async function walkDirectory(dir, callback) {
|
|
|
101
103
|
}
|
|
102
104
|
}
|
|
103
105
|
/**
|
|
104
|
-
* Load project questions from .
|
|
106
|
+
* Load project questions from .boilerplate.json or .boilerplate.js
|
|
105
107
|
* @param templateDir - Path to the template directory
|
|
106
108
|
* @returns Questions object or null if not found
|
|
107
109
|
*/
|
|
108
110
|
async function loadProjectQuestions(templateDir) {
|
|
109
|
-
const jsonPath = path.join(templateDir, '.
|
|
111
|
+
const jsonPath = path.join(templateDir, '.boilerplate.json');
|
|
110
112
|
if (fs.existsSync(jsonPath)) {
|
|
111
113
|
try {
|
|
112
114
|
const content = fs.readFileSync(jsonPath, 'utf8');
|
|
113
|
-
const
|
|
115
|
+
const parsed = JSON.parse(content);
|
|
116
|
+
// .boilerplate.json has { questions: [...] } structure
|
|
117
|
+
const questions = parsed.questions ? { questions: parsed.questions } : parsed;
|
|
114
118
|
return validateQuestions(questions) ? normalizeQuestions(questions) : null;
|
|
115
119
|
}
|
|
116
120
|
catch (error) {
|
|
117
121
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
118
|
-
console.warn(`Failed to parse .
|
|
122
|
+
console.warn(`Failed to parse .boilerplate.json: ${errorMessage}`);
|
|
119
123
|
}
|
|
120
124
|
}
|
|
121
|
-
const jsPath = path.join(templateDir, '.
|
|
125
|
+
const jsPath = path.join(templateDir, '.boilerplate.js');
|
|
122
126
|
if (fs.existsSync(jsPath)) {
|
|
123
127
|
try {
|
|
124
128
|
const module = require(jsPath);
|
|
125
|
-
const
|
|
129
|
+
const exported = module.default || module;
|
|
130
|
+
// .boilerplate.js can export { questions: [...] } or just the questions array
|
|
131
|
+
const questions = exported.questions ? { questions: exported.questions } : exported;
|
|
126
132
|
return validateQuestions(questions) ? normalizeQuestions(questions) : null;
|
|
127
133
|
}
|
|
128
134
|
catch (error) {
|
|
129
135
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
130
|
-
console.warn(`Failed to load .
|
|
136
|
+
console.warn(`Failed to load .boilerplate.js: ${errorMessage}`);
|
|
131
137
|
}
|
|
132
138
|
}
|
|
133
139
|
return null;
|
package/esm/template/replace.js
CHANGED
|
@@ -31,7 +31,10 @@ async function walkAndReplace(sourceDir, destDir, extractedVariables, answers, s
|
|
|
31
31
|
const entries = fs.readdirSync(currentSource, { withFileTypes: true });
|
|
32
32
|
for (const entry of entries) {
|
|
33
33
|
const sourceEntryPath = path.join(currentSource, entry.name);
|
|
34
|
-
|
|
34
|
+
// Skip template configuration files - they should not be copied to output
|
|
35
|
+
if (entry.name === '.boilerplate.json' ||
|
|
36
|
+
entry.name === '.boilerplate.js' ||
|
|
37
|
+
entry.name === '.boilerplates.json') {
|
|
35
38
|
continue;
|
|
36
39
|
}
|
|
37
40
|
let newName = entry.name;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
Copyright (c) {{YEAR}} {{AUTHOR}}{{EMAIL_LINE}}
|
|
2
|
+
|
|
3
|
+
All Rights Reserved.
|
|
4
|
+
|
|
5
|
+
This software and associated documentation files (the "Software") are the
|
|
6
|
+
exclusive property of the copyright holder. No part of the Software may be
|
|
7
|
+
reproduced, distributed, modified, or transmitted in any form or by any means,
|
|
8
|
+
including photocopying, recording, or other electronic or mechanical methods,
|
|
9
|
+
without the prior written permission of the copyright holder.
|
|
10
|
+
|
|
11
|
+
Unauthorized copying, modification, distribution, or use of this Software,
|
|
12
|
+
via any medium, is strictly prohibited.
|
|
13
|
+
|
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
15
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
16
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
17
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
18
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
19
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
20
|
+
SOFTWARE.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-gen-app",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"author": "Constructive <developers@constructive.io>",
|
|
5
5
|
"description": "Clone and customize template repositories with variable replacement",
|
|
6
6
|
"main": "index.js",
|
|
@@ -36,5 +36,5 @@
|
|
|
36
36
|
"makage": "0.1.8"
|
|
37
37
|
},
|
|
38
38
|
"keywords": [],
|
|
39
|
-
"gitHead": "
|
|
39
|
+
"gitHead": "725145c7e4cf22c296c3d87b8664444b3303e313"
|
|
40
40
|
}
|
package/template/extract.js
CHANGED
|
@@ -54,8 +54,10 @@ async function extractVariables(templateDir) {
|
|
|
54
54
|
const projectQuestions = await loadProjectQuestions(templateDir);
|
|
55
55
|
await walkDirectory(templateDir, async (filePath) => {
|
|
56
56
|
const relativePath = path.relative(templateDir, filePath);
|
|
57
|
-
|
|
58
|
-
|
|
57
|
+
// Skip boilerplate configuration files from variable extraction
|
|
58
|
+
if (relativePath === '.boilerplate.json' ||
|
|
59
|
+
relativePath === '.boilerplate.js' ||
|
|
60
|
+
relativePath === '.boilerplates.json') {
|
|
59
61
|
return;
|
|
60
62
|
}
|
|
61
63
|
const matches = relativePath.matchAll(VARIABLE_PATTERN);
|
|
@@ -137,33 +139,37 @@ async function walkDirectory(dir, callback) {
|
|
|
137
139
|
}
|
|
138
140
|
}
|
|
139
141
|
/**
|
|
140
|
-
* Load project questions from .
|
|
142
|
+
* Load project questions from .boilerplate.json or .boilerplate.js
|
|
141
143
|
* @param templateDir - Path to the template directory
|
|
142
144
|
* @returns Questions object or null if not found
|
|
143
145
|
*/
|
|
144
146
|
async function loadProjectQuestions(templateDir) {
|
|
145
|
-
const jsonPath = path.join(templateDir, '.
|
|
147
|
+
const jsonPath = path.join(templateDir, '.boilerplate.json');
|
|
146
148
|
if (fs.existsSync(jsonPath)) {
|
|
147
149
|
try {
|
|
148
150
|
const content = fs.readFileSync(jsonPath, 'utf8');
|
|
149
|
-
const
|
|
151
|
+
const parsed = JSON.parse(content);
|
|
152
|
+
// .boilerplate.json has { questions: [...] } structure
|
|
153
|
+
const questions = parsed.questions ? { questions: parsed.questions } : parsed;
|
|
150
154
|
return validateQuestions(questions) ? normalizeQuestions(questions) : null;
|
|
151
155
|
}
|
|
152
156
|
catch (error) {
|
|
153
157
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
154
|
-
console.warn(`Failed to parse .
|
|
158
|
+
console.warn(`Failed to parse .boilerplate.json: ${errorMessage}`);
|
|
155
159
|
}
|
|
156
160
|
}
|
|
157
|
-
const jsPath = path.join(templateDir, '.
|
|
161
|
+
const jsPath = path.join(templateDir, '.boilerplate.js');
|
|
158
162
|
if (fs.existsSync(jsPath)) {
|
|
159
163
|
try {
|
|
160
164
|
const module = require(jsPath);
|
|
161
|
-
const
|
|
165
|
+
const exported = module.default || module;
|
|
166
|
+
// .boilerplate.js can export { questions: [...] } or just the questions array
|
|
167
|
+
const questions = exported.questions ? { questions: exported.questions } : exported;
|
|
162
168
|
return validateQuestions(questions) ? normalizeQuestions(questions) : null;
|
|
163
169
|
}
|
|
164
170
|
catch (error) {
|
|
165
171
|
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
166
|
-
console.warn(`Failed to load .
|
|
172
|
+
console.warn(`Failed to load .boilerplate.js: ${errorMessage}`);
|
|
167
173
|
}
|
|
168
174
|
}
|
|
169
175
|
return null;
|
package/template/replace.js
CHANGED
|
@@ -67,7 +67,10 @@ async function walkAndReplace(sourceDir, destDir, extractedVariables, answers, s
|
|
|
67
67
|
const entries = fs.readdirSync(currentSource, { withFileTypes: true });
|
|
68
68
|
for (const entry of entries) {
|
|
69
69
|
const sourceEntryPath = path.join(currentSource, entry.name);
|
|
70
|
-
|
|
70
|
+
// Skip template configuration files - they should not be copied to output
|
|
71
|
+
if (entry.name === '.boilerplate.json' ||
|
|
72
|
+
entry.name === '.boilerplate.js' ||
|
|
73
|
+
entry.name === '.boilerplates.json') {
|
|
71
74
|
continue;
|
|
72
75
|
}
|
|
73
76
|
let newName = entry.name;
|
package/types.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Question } from 'inquirerer';
|
|
2
2
|
/**
|
|
3
|
-
* Questions configuration that can be loaded from .
|
|
3
|
+
* Questions configuration that can be loaded from .boilerplate.json or .boilerplate.js
|
|
4
4
|
* @typedef {Object} Questions
|
|
5
5
|
* @property {Question[]} questions - Array of inquirerer questions
|
|
6
6
|
*/
|