simple-scaffold 1.3.0 → 1.3.2
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/cmd.d.ts +2 -0
- package/cmd.js +127 -0
- package/cmd.js.map +1 -0
- package/index.d.ts +4 -0
- package/index.js +24 -0
- package/index.js.map +1 -0
- package/package.json +1 -4
- package/scaffold.d.ts +34 -0
- package/scaffold.js +113 -0
- package/scaffold.js.map +1 -0
- package/types.d.ts +310 -0
- package/types.js +32 -0
- package/types.js.map +1 -0
- package/utils.d.ts +66 -0
- package/utils.js +303 -0
- package/utils.js.map +1 -0
- package/.editorconfig +0 -8
- package/.github/FUNDING.yml +0 -13
- package/.github/ISSUE_TEMPLATE/bug_report.md +0 -47
- package/.github/ISSUE_TEMPLATE/feature_request.md +0 -24
- package/.github/workflows/docs.yml +0 -20
- package/.github/workflows/pull_requests.yml +0 -17
- package/.github/workflows/release.yml +0 -22
- package/.markdownlint.json +0 -9
- package/.prettierrc +0 -15
- package/.vscode/launch.json +0 -27
- package/.vscode/settings.json +0 -22
- package/.vscode/tasks.json +0 -59
- package/CHANGELOG.md +0 -111
- package/LICENSE +0 -21
- package/examples/test-input/Component/.hidden-file +0 -0
- package/examples/test-input/Component/button-example.png +0 -0
- package/examples/test-input/Component/inner/inner-{{name}}.txt +0 -1
- package/examples/test-input/Component/{{Name}}.tsx +0 -17
- package/examples/test-input/scaffold.config.js +0 -13
- package/jest.config.ts +0 -205
- package/media/intro.gif +0 -0
- package/pages/README.md +0 -7
- package/pages/cli.md +0 -74
- package/pages/configuration_files.md +0 -86
- package/pages/migration.md +0 -25
- package/pages/node.md +0 -53
- package/pages/templates.md +0 -224
- package/release.config.js +0 -76
- package/src/cmd.ts +0 -131
- package/src/docs.css +0 -55
- package/src/index.ts +0 -4
- package/src/scaffold.ts +0 -140
- package/src/types.ts +0 -342
- package/src/utils.ts +0 -423
- package/tests/scaffold.test.ts +0 -502
- package/tests/utils.test.ts +0 -124
- package/tsconfig.json +0 -16
- package/typedoc.config.js +0 -63
package/tests/scaffold.test.ts
DELETED
|
@@ -1,502 +0,0 @@
|
|
|
1
|
-
import mockFs from "mock-fs"
|
|
2
|
-
import FileSystem from "mock-fs/lib/filesystem"
|
|
3
|
-
import Scaffold from "../src/scaffold"
|
|
4
|
-
import { readdirSync, readFileSync } from "fs"
|
|
5
|
-
import { Console } from "console"
|
|
6
|
-
import { defaultHelpers } from "../src/utils"
|
|
7
|
-
import { join } from "path"
|
|
8
|
-
import * as dateFns from "date-fns"
|
|
9
|
-
import crypto from "crypto"
|
|
10
|
-
|
|
11
|
-
const fileStructNormal = {
|
|
12
|
-
input: {
|
|
13
|
-
"{{name}}.txt": "Hello, my app is {{name}}",
|
|
14
|
-
},
|
|
15
|
-
output: {},
|
|
16
|
-
}
|
|
17
|
-
const fileStructWithBinary = {
|
|
18
|
-
input: {
|
|
19
|
-
"{{name}}.txt": "Hello, my app is {{name}}",
|
|
20
|
-
"{{name}}.bin": crypto.randomBytes(10000),
|
|
21
|
-
},
|
|
22
|
-
output: {},
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
const fileStructWithData = {
|
|
26
|
-
input: {
|
|
27
|
-
"{{name}}.txt": "Hello, my value is {{value}}",
|
|
28
|
-
},
|
|
29
|
-
output: {},
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const fileStructNested = {
|
|
33
|
-
input: {
|
|
34
|
-
"{{name}}-1.txt": "This should be in root",
|
|
35
|
-
"{{Name}}": {
|
|
36
|
-
"{{name}}-2.txt": "Hello, my value is {{value}}",
|
|
37
|
-
moreNesting: {
|
|
38
|
-
"{{name}}-3.txt": "Hi! My value is actually NOT {{value}}!",
|
|
39
|
-
},
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
output: {},
|
|
43
|
-
}
|
|
44
|
-
const fileStructSubdirTransformer = {
|
|
45
|
-
input: {
|
|
46
|
-
"{{name}}.txt": "Hello, my app is {{name}}",
|
|
47
|
-
},
|
|
48
|
-
output: {},
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
const defaultHelperNames = Object.keys(defaultHelpers)
|
|
52
|
-
const fileStructHelpers = {
|
|
53
|
-
input: {
|
|
54
|
-
defaults: defaultHelperNames.reduce<Record<string, string>>(
|
|
55
|
-
(all, cur) => ({ ...all, [cur + ".txt"]: `{{ ${cur} name }}` }),
|
|
56
|
-
{},
|
|
57
|
-
),
|
|
58
|
-
custom: {
|
|
59
|
-
"add1.txt": "{{ add1 name }}",
|
|
60
|
-
},
|
|
61
|
-
},
|
|
62
|
-
output: {},
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const fileStructDates = {
|
|
66
|
-
input: {
|
|
67
|
-
"now.txt": "Today is {{ now 'mmm' }}, time is {{ now 'HH:mm' }}",
|
|
68
|
-
"offset.txt": "Yesterday was {{ now 'mmm' -1 'days' }}, time is {{ now 'HH:mm' -1 'days' }}",
|
|
69
|
-
"custom.txt": "Custom date is {{ date customDate 'mmm' }}, time is {{ date customDate 'HH:mm' }}",
|
|
70
|
-
},
|
|
71
|
-
output: {},
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
function withMock(fileStruct: FileSystem.DirectoryItems, testFn: jest.EmptyFunction): jest.EmptyFunction {
|
|
75
|
-
return () => {
|
|
76
|
-
beforeEach(() => {
|
|
77
|
-
// console.log("Mocking:", fileStruct)
|
|
78
|
-
console = new Console(process.stdout, process.stderr)
|
|
79
|
-
|
|
80
|
-
mockFs(fileStruct)
|
|
81
|
-
// logMock = jest.spyOn(console, 'log').mockImplementation((...args) => {
|
|
82
|
-
// logsTemp.push(args)
|
|
83
|
-
// })
|
|
84
|
-
})
|
|
85
|
-
testFn()
|
|
86
|
-
afterEach(() => {
|
|
87
|
-
// console.log("Restoring mock")
|
|
88
|
-
mockFs.restore()
|
|
89
|
-
})
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
describe("Scaffold", () => {
|
|
94
|
-
describe(
|
|
95
|
-
"create subfolder",
|
|
96
|
-
withMock(fileStructNormal, () => {
|
|
97
|
-
test("should not create by default", async () => {
|
|
98
|
-
await Scaffold({
|
|
99
|
-
name: "app_name",
|
|
100
|
-
output: "output",
|
|
101
|
-
templates: ["input"],
|
|
102
|
-
verbose: 0,
|
|
103
|
-
})
|
|
104
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
105
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
106
|
-
})
|
|
107
|
-
|
|
108
|
-
test("should create with config", async () => {
|
|
109
|
-
await Scaffold({
|
|
110
|
-
name: "app_name",
|
|
111
|
-
output: "output",
|
|
112
|
-
templates: ["input"],
|
|
113
|
-
createSubFolder: true,
|
|
114
|
-
verbose: 0,
|
|
115
|
-
})
|
|
116
|
-
|
|
117
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name", "app_name.txt"))
|
|
118
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
119
|
-
})
|
|
120
|
-
}),
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
describe(
|
|
124
|
-
"binary files",
|
|
125
|
-
withMock(fileStructWithBinary, () => {
|
|
126
|
-
test("should copy as-is", async () => {
|
|
127
|
-
await Scaffold({
|
|
128
|
-
name: "app_name",
|
|
129
|
-
output: "output",
|
|
130
|
-
templates: ["input"],
|
|
131
|
-
verbose: 0,
|
|
132
|
-
})
|
|
133
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
134
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
135
|
-
const dataBin = readFileSync(join(process.cwd(), "output", "app_name.bin"))
|
|
136
|
-
expect(dataBin).toEqual(fileStructWithBinary.input["{{name}}.bin"])
|
|
137
|
-
})
|
|
138
|
-
}),
|
|
139
|
-
)
|
|
140
|
-
|
|
141
|
-
describe(
|
|
142
|
-
"overwrite",
|
|
143
|
-
withMock(fileStructWithData, () => {
|
|
144
|
-
test("should not overwrite by default", async () => {
|
|
145
|
-
await Scaffold({
|
|
146
|
-
name: "app_name",
|
|
147
|
-
output: "output",
|
|
148
|
-
templates: ["input"],
|
|
149
|
-
data: { value: "1" },
|
|
150
|
-
verbose: 0,
|
|
151
|
-
})
|
|
152
|
-
|
|
153
|
-
await Scaffold({
|
|
154
|
-
name: "app_name",
|
|
155
|
-
output: "output",
|
|
156
|
-
templates: ["input"],
|
|
157
|
-
data: { value: "2" },
|
|
158
|
-
verbose: 0,
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
162
|
-
expect(data.toString()).toEqual("Hello, my value is 1")
|
|
163
|
-
})
|
|
164
|
-
|
|
165
|
-
test("should overwrite with config", async () => {
|
|
166
|
-
await Scaffold({
|
|
167
|
-
name: "app_name",
|
|
168
|
-
output: "output",
|
|
169
|
-
templates: ["input"],
|
|
170
|
-
data: { value: "1" },
|
|
171
|
-
verbose: 0,
|
|
172
|
-
})
|
|
173
|
-
|
|
174
|
-
await Scaffold({
|
|
175
|
-
name: "app_name",
|
|
176
|
-
output: "output",
|
|
177
|
-
templates: ["input"],
|
|
178
|
-
data: { value: "2" },
|
|
179
|
-
overwrite: true,
|
|
180
|
-
verbose: 0,
|
|
181
|
-
})
|
|
182
|
-
|
|
183
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
184
|
-
expect(data.toString()).toEqual("Hello, my value is 2")
|
|
185
|
-
})
|
|
186
|
-
}),
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
describe(
|
|
190
|
-
"errors",
|
|
191
|
-
withMock(fileStructNormal, () => {
|
|
192
|
-
let consoleMock1: jest.SpyInstance
|
|
193
|
-
beforeAll(() => {
|
|
194
|
-
consoleMock1 = jest.spyOn(console, "error").mockImplementation(() => void 0)
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
afterAll(() => {
|
|
198
|
-
consoleMock1.mockRestore()
|
|
199
|
-
})
|
|
200
|
-
|
|
201
|
-
test("should throw for bad input", async () => {
|
|
202
|
-
await expect(
|
|
203
|
-
Scaffold({
|
|
204
|
-
name: "app_name",
|
|
205
|
-
output: "output",
|
|
206
|
-
templates: ["non-existing-input"],
|
|
207
|
-
data: { value: "1" },
|
|
208
|
-
verbose: 0,
|
|
209
|
-
}),
|
|
210
|
-
).rejects.toThrow()
|
|
211
|
-
|
|
212
|
-
await expect(
|
|
213
|
-
Scaffold({
|
|
214
|
-
name: "app_name",
|
|
215
|
-
output: "output",
|
|
216
|
-
templates: ["non-existing-input/non-existing-file.txt"],
|
|
217
|
-
data: { value: "1" },
|
|
218
|
-
verbose: 0,
|
|
219
|
-
}),
|
|
220
|
-
).rejects.toThrow()
|
|
221
|
-
|
|
222
|
-
expect(() => readFileSync(join(process.cwd(), "output", "app_name.txt"))).toThrow()
|
|
223
|
-
})
|
|
224
|
-
}),
|
|
225
|
-
)
|
|
226
|
-
|
|
227
|
-
describe(
|
|
228
|
-
"dry run",
|
|
229
|
-
withMock(fileStructNormal, () => {
|
|
230
|
-
let consoleMock1: jest.SpyInstance
|
|
231
|
-
beforeAll(() => {
|
|
232
|
-
consoleMock1 = jest.spyOn(console, "error").mockImplementation(() => void 0)
|
|
233
|
-
})
|
|
234
|
-
|
|
235
|
-
afterAll(() => {
|
|
236
|
-
consoleMock1.mockRestore()
|
|
237
|
-
})
|
|
238
|
-
|
|
239
|
-
test("should not write to disk", async () => {
|
|
240
|
-
Scaffold({
|
|
241
|
-
name: "app_name",
|
|
242
|
-
output: "output",
|
|
243
|
-
templates: ["input"],
|
|
244
|
-
data: { value: "1" },
|
|
245
|
-
verbose: 0,
|
|
246
|
-
dryRun: true,
|
|
247
|
-
})
|
|
248
|
-
|
|
249
|
-
expect(() => readFileSync(join(process.cwd(), "output", "app_name.txt"))).toThrow()
|
|
250
|
-
})
|
|
251
|
-
}),
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
describe(
|
|
255
|
-
"outputPath override",
|
|
256
|
-
withMock(fileStructNormal, () => {
|
|
257
|
-
test("should allow override function", async () => {
|
|
258
|
-
await Scaffold({
|
|
259
|
-
name: "app_name",
|
|
260
|
-
output: (fullPath, basedir, basename) => join("custom-output", `${basename.split(".")[0]}`),
|
|
261
|
-
templates: ["input"],
|
|
262
|
-
data: { value: "1" },
|
|
263
|
-
verbose: 0,
|
|
264
|
-
})
|
|
265
|
-
const data = readFileSync(join(process.cwd(), "/custom-output/app_name/app_name.txt"))
|
|
266
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
267
|
-
})
|
|
268
|
-
}),
|
|
269
|
-
)
|
|
270
|
-
|
|
271
|
-
describe(
|
|
272
|
-
"output structure",
|
|
273
|
-
withMock(fileStructNested, () => {
|
|
274
|
-
test("should maintain input structure on output", async () => {
|
|
275
|
-
await Scaffold({
|
|
276
|
-
name: "app_name",
|
|
277
|
-
output: "output",
|
|
278
|
-
templates: ["input"],
|
|
279
|
-
data: { value: "1" },
|
|
280
|
-
verbose: 0,
|
|
281
|
-
})
|
|
282
|
-
|
|
283
|
-
const rootDir = readdirSync(join(process.cwd(), "output"))
|
|
284
|
-
const dir = readdirSync(join(process.cwd(), "output", "AppName"))
|
|
285
|
-
const nestedDir = readdirSync(join(process.cwd(), "output", "AppName", "moreNesting"))
|
|
286
|
-
expect(rootDir).toHaveProperty("length")
|
|
287
|
-
expect(dir).toHaveProperty("length")
|
|
288
|
-
expect(nestedDir).toHaveProperty("length")
|
|
289
|
-
|
|
290
|
-
const rootFile = readFileSync(join(process.cwd(), "output", "app_name-1.txt"))
|
|
291
|
-
const oneDeepFile = readFileSync(join(process.cwd(), "output", "AppName/app_name-2.txt"))
|
|
292
|
-
const twoDeepFile = readFileSync(join(process.cwd(), "output", "AppName/moreNesting/app_name-3.txt"))
|
|
293
|
-
expect(rootFile.toString()).toEqual("This should be in root")
|
|
294
|
-
expect(oneDeepFile.toString()).toEqual("Hello, my value is 1")
|
|
295
|
-
expect(twoDeepFile.toString()).toEqual("Hi! My value is actually NOT 1!")
|
|
296
|
-
})
|
|
297
|
-
}),
|
|
298
|
-
)
|
|
299
|
-
|
|
300
|
-
describe(
|
|
301
|
-
"capitalization helpers",
|
|
302
|
-
withMock(fileStructHelpers, () => {
|
|
303
|
-
const _helpers: Record<string, (text: string) => string> = {
|
|
304
|
-
add1: (text) => text + " 1",
|
|
305
|
-
}
|
|
306
|
-
|
|
307
|
-
test("should work", async () => {
|
|
308
|
-
await Scaffold({
|
|
309
|
-
name: "app_name",
|
|
310
|
-
output: "output",
|
|
311
|
-
templates: ["input"],
|
|
312
|
-
verbose: 0,
|
|
313
|
-
helpers: _helpers,
|
|
314
|
-
})
|
|
315
|
-
|
|
316
|
-
const results = {
|
|
317
|
-
camelCase: "appName",
|
|
318
|
-
snakeCase: "app_name",
|
|
319
|
-
startCase: "App Name",
|
|
320
|
-
kebabCase: "app-name",
|
|
321
|
-
hyphenCase: "app-name",
|
|
322
|
-
pascalCase: "AppName",
|
|
323
|
-
lowerCase: "app_name",
|
|
324
|
-
upperCase: "APP_NAME",
|
|
325
|
-
}
|
|
326
|
-
for (const key in results) {
|
|
327
|
-
const file = readFileSync(join(process.cwd(), "output", "defaults", `${key}.txt`))
|
|
328
|
-
expect(file.toString()).toEqual(results[key as keyof typeof results])
|
|
329
|
-
}
|
|
330
|
-
})
|
|
331
|
-
}),
|
|
332
|
-
)
|
|
333
|
-
describe(
|
|
334
|
-
"date helpers",
|
|
335
|
-
withMock(fileStructDates, () => {
|
|
336
|
-
test("should work", async () => {
|
|
337
|
-
const now = new Date()
|
|
338
|
-
const yesterday = dateFns.add(new Date(), { days: -1 })
|
|
339
|
-
const customDate = dateFns.formatISO(dateFns.add(new Date(), { days: -1 }))
|
|
340
|
-
|
|
341
|
-
await Scaffold({
|
|
342
|
-
name: "app_name",
|
|
343
|
-
output: "output",
|
|
344
|
-
templates: ["input"],
|
|
345
|
-
verbose: 0,
|
|
346
|
-
data: { customDate },
|
|
347
|
-
})
|
|
348
|
-
|
|
349
|
-
const nowFile = readFileSync(join(process.cwd(), "output", "now.txt"))
|
|
350
|
-
const offsetFile = readFileSync(join(process.cwd(), "output", "offset.txt"))
|
|
351
|
-
const customFile = readFileSync(join(process.cwd(), "output", "custom.txt"))
|
|
352
|
-
|
|
353
|
-
// "now.txt": "Today is {{ now 'mmm' }}, time is {{ now 'HH:mm' }}",
|
|
354
|
-
// "offset.txt": "Yesterday was {{ now 'mmm' -1 'days' }}, time is {{ now 'HH:mm' -1 'days' }}",
|
|
355
|
-
// "custom.txt": "Custom date is {{ date customDate 'mmm' }}, time is {{ date customDate 'HH:mm' }}",
|
|
356
|
-
|
|
357
|
-
expect(nowFile.toString()).toEqual(
|
|
358
|
-
`Today is ${dateFns.format(now, "mmm")}, time is ${dateFns.format(now, "HH:mm")}`,
|
|
359
|
-
)
|
|
360
|
-
expect(offsetFile.toString()).toEqual(
|
|
361
|
-
`Yesterday was ${dateFns.format(yesterday, "mmm")}, time is ${dateFns.format(yesterday, "HH:mm")}`,
|
|
362
|
-
)
|
|
363
|
-
expect(customFile.toString()).toEqual(
|
|
364
|
-
`Custom date is ${dateFns.format(dateFns.parseISO(customDate), "mmm")}, time is ${dateFns.format(
|
|
365
|
-
dateFns.parseISO(customDate),
|
|
366
|
-
"HH:mm",
|
|
367
|
-
)}`,
|
|
368
|
-
)
|
|
369
|
-
})
|
|
370
|
-
}),
|
|
371
|
-
)
|
|
372
|
-
describe(
|
|
373
|
-
"custom helpers",
|
|
374
|
-
withMock(fileStructHelpers, () => {
|
|
375
|
-
const _helpers: Record<string, (text: string) => string> = {
|
|
376
|
-
add1: (text) => text + " 1",
|
|
377
|
-
}
|
|
378
|
-
test("should work", async () => {
|
|
379
|
-
await Scaffold({
|
|
380
|
-
name: "app_name",
|
|
381
|
-
output: "output",
|
|
382
|
-
templates: ["input"],
|
|
383
|
-
verbose: 0,
|
|
384
|
-
helpers: _helpers,
|
|
385
|
-
})
|
|
386
|
-
|
|
387
|
-
const results = {
|
|
388
|
-
add1: "app_name 1",
|
|
389
|
-
}
|
|
390
|
-
for (const key in results) {
|
|
391
|
-
const file = readFileSync(join(process.cwd(), "output", "custom", `${key}.txt`))
|
|
392
|
-
expect(file.toString()).toEqual(results[key as keyof typeof results])
|
|
393
|
-
}
|
|
394
|
-
})
|
|
395
|
-
}),
|
|
396
|
-
)
|
|
397
|
-
describe(
|
|
398
|
-
"transform subfolder",
|
|
399
|
-
withMock(fileStructSubdirTransformer, () => {
|
|
400
|
-
test("should work with no helper", async () => {
|
|
401
|
-
await Scaffold({
|
|
402
|
-
name: "app_name",
|
|
403
|
-
output: "output",
|
|
404
|
-
templates: ["input"],
|
|
405
|
-
createSubFolder: true,
|
|
406
|
-
verbose: 0,
|
|
407
|
-
})
|
|
408
|
-
|
|
409
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name", "app_name.txt"))
|
|
410
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
411
|
-
})
|
|
412
|
-
|
|
413
|
-
test("should work with default helper", async () => {
|
|
414
|
-
await Scaffold({
|
|
415
|
-
name: "app_name",
|
|
416
|
-
output: "output",
|
|
417
|
-
templates: ["input"],
|
|
418
|
-
createSubFolder: true,
|
|
419
|
-
verbose: 0,
|
|
420
|
-
subFolderNameHelper: "upperCase",
|
|
421
|
-
})
|
|
422
|
-
|
|
423
|
-
const data = readFileSync(join(process.cwd(), "output", "APP_NAME", "app_name.txt"))
|
|
424
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
425
|
-
})
|
|
426
|
-
|
|
427
|
-
test("should work with custom helper", async () => {
|
|
428
|
-
await Scaffold({
|
|
429
|
-
name: "app_name",
|
|
430
|
-
output: "output",
|
|
431
|
-
templates: ["input"],
|
|
432
|
-
createSubFolder: true,
|
|
433
|
-
verbose: 0,
|
|
434
|
-
subFolderNameHelper: "test",
|
|
435
|
-
helpers: {
|
|
436
|
-
test: () => "REPLACED",
|
|
437
|
-
},
|
|
438
|
-
})
|
|
439
|
-
|
|
440
|
-
const data = readFileSync(join(process.cwd(), "output", "REPLACED", "app_name.txt"))
|
|
441
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
442
|
-
})
|
|
443
|
-
}),
|
|
444
|
-
)
|
|
445
|
-
describe(
|
|
446
|
-
"before write",
|
|
447
|
-
withMock(fileStructNormal, () => {
|
|
448
|
-
test("should work with no callback", async () => {
|
|
449
|
-
await Scaffold({
|
|
450
|
-
name: "app_name",
|
|
451
|
-
output: "output",
|
|
452
|
-
templates: ["input"],
|
|
453
|
-
verbose: 0,
|
|
454
|
-
data: {
|
|
455
|
-
value: "value",
|
|
456
|
-
},
|
|
457
|
-
})
|
|
458
|
-
|
|
459
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
460
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
461
|
-
})
|
|
462
|
-
|
|
463
|
-
test("should work with custom callback", async () => {
|
|
464
|
-
await Scaffold({
|
|
465
|
-
name: "app_name",
|
|
466
|
-
output: "output",
|
|
467
|
-
templates: ["input"],
|
|
468
|
-
verbose: 0,
|
|
469
|
-
data: {
|
|
470
|
-
value: "value",
|
|
471
|
-
},
|
|
472
|
-
beforeWrite: (content, beforeContent, outputPath) =>
|
|
473
|
-
[content.toString().toUpperCase(), beforeContent, outputPath].join(", "),
|
|
474
|
-
})
|
|
475
|
-
|
|
476
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
477
|
-
expect(data.toString()).toEqual(
|
|
478
|
-
[
|
|
479
|
-
"Hello, my app is app_name".toUpperCase(),
|
|
480
|
-
fileStructNormal.input["{{name}}.txt"],
|
|
481
|
-
join(process.cwd(), "output", "app_name.txt"),
|
|
482
|
-
].join(", "),
|
|
483
|
-
)
|
|
484
|
-
})
|
|
485
|
-
test("should work with undefined response custom callback", async () => {
|
|
486
|
-
await Scaffold({
|
|
487
|
-
name: "app_name",
|
|
488
|
-
output: "output",
|
|
489
|
-
templates: ["input"],
|
|
490
|
-
verbose: 0,
|
|
491
|
-
data: {
|
|
492
|
-
value: "value",
|
|
493
|
-
},
|
|
494
|
-
beforeWrite: () => undefined,
|
|
495
|
-
})
|
|
496
|
-
|
|
497
|
-
const data = readFileSync(join(process.cwd(), "output", "app_name.txt"))
|
|
498
|
-
expect(data.toString()).toEqual("Hello, my app is app_name")
|
|
499
|
-
})
|
|
500
|
-
}),
|
|
501
|
-
)
|
|
502
|
-
})
|
package/tests/utils.test.ts
DELETED
|
@@ -1,124 +0,0 @@
|
|
|
1
|
-
import { dateHelper, handlebarsParse, nowHelper, parseAppendData } from "../src/utils"
|
|
2
|
-
import { ScaffoldCmdConfig, ScaffoldConfig } from "../src/types"
|
|
3
|
-
import path from "path"
|
|
4
|
-
import * as dateFns from "date-fns"
|
|
5
|
-
import { OptionsBase } from "massarg/types"
|
|
6
|
-
|
|
7
|
-
const blankConf: ScaffoldConfig = {
|
|
8
|
-
verbose: 0,
|
|
9
|
-
name: "",
|
|
10
|
-
output: "",
|
|
11
|
-
templates: [],
|
|
12
|
-
data: { name: "test" },
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
const blankCliConf: ScaffoldCmdConfig & OptionsBase = {
|
|
16
|
-
verbose: 0,
|
|
17
|
-
name: "",
|
|
18
|
-
output: "",
|
|
19
|
-
templates: [],
|
|
20
|
-
data: { name: "test" },
|
|
21
|
-
overwrite: false,
|
|
22
|
-
createSubFolder: false,
|
|
23
|
-
dryRun: false,
|
|
24
|
-
quiet: false,
|
|
25
|
-
extras: [],
|
|
26
|
-
help: false,
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
describe("Utils", () => {
|
|
30
|
-
describe("handlebarsParse", () => {
|
|
31
|
-
let origSep: any
|
|
32
|
-
describe("windows paths", () => {
|
|
33
|
-
beforeAll(() => {
|
|
34
|
-
origSep = path.sep
|
|
35
|
-
Object.defineProperty(path, "sep", { value: "\\" })
|
|
36
|
-
})
|
|
37
|
-
afterAll(() => {
|
|
38
|
-
Object.defineProperty(path, "sep", { value: origSep })
|
|
39
|
-
})
|
|
40
|
-
test("should work for windows paths", async () => {
|
|
41
|
-
expect(handlebarsParse(blankConf, "C:\\exports\\{{name}}.txt", { isPath: true })).toEqual(
|
|
42
|
-
Buffer.from("C:\\exports\\test.txt"),
|
|
43
|
-
)
|
|
44
|
-
})
|
|
45
|
-
})
|
|
46
|
-
describe("non-windows paths", () => {
|
|
47
|
-
beforeAll(() => {
|
|
48
|
-
origSep = path.sep
|
|
49
|
-
Object.defineProperty(path, "sep", { value: "/" })
|
|
50
|
-
})
|
|
51
|
-
afterAll(() => {
|
|
52
|
-
Object.defineProperty(path, "sep", { value: origSep })
|
|
53
|
-
})
|
|
54
|
-
test("should work for non-windows paths", async () => {
|
|
55
|
-
expect(handlebarsParse(blankConf, "/home/test/{{name}}.txt", { isPath: true })).toEqual(
|
|
56
|
-
Buffer.from("/home/test/test.txt"),
|
|
57
|
-
)
|
|
58
|
-
})
|
|
59
|
-
})
|
|
60
|
-
test("should not do path escaping on non-path compiles", async () => {
|
|
61
|
-
expect(
|
|
62
|
-
handlebarsParse(
|
|
63
|
-
{ ...blankConf, data: { ...blankConf.data, escaped: "value" } },
|
|
64
|
-
"/home/test/{{name}} \\{{escaped}}.txt",
|
|
65
|
-
{
|
|
66
|
-
isPath: false,
|
|
67
|
-
},
|
|
68
|
-
),
|
|
69
|
-
).toEqual(Buffer.from("/home/test/test {{escaped}}.txt"))
|
|
70
|
-
})
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
describe("Helpers", () => {
|
|
74
|
-
describe("date helpers", () => {
|
|
75
|
-
describe("now", () => {
|
|
76
|
-
test("should work without extra params", () => {
|
|
77
|
-
const now = new Date()
|
|
78
|
-
const fmt = "yyyy-MM-dd HH:mm"
|
|
79
|
-
|
|
80
|
-
expect(nowHelper(fmt)).toEqual(dateFns.format(now, fmt))
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
|
|
84
|
-
describe("date", () => {
|
|
85
|
-
test("should work with no offset params", () => {
|
|
86
|
-
const now = new Date()
|
|
87
|
-
const fmt = "yyyy-MM-dd HH:mm"
|
|
88
|
-
|
|
89
|
-
expect(dateHelper(now.toISOString(), fmt)).toEqual(dateFns.format(now, fmt))
|
|
90
|
-
})
|
|
91
|
-
|
|
92
|
-
test("should work with offset params", () => {
|
|
93
|
-
const now = new Date()
|
|
94
|
-
const fmt = "yyyy-MM-dd HH:mm"
|
|
95
|
-
|
|
96
|
-
expect(dateHelper(now.toISOString(), fmt, -1, "days")).toEqual(
|
|
97
|
-
dateFns.format(dateFns.add(now, { days: -1 }), fmt),
|
|
98
|
-
)
|
|
99
|
-
expect(dateHelper(now.toISOString(), fmt, 1, "months")).toEqual(
|
|
100
|
-
dateFns.format(dateFns.add(now, { months: 1 }), fmt),
|
|
101
|
-
)
|
|
102
|
-
})
|
|
103
|
-
})
|
|
104
|
-
})
|
|
105
|
-
})
|
|
106
|
-
|
|
107
|
-
describe("parseAppendData", () => {
|
|
108
|
-
test('works for "key=value"', () => {
|
|
109
|
-
expect(parseAppendData("key=value", blankCliConf)).toEqual({ key: "value", name: "test" })
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
test('works for "key:=value"', () => {
|
|
113
|
-
expect(parseAppendData("key:=123", blankCliConf)).toEqual({ key: 123, name: "test" })
|
|
114
|
-
})
|
|
115
|
-
|
|
116
|
-
test("overwrites existing value", () => {
|
|
117
|
-
expect(parseAppendData("name:=123", blankCliConf)).toEqual({ name: 123 })
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
test("works with quotes", () => {
|
|
121
|
-
expect(parseAppendData('key="value test"', blankCliConf)).toEqual({ key: "value test", name: "test" })
|
|
122
|
-
})
|
|
123
|
-
})
|
|
124
|
-
})
|
package/tsconfig.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2019",
|
|
4
|
-
"module": "commonjs",
|
|
5
|
-
"moduleResolution": "node",
|
|
6
|
-
"esModuleInterop": true,
|
|
7
|
-
"lib": ["ES2019"],
|
|
8
|
-
"declaration": true,
|
|
9
|
-
"outDir": "dist",
|
|
10
|
-
"strict": true,
|
|
11
|
-
"sourceMap": true,
|
|
12
|
-
"removeComments": false
|
|
13
|
-
},
|
|
14
|
-
"include": ["src/index.ts", "src/cmd.ts"],
|
|
15
|
-
"exclude": ["tests/*"]
|
|
16
|
-
}
|
package/typedoc.config.js
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
const path = require("path")
|
|
2
|
-
|
|
3
|
-
/** @type {import('typedoc').TypeDocOptions} */
|
|
4
|
-
module.exports = {
|
|
5
|
-
name: "Simple Scaffold",
|
|
6
|
-
entryPoints: ["src/index.ts"],
|
|
7
|
-
includeVersion: true,
|
|
8
|
-
categorizeByGroup: false,
|
|
9
|
-
sort: ["visibility"],
|
|
10
|
-
categoryOrder: ["Main", "*"],
|
|
11
|
-
media: "media",
|
|
12
|
-
githubPages: true,
|
|
13
|
-
entryPointStrategy: "expand",
|
|
14
|
-
out: "docs",
|
|
15
|
-
excludePrivate: true,
|
|
16
|
-
excludeProtected: true,
|
|
17
|
-
excludeInternal: true,
|
|
18
|
-
gaID: "GTM-KHQS9TQ",
|
|
19
|
-
validation: {
|
|
20
|
-
invalidLink: true,
|
|
21
|
-
},
|
|
22
|
-
plugin: ["@knodes/typedoc-plugin-pages"],
|
|
23
|
-
customCss: "src/docs.css",
|
|
24
|
-
options: "typedoc.config.js",
|
|
25
|
-
logLevel: "Verbose",
|
|
26
|
-
pluginPages: {
|
|
27
|
-
logLevel: "Verbose",
|
|
28
|
-
pages: [
|
|
29
|
-
{
|
|
30
|
-
name: "Configuration",
|
|
31
|
-
source: "README.md",
|
|
32
|
-
childrenDir: path.join(process.cwd(), "pages"),
|
|
33
|
-
childrenOutputDir: "./",
|
|
34
|
-
children: [
|
|
35
|
-
{
|
|
36
|
-
name: "CLI usage",
|
|
37
|
-
source: "cli.md",
|
|
38
|
-
},
|
|
39
|
-
{
|
|
40
|
-
name: "Node.js usage",
|
|
41
|
-
source: "node.md",
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
name: "Templates",
|
|
45
|
-
source: "templates.md",
|
|
46
|
-
},
|
|
47
|
-
{
|
|
48
|
-
name: "Configuration Files",
|
|
49
|
-
source: "configuration_files.md",
|
|
50
|
-
},
|
|
51
|
-
{
|
|
52
|
-
name: "Migrating v0.x to v1.x",
|
|
53
|
-
source: "migration.md",
|
|
54
|
-
},
|
|
55
|
-
],
|
|
56
|
-
},
|
|
57
|
-
{
|
|
58
|
-
name: "Changelog",
|
|
59
|
-
source: "./CHANGELOG.md",
|
|
60
|
-
},
|
|
61
|
-
],
|
|
62
|
-
},
|
|
63
|
-
}
|