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/src/utils.ts
DELETED
|
@@ -1,423 +0,0 @@
|
|
|
1
|
-
import path from "path"
|
|
2
|
-
import { F_OK } from "constants"
|
|
3
|
-
import {
|
|
4
|
-
DefaultHelpers,
|
|
5
|
-
FileResponse,
|
|
6
|
-
FileResponseHandler,
|
|
7
|
-
Helper,
|
|
8
|
-
LogLevel,
|
|
9
|
-
ScaffoldCmdConfig,
|
|
10
|
-
ScaffoldConfig,
|
|
11
|
-
ScaffoldConfigFile,
|
|
12
|
-
} from "./types"
|
|
13
|
-
import camelCase from "lodash/camelCase"
|
|
14
|
-
import snakeCase from "lodash/snakeCase"
|
|
15
|
-
import kebabCase from "lodash/kebabCase"
|
|
16
|
-
import startCase from "lodash/startCase"
|
|
17
|
-
import Handlebars from "handlebars"
|
|
18
|
-
import { promises as fsPromises } from "fs"
|
|
19
|
-
import chalk from "chalk"
|
|
20
|
-
const { stat, access, mkdir } = fsPromises
|
|
21
|
-
import dtAdd from "date-fns/add"
|
|
22
|
-
import dtFormat from "date-fns/format"
|
|
23
|
-
import dtParseISO from "date-fns/parseISO"
|
|
24
|
-
import { glob, hasMagic } from "glob"
|
|
25
|
-
import { OptionsBase } from "massarg/types"
|
|
26
|
-
|
|
27
|
-
const dateFns = {
|
|
28
|
-
add: dtAdd,
|
|
29
|
-
format: dtFormat,
|
|
30
|
-
parseISO: dtParseISO,
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const { readFile, writeFile } = fsPromises
|
|
34
|
-
|
|
35
|
-
export const defaultHelpers: Record<DefaultHelpers, Helper> = {
|
|
36
|
-
camelCase,
|
|
37
|
-
snakeCase,
|
|
38
|
-
startCase,
|
|
39
|
-
kebabCase,
|
|
40
|
-
hyphenCase: kebabCase,
|
|
41
|
-
pascalCase,
|
|
42
|
-
lowerCase: (text) => text.toLowerCase(),
|
|
43
|
-
upperCase: (text) => text.toUpperCase(),
|
|
44
|
-
now: nowHelper,
|
|
45
|
-
date: dateHelper,
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export function _dateHelper(date: Date, formatString: string): string
|
|
49
|
-
export function _dateHelper(
|
|
50
|
-
date: Date,
|
|
51
|
-
formatString: string,
|
|
52
|
-
durationDifference: number,
|
|
53
|
-
durationType: keyof Duration,
|
|
54
|
-
): string
|
|
55
|
-
export function _dateHelper(
|
|
56
|
-
date: Date,
|
|
57
|
-
formatString: string,
|
|
58
|
-
durationDifference?: number,
|
|
59
|
-
durationType?: keyof Duration,
|
|
60
|
-
): string {
|
|
61
|
-
if (durationType && durationDifference !== undefined) {
|
|
62
|
-
return dateFns.format(dateFns.add(date, { [durationType]: durationDifference }), formatString)
|
|
63
|
-
}
|
|
64
|
-
return dateFns.format(date, formatString)
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
export function nowHelper(formatString: string): string
|
|
68
|
-
export function nowHelper(formatString: string, durationDifference: number, durationType: keyof Duration): string
|
|
69
|
-
export function nowHelper(formatString: string, durationDifference?: number, durationType?: keyof Duration): string {
|
|
70
|
-
return _dateHelper(new Date(), formatString, durationDifference!, durationType!)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
export function dateHelper(date: string, formatString: string): string
|
|
74
|
-
export function dateHelper(
|
|
75
|
-
date: string,
|
|
76
|
-
formatString: string,
|
|
77
|
-
durationDifference: number,
|
|
78
|
-
durationType: keyof Duration,
|
|
79
|
-
): string
|
|
80
|
-
|
|
81
|
-
export function dateHelper(
|
|
82
|
-
date: string,
|
|
83
|
-
formatString: string,
|
|
84
|
-
durationDifference?: number,
|
|
85
|
-
durationType?: keyof Duration,
|
|
86
|
-
): string {
|
|
87
|
-
return _dateHelper(dateFns.parseISO(date), formatString, durationDifference!, durationType!)
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
export function registerHelpers(config: ScaffoldConfig): void {
|
|
91
|
-
const _helpers = { ...defaultHelpers, ...config.helpers }
|
|
92
|
-
for (const helperName in _helpers) {
|
|
93
|
-
log(config, LogLevel.Debug, `Registering helper: ${helperName}`)
|
|
94
|
-
Handlebars.registerHelper(helperName, _helpers[helperName as keyof typeof _helpers])
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
export function handleErr(err: NodeJS.ErrnoException | null): void {
|
|
99
|
-
if (err) throw err
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
export function log(config: ScaffoldConfig, level: LogLevel, ...obj: any[]): void {
|
|
103
|
-
if (config.quiet || config.verbose === LogLevel.None || level < (config.verbose ?? LogLevel.Info)) {
|
|
104
|
-
return
|
|
105
|
-
}
|
|
106
|
-
const levelColor: Record<LogLevel, keyof typeof chalk> = {
|
|
107
|
-
[LogLevel.None]: "reset",
|
|
108
|
-
[LogLevel.Debug]: "blue",
|
|
109
|
-
[LogLevel.Info]: "dim",
|
|
110
|
-
[LogLevel.Warning]: "yellow",
|
|
111
|
-
[LogLevel.Error]: "red",
|
|
112
|
-
}
|
|
113
|
-
const chalkFn: any = chalk[levelColor[level]]
|
|
114
|
-
const key: "log" | "warn" | "error" = level === LogLevel.Error ? "error" : level === LogLevel.Warning ? "warn" : "log"
|
|
115
|
-
const logFn: any = console[key]
|
|
116
|
-
logFn(
|
|
117
|
-
...obj.map((i) =>
|
|
118
|
-
i instanceof Error
|
|
119
|
-
? chalkFn(i, JSON.stringify(i, undefined, 1), i.stack)
|
|
120
|
-
: typeof i === "object"
|
|
121
|
-
? chalkFn(JSON.stringify(i, undefined, 1))
|
|
122
|
-
: chalkFn(i),
|
|
123
|
-
),
|
|
124
|
-
)
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
export async function createDirIfNotExists(dir: string, config: ScaffoldConfig): Promise<void> {
|
|
128
|
-
const parentDir = path.dirname(dir)
|
|
129
|
-
|
|
130
|
-
if (!(await pathExists(parentDir))) {
|
|
131
|
-
await createDirIfNotExists(parentDir, config)
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (!(await pathExists(dir))) {
|
|
135
|
-
try {
|
|
136
|
-
log(config, LogLevel.Debug, `Creating dir ${dir}`)
|
|
137
|
-
await mkdir(dir)
|
|
138
|
-
return
|
|
139
|
-
} catch (e: any) {
|
|
140
|
-
if (e.code !== "EEXIST") {
|
|
141
|
-
throw e
|
|
142
|
-
}
|
|
143
|
-
return
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
export function getOptionValueForFile<T>(
|
|
149
|
-
config: ScaffoldConfig,
|
|
150
|
-
filePath: string,
|
|
151
|
-
fn: FileResponse<T>,
|
|
152
|
-
defaultValue?: T,
|
|
153
|
-
): T {
|
|
154
|
-
if (typeof fn !== "function") {
|
|
155
|
-
return defaultValue ?? (fn as T)
|
|
156
|
-
}
|
|
157
|
-
return (fn as FileResponseHandler<T>)(
|
|
158
|
-
filePath,
|
|
159
|
-
path.dirname(handlebarsParse(config, filePath, { isPath: true }).toString()),
|
|
160
|
-
path.basename(handlebarsParse(config, filePath, { isPath: true }).toString()),
|
|
161
|
-
)
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
export function handlebarsParse(
|
|
165
|
-
config: ScaffoldConfig,
|
|
166
|
-
templateBuffer: Buffer | string,
|
|
167
|
-
{ isPath = false }: { isPath?: boolean } = {},
|
|
168
|
-
): Buffer {
|
|
169
|
-
const { data } = config
|
|
170
|
-
try {
|
|
171
|
-
let str = templateBuffer.toString()
|
|
172
|
-
if (isPath) {
|
|
173
|
-
str = str.replace(/\\/g, "/")
|
|
174
|
-
}
|
|
175
|
-
const parser = Handlebars.compile(str, { noEscape: true })
|
|
176
|
-
let outputContents = parser(data)
|
|
177
|
-
if (isPath && path.sep !== "/") {
|
|
178
|
-
outputContents = outputContents.replace(/\//g, "\\")
|
|
179
|
-
}
|
|
180
|
-
return Buffer.from(outputContents)
|
|
181
|
-
} catch (e) {
|
|
182
|
-
log(config, LogLevel.Debug, e)
|
|
183
|
-
log(config, LogLevel.Warning, "Couldn't parse file with handlebars, returning original content")
|
|
184
|
-
return Buffer.from(templateBuffer)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
export async function pathExists(filePath: string): Promise<boolean> {
|
|
189
|
-
try {
|
|
190
|
-
await access(filePath, F_OK)
|
|
191
|
-
return true
|
|
192
|
-
} catch (e: any) {
|
|
193
|
-
if (e.code === "ENOENT") {
|
|
194
|
-
return false
|
|
195
|
-
}
|
|
196
|
-
throw e
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
export function pascalCase(s: string): string {
|
|
201
|
-
return startCase(s).replace(/\s+/g, "")
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
export async function isDir(path: string): Promise<boolean> {
|
|
205
|
-
const tplStat = await stat(path)
|
|
206
|
-
return tplStat.isDirectory()
|
|
207
|
-
}
|
|
208
|
-
|
|
209
|
-
export function removeGlob(template: string): string {
|
|
210
|
-
return template.replace(/\*/g, "").replace(/(\/\/|\\\\)/g, path.sep)
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
export function makeRelativePath(str: string): string {
|
|
214
|
-
return str.startsWith(path.sep) ? str.slice(1) : str
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
export function getBasePath(relPath: string): string {
|
|
218
|
-
return path
|
|
219
|
-
.resolve(process.cwd(), relPath)
|
|
220
|
-
.replace(process.cwd() + path.sep, "")
|
|
221
|
-
.replace(process.cwd(), "")
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
export async function getFileList(config: ScaffoldConfig, template: string): Promise<string[]> {
|
|
225
|
-
return (
|
|
226
|
-
await glob(template, {
|
|
227
|
-
dot: true,
|
|
228
|
-
nodir: true,
|
|
229
|
-
// debug: config.verbose === LogLevel.Debug,
|
|
230
|
-
})
|
|
231
|
-
).map((f) => f.replace(/\//g, path.sep))
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export interface GlobInfo {
|
|
235
|
-
nonGlobTemplate: string
|
|
236
|
-
origTemplate: string
|
|
237
|
-
isDirOrGlob: boolean
|
|
238
|
-
isGlob: boolean
|
|
239
|
-
template: string
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
export async function getTemplateGlobInfo(config: ScaffoldConfig, template: string): Promise<GlobInfo> {
|
|
243
|
-
const isGlob = hasMagic(template)
|
|
244
|
-
log(config, LogLevel.Debug, "before isDir", "isGlob:", isGlob, template)
|
|
245
|
-
let _template = template
|
|
246
|
-
let nonGlobTemplate = isGlob ? removeGlob(template) : template
|
|
247
|
-
nonGlobTemplate = path.normalize(nonGlobTemplate)
|
|
248
|
-
const isDirOrGlob = isGlob ? true : await isDir(template)
|
|
249
|
-
log(config, LogLevel.Debug, "after isDir", isDirOrGlob)
|
|
250
|
-
const _shouldAddGlob = !isGlob && isDirOrGlob
|
|
251
|
-
const origTemplate = template
|
|
252
|
-
if (_shouldAddGlob) {
|
|
253
|
-
_template = path.join(template, "**", "*")
|
|
254
|
-
}
|
|
255
|
-
return { nonGlobTemplate, origTemplate, isDirOrGlob, isGlob, template: _template }
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
export interface OutputFileInfo {
|
|
259
|
-
inputPath: string
|
|
260
|
-
outputPathOpt: string
|
|
261
|
-
outputDir: string
|
|
262
|
-
outputPath: string
|
|
263
|
-
exists: boolean
|
|
264
|
-
}
|
|
265
|
-
|
|
266
|
-
export async function getTemplateFileInfo(
|
|
267
|
-
config: ScaffoldConfig,
|
|
268
|
-
{ templatePath, basePath }: { templatePath: string; basePath: string },
|
|
269
|
-
): Promise<OutputFileInfo> {
|
|
270
|
-
const inputPath = path.resolve(process.cwd(), templatePath)
|
|
271
|
-
const outputPathOpt = getOptionValueForFile(config, inputPath, config.output)
|
|
272
|
-
const outputDir = getOutputDir(config, outputPathOpt, basePath)
|
|
273
|
-
const outputPath = handlebarsParse(config, path.join(outputDir, path.basename(inputPath)), {
|
|
274
|
-
isPath: true,
|
|
275
|
-
}).toString()
|
|
276
|
-
const exists = await pathExists(outputPath)
|
|
277
|
-
return { inputPath, outputPathOpt, outputDir, outputPath, exists }
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
export async function copyFileTransformed(
|
|
281
|
-
config: ScaffoldConfig,
|
|
282
|
-
{
|
|
283
|
-
exists,
|
|
284
|
-
overwrite,
|
|
285
|
-
outputPath,
|
|
286
|
-
inputPath,
|
|
287
|
-
}: {
|
|
288
|
-
exists: boolean
|
|
289
|
-
overwrite: boolean
|
|
290
|
-
outputPath: string
|
|
291
|
-
inputPath: string
|
|
292
|
-
},
|
|
293
|
-
): Promise<void> {
|
|
294
|
-
if (!exists || overwrite) {
|
|
295
|
-
if (exists && overwrite) {
|
|
296
|
-
log(config, LogLevel.Info, `File ${outputPath} exists, overwriting`)
|
|
297
|
-
}
|
|
298
|
-
const templateBuffer = await readFile(inputPath)
|
|
299
|
-
const unprocessedOutputContents = handlebarsParse(config, templateBuffer)
|
|
300
|
-
const finalOutputContents =
|
|
301
|
-
(await config.beforeWrite?.(unprocessedOutputContents, templateBuffer, outputPath)) ?? unprocessedOutputContents
|
|
302
|
-
|
|
303
|
-
if (!config.dryRun) {
|
|
304
|
-
await writeFile(outputPath, finalOutputContents)
|
|
305
|
-
log(config, LogLevel.Info, "Done.")
|
|
306
|
-
} else {
|
|
307
|
-
log(config, LogLevel.Info, "Content output:")
|
|
308
|
-
log(config, LogLevel.Info, finalOutputContents)
|
|
309
|
-
}
|
|
310
|
-
} else if (exists) {
|
|
311
|
-
log(config, LogLevel.Info, `File ${outputPath} already exists, skipping`)
|
|
312
|
-
}
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
export function getOutputDir(config: ScaffoldConfig, outputPathOpt: string, basePath: string): string {
|
|
316
|
-
return path.resolve(
|
|
317
|
-
process.cwd(),
|
|
318
|
-
...([
|
|
319
|
-
outputPathOpt,
|
|
320
|
-
basePath,
|
|
321
|
-
config.createSubFolder
|
|
322
|
-
? config.subFolderNameHelper
|
|
323
|
-
? handlebarsParse(config, `{{ ${config.subFolderNameHelper} name }}`).toString()
|
|
324
|
-
: config.name
|
|
325
|
-
: undefined,
|
|
326
|
-
].filter(Boolean) as string[]),
|
|
327
|
-
)
|
|
328
|
-
}
|
|
329
|
-
|
|
330
|
-
export function logInputFile(
|
|
331
|
-
config: ScaffoldConfig,
|
|
332
|
-
{
|
|
333
|
-
origTemplate,
|
|
334
|
-
relPath,
|
|
335
|
-
template,
|
|
336
|
-
inputFilePath,
|
|
337
|
-
nonGlobTemplate,
|
|
338
|
-
basePath,
|
|
339
|
-
isDirOrGlob,
|
|
340
|
-
isGlob,
|
|
341
|
-
}: {
|
|
342
|
-
origTemplate: string
|
|
343
|
-
relPath: string
|
|
344
|
-
template: string
|
|
345
|
-
inputFilePath: string
|
|
346
|
-
nonGlobTemplate: string
|
|
347
|
-
basePath: string
|
|
348
|
-
isDirOrGlob: boolean
|
|
349
|
-
isGlob: boolean
|
|
350
|
-
},
|
|
351
|
-
): void {
|
|
352
|
-
log(
|
|
353
|
-
config,
|
|
354
|
-
LogLevel.Debug,
|
|
355
|
-
`\nprocess.cwd(): ${process.cwd()}`,
|
|
356
|
-
`\norigTemplate: ${origTemplate}`,
|
|
357
|
-
`\nrelPath: ${relPath}`,
|
|
358
|
-
`\ntemplate: ${template}`,
|
|
359
|
-
`\ninputFilePath: ${inputFilePath}`,
|
|
360
|
-
`\nnonGlobTemplate: ${nonGlobTemplate}`,
|
|
361
|
-
`\nbasePath: ${basePath}`,
|
|
362
|
-
`\nisDirOrGlob: ${isDirOrGlob}`,
|
|
363
|
-
`\nisGlob: ${isGlob}`,
|
|
364
|
-
`\n`,
|
|
365
|
-
)
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
export function logInitStep(config: ScaffoldConfig): void {
|
|
369
|
-
log(config, LogLevel.Debug, "Full config:", {
|
|
370
|
-
name: config.name,
|
|
371
|
-
templates: config.templates,
|
|
372
|
-
output: config.output,
|
|
373
|
-
createSubfolder: config.createSubFolder,
|
|
374
|
-
data: config.data,
|
|
375
|
-
overwrite: config.overwrite,
|
|
376
|
-
quiet: config.quiet,
|
|
377
|
-
subFolderTransformHelper: config.subFolderNameHelper,
|
|
378
|
-
helpers: Object.keys(config.helpers ?? {}),
|
|
379
|
-
verbose: `${config.verbose} (${Object.keys(LogLevel).find(
|
|
380
|
-
(k) => (LogLevel[k as any] as unknown as number) === config.verbose!,
|
|
381
|
-
)})`,
|
|
382
|
-
})
|
|
383
|
-
log(config, LogLevel.Info, "Data:", config.data)
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
export function parseAppendData(value: string, options: ScaffoldCmdConfig & OptionsBase): unknown {
|
|
387
|
-
const data = options.data ?? {}
|
|
388
|
-
const [key, val] = value.split(/\:?=/)
|
|
389
|
-
// raw
|
|
390
|
-
if (value.includes(":=") && !val.includes(":=")) {
|
|
391
|
-
return { ...data, [key]: JSON.parse(val) }
|
|
392
|
-
}
|
|
393
|
-
return { ...data, [key]: isWrappedWithQuotes(val) ? val.substring(1, val.length - 1) : val }
|
|
394
|
-
}
|
|
395
|
-
|
|
396
|
-
function isWrappedWithQuotes(string: string): boolean {
|
|
397
|
-
return (string.startsWith('"') && string.endsWith('"')) || (string.startsWith("'") && string.endsWith("'"))
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
/** @internal */
|
|
401
|
-
export function parseConfig(config: ScaffoldCmdConfig & OptionsBase): ScaffoldConfig {
|
|
402
|
-
let c: ScaffoldConfig = config
|
|
403
|
-
|
|
404
|
-
if (config.config) {
|
|
405
|
-
const [configFile, template = "default"] = config.config.split(":")
|
|
406
|
-
const configImport: ScaffoldConfigFile = require(path.resolve(process.cwd(), configFile))
|
|
407
|
-
if (!configImport[template]) {
|
|
408
|
-
throw new Error(`Template "${template}" not found in ${configFile}`)
|
|
409
|
-
}
|
|
410
|
-
c = {
|
|
411
|
-
...config,
|
|
412
|
-
...configImport[template],
|
|
413
|
-
data: {
|
|
414
|
-
...configImport[template].data,
|
|
415
|
-
...config.data,
|
|
416
|
-
},
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
c.data = { ...c.data, ...config.appendData }
|
|
421
|
-
delete config.appendData
|
|
422
|
-
return c
|
|
423
|
-
}
|