@quilted/create 0.1.36 → 0.1.38
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/CHANGELOG.md +12 -0
- package/build/cjs/app.cjs +17 -21
- package/build/cjs/index4.cjs +7635 -0
- package/build/cjs/package.cjs +162 -65
- package/build/cjs/shared/package-manager.cjs +57 -7
- package/build/esm/app.mjs +18 -22
- package/build/esm/index4.mjs +7626 -0
- package/build/esm/package.mjs +164 -67
- package/build/esm/shared/package-manager.mjs +57 -8
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts.map +1 -1
- package/build/typescript/package.d.ts.map +1 -1
- package/build/typescript/shared/prompts.d.ts +9 -2
- package/build/typescript/shared/prompts.d.ts.map +1 -1
- package/build/typescript/shared.d.ts +1 -0
- package/build/typescript/shared.d.ts.map +1 -1
- package/package.json +2 -1
- package/source/app.ts +20 -28
- package/source/package.ts +239 -101
- package/source/shared/prompts.ts +21 -6
- package/source/shared.ts +68 -7
- package/templates/package/README.md +1 -1
- package/templates/package/quilt.project.ts +1 -1
- package/templates/workspace/_nvmrc +1 -1
- package/templates/workspace/package.json +4 -0
package/source/package.ts
CHANGED
|
@@ -8,13 +8,14 @@ import {
|
|
|
8
8
|
format,
|
|
9
9
|
loadTemplate,
|
|
10
10
|
createOutputTarget,
|
|
11
|
-
mergeDependencies,
|
|
12
11
|
isEmpty,
|
|
13
12
|
emptyDirectory,
|
|
14
13
|
toValidPackageName,
|
|
15
14
|
relativeDirectoryForDisplay,
|
|
15
|
+
mergeWorkspaceAndProjectPackageJsons,
|
|
16
16
|
} from './shared';
|
|
17
17
|
import {
|
|
18
|
+
getInWorkspace,
|
|
18
19
|
getCreateAsMonorepo,
|
|
19
20
|
getExtrasToSetup,
|
|
20
21
|
getPackageManager,
|
|
@@ -30,6 +31,13 @@ export async function createProject() {
|
|
|
30
31
|
|
|
31
32
|
if (args['--help']) {
|
|
32
33
|
const additionalOptions = stripIndent`
|
|
34
|
+
${color.cyan(`--description`)}, ${color.cyan(`--no-description`)}
|
|
35
|
+
A short description of the package. If you don’t provide this option, the command will ask
|
|
36
|
+
you for a description later.
|
|
37
|
+
${color.dim(
|
|
38
|
+
`@see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#description`,
|
|
39
|
+
)}
|
|
40
|
+
|
|
33
41
|
${color.cyan(`--react`)}, ${color.cyan(`--no-react`)}
|
|
34
42
|
Whether this package will use React. If you don’t provide this option, the command
|
|
35
43
|
will ask you about it later.
|
|
@@ -38,6 +46,13 @@ export async function createProject() {
|
|
|
38
46
|
Whether this package will be published for other projects to install. If you do not
|
|
39
47
|
provide this option, the command will ask you about it later.
|
|
40
48
|
|
|
49
|
+
${color.cyan(`--repository`)}, ${color.cyan(`--no-repository`)}
|
|
50
|
+
The URL of a git repository where your code lives. If you do not provide this option,
|
|
51
|
+
this command will try to guess the correct repository to use based on existing packages.
|
|
52
|
+
${color.dim(
|
|
53
|
+
`@see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#repository`,
|
|
54
|
+
)}
|
|
55
|
+
|
|
41
56
|
${color.cyan(`--registry`)}
|
|
42
57
|
The package registry to publish this package to. This option only applies if you create
|
|
43
58
|
a public package. If you do not provide this option, it will use the default NPM registry.
|
|
@@ -51,17 +66,19 @@ export async function createProject() {
|
|
|
51
66
|
return;
|
|
52
67
|
}
|
|
53
68
|
|
|
54
|
-
const inWorkspace = fs.existsSync('quilt.workspace.ts');
|
|
55
|
-
|
|
56
69
|
const name = await getName(args);
|
|
70
|
+
const description = await getDescription(args);
|
|
71
|
+
const inWorkspace = await getInWorkspace(args);
|
|
57
72
|
const directory = await getDirectory(args, {name, inWorkspace});
|
|
58
73
|
const isPublic = await getPublic(args);
|
|
74
|
+
const repository = await getRepository(args, {inWorkspace});
|
|
59
75
|
const useReact = await getReact(args);
|
|
60
76
|
|
|
61
|
-
const createAsMonorepo =
|
|
62
|
-
|
|
63
|
-
const packageManager = await getPackageManager(args, {root: directory});
|
|
77
|
+
const createAsMonorepo =
|
|
78
|
+
!inWorkspace && (await getCreateAsMonorepo(args, {type: 'package'}));
|
|
64
79
|
const setupExtras = await getExtrasToSetup(args, {inWorkspace});
|
|
80
|
+
const shouldInstall = await getShouldInstall(args, {type: 'package'});
|
|
81
|
+
const packageManager = await getPackageManager(args, {root: directory});
|
|
65
82
|
|
|
66
83
|
const partOfMonorepo = inWorkspace || createAsMonorepo;
|
|
67
84
|
|
|
@@ -89,11 +106,18 @@ export async function createProject() {
|
|
|
89
106
|
|
|
90
107
|
let quiltProject = await packageTemplate.read('quilt.project.ts');
|
|
91
108
|
|
|
109
|
+
if (!useReact) {
|
|
110
|
+
quiltProject = quiltProject.replace(
|
|
111
|
+
'quiltPackage()',
|
|
112
|
+
'quiltPackage({react: false})',
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
|
|
92
116
|
// If we aren’t already in a workspace, copy the workspace files over, which
|
|
93
117
|
// are needed if we are making a monorepo or not.
|
|
94
118
|
if (!inWorkspace) {
|
|
95
119
|
await workspaceTemplate.copy(directory, (file) => {
|
|
96
|
-
// When this is a single project, we use the project’s Quilt
|
|
120
|
+
// When this is a single project, we use the project’s Quilt configuration as the base.
|
|
97
121
|
if (file === 'quilt.workspace.ts') return createAsMonorepo;
|
|
98
122
|
|
|
99
123
|
// We need to make some adjustments to the root package.json
|
|
@@ -103,11 +127,19 @@ export async function createProject() {
|
|
|
103
127
|
// If we are creating a monorepo, we need to add the root package.json and
|
|
104
128
|
// package manager workspace configuration.
|
|
105
129
|
if (createAsMonorepo) {
|
|
130
|
+
const packageRelativeToRoot = path.relative(
|
|
131
|
+
rootDirectory,
|
|
132
|
+
packageDirectory,
|
|
133
|
+
);
|
|
134
|
+
const packageGlobRelativeToRoot = relativeDirectoryForDisplay(
|
|
135
|
+
path.join(packageRelativeToRoot, '*'),
|
|
136
|
+
);
|
|
106
137
|
const workspacePackageJson = JSON.parse(
|
|
107
138
|
await workspaceTemplate.read('package.json'),
|
|
108
139
|
);
|
|
109
140
|
|
|
110
141
|
workspacePackageJson.name = toValidPackageName(name!);
|
|
142
|
+
workspacePackageJson.workspaces = [packageGlobRelativeToRoot];
|
|
111
143
|
|
|
112
144
|
if (packageManager.type === 'pnpm') {
|
|
113
145
|
await outputRoot.write(
|
|
@@ -115,13 +147,11 @@ export async function createProject() {
|
|
|
115
147
|
await format(
|
|
116
148
|
`
|
|
117
149
|
packages:
|
|
118
|
-
- '
|
|
150
|
+
- '${packageGlobRelativeToRoot}'
|
|
119
151
|
`,
|
|
120
152
|
{as: 'yaml'},
|
|
121
153
|
),
|
|
122
154
|
);
|
|
123
|
-
} else {
|
|
124
|
-
workspacePackageJson.workspaces = ['packages/*'];
|
|
125
155
|
}
|
|
126
156
|
|
|
127
157
|
await outputRoot.write(
|
|
@@ -144,31 +174,14 @@ export async function createProject() {
|
|
|
144
174
|
.then((content) => JSON.parse(content)),
|
|
145
175
|
]);
|
|
146
176
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
// We want to put the project’s dependencies in the package.json, respecting
|
|
153
|
-
// the preferred ordering (dependencies, peer dependencies, dev dependencies).
|
|
154
|
-
for (const [key, value] of Object.entries(projectPackageJson)) {
|
|
155
|
-
if (key !== 'devDependencies') {
|
|
156
|
-
newPackageJson[key] = value;
|
|
157
|
-
continue;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
newPackageJson.dependencies = projectPackageJson.dependencies;
|
|
161
|
-
newPackageJson.peerDependencies = projectPackageJson.peerDependencies;
|
|
162
|
-
newPackageJson.peerDependenciesMeta =
|
|
163
|
-
projectPackageJson.peerDependenciesMeta;
|
|
164
|
-
newPackageJson.devDependencies = mergeDependencies(
|
|
165
|
-
workspacePackageJson.devDependencies,
|
|
166
|
-
projectPackageJson.devDependencies,
|
|
167
|
-
);
|
|
168
|
-
}
|
|
177
|
+
const mergedPackageJson = mergeWorkspaceAndProjectPackageJsons(
|
|
178
|
+
projectPackageJson,
|
|
179
|
+
workspacePackageJson,
|
|
180
|
+
);
|
|
169
181
|
|
|
170
|
-
adjustPackageJson(
|
|
182
|
+
adjustPackageJson(mergedPackageJson, {
|
|
171
183
|
name: toValidPackageName(name!),
|
|
184
|
+
description,
|
|
172
185
|
react: useReact,
|
|
173
186
|
isPublic,
|
|
174
187
|
registry: args['--registry'],
|
|
@@ -185,7 +198,7 @@ export async function createProject() {
|
|
|
185
198
|
|
|
186
199
|
await outputRoot.write(
|
|
187
200
|
'package.json',
|
|
188
|
-
await format(JSON.stringify(
|
|
201
|
+
await format(JSON.stringify(mergedPackageJson), {
|
|
189
202
|
as: 'json-stringify',
|
|
190
203
|
}),
|
|
191
204
|
);
|
|
@@ -211,23 +224,48 @@ export async function createProject() {
|
|
|
211
224
|
return partOfMonorepo;
|
|
212
225
|
}
|
|
213
226
|
|
|
214
|
-
// We need to make some adjustments the project’s package.json and Quilt config
|
|
215
|
-
return
|
|
227
|
+
// We need to make some adjustments the project’s package.json, README, and Quilt config
|
|
228
|
+
return (
|
|
229
|
+
file !== 'package.json' &&
|
|
230
|
+
file !== 'quilt.project.ts' &&
|
|
231
|
+
file !== 'README.md'
|
|
232
|
+
);
|
|
216
233
|
});
|
|
217
234
|
|
|
235
|
+
await outputRoot.write(
|
|
236
|
+
path.join(packageDirectory, 'package.json'),
|
|
237
|
+
(
|
|
238
|
+
await packageTemplate.read('README.md')
|
|
239
|
+
).replaceAll('{{name}}', toValidPackageName(name!)),
|
|
240
|
+
);
|
|
241
|
+
|
|
218
242
|
if (partOfMonorepo) {
|
|
219
243
|
// Write the package’s package.json (the root one was already created)
|
|
220
244
|
const projectPackageJson = JSON.parse(
|
|
221
245
|
await packageTemplate.read('package.json'),
|
|
222
246
|
);
|
|
223
247
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
248
|
+
if (repository === false) {
|
|
249
|
+
delete projectPackageJson.repository;
|
|
250
|
+
} else {
|
|
251
|
+
const directory = path.relative(rootDirectory, packageDirectory);
|
|
252
|
+
|
|
253
|
+
if (typeof repository === 'string') {
|
|
254
|
+
projectPackageJson.repository = {
|
|
255
|
+
type: 'git',
|
|
256
|
+
url: repository,
|
|
257
|
+
directory,
|
|
258
|
+
};
|
|
259
|
+
} else if (repository != null) {
|
|
260
|
+
projectPackageJson.repository = {type: 'git', ...repository, directory};
|
|
261
|
+
} else {
|
|
262
|
+
projectPackageJson.repository.directory = directory;
|
|
263
|
+
}
|
|
264
|
+
}
|
|
228
265
|
|
|
229
266
|
adjustPackageJson(projectPackageJson, {
|
|
230
267
|
name: toValidPackageName(name),
|
|
268
|
+
description,
|
|
231
269
|
react: useReact,
|
|
232
270
|
isPublic,
|
|
233
271
|
registry: args['--registry'],
|
|
@@ -256,80 +294,112 @@ export async function createProject() {
|
|
|
256
294
|
}
|
|
257
295
|
|
|
258
296
|
if (shouldInstall) {
|
|
259
|
-
|
|
297
|
+
console.log();
|
|
260
298
|
// TODO: better loading, handle errors
|
|
261
299
|
await packageManager.install();
|
|
262
|
-
process.stdout.moveCursor(0, -1);
|
|
263
|
-
process.stdout.clearLine(1);
|
|
264
|
-
console.log('Installed dependencies.');
|
|
265
300
|
}
|
|
266
301
|
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
302
|
+
console.log();
|
|
303
|
+
console.log(
|
|
304
|
+
stripIndent`
|
|
305
|
+
Your new package, ${color.bold(
|
|
306
|
+
name,
|
|
307
|
+
)}, is ready to go! You can edit the code
|
|
308
|
+
for your package in ${color.cyan(
|
|
309
|
+
relativeDirectoryForDisplay(
|
|
310
|
+
path.relative(process.cwd(), path.join(packageDirectory, 'source')),
|
|
274
311
|
),
|
|
275
|
-
)
|
|
276
|
-
|
|
312
|
+
)}.
|
|
313
|
+
`,
|
|
314
|
+
);
|
|
277
315
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
)}, where you provide a description of what your package does
|
|
281
|
-
- ${color.bold(`"repository"`)}, where you should include the ${color.bold(
|
|
282
|
-
`"url"`,
|
|
283
|
-
)} of your project’s repo
|
|
316
|
+
if (isPublic) {
|
|
317
|
+
const needsPackageJsonKeys: {field: string; url: string}[] = [];
|
|
284
318
|
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
319
|
+
if (!description) {
|
|
320
|
+
needsPackageJsonKeys.push({
|
|
321
|
+
field: 'description',
|
|
322
|
+
url: 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#description',
|
|
323
|
+
});
|
|
324
|
+
}
|
|
290
325
|
|
|
291
|
-
|
|
292
|
-
|
|
326
|
+
if (repository == null) {
|
|
327
|
+
needsPackageJsonKeys.push({
|
|
328
|
+
field: 'repository.url',
|
|
329
|
+
url: 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#repository',
|
|
330
|
+
});
|
|
331
|
+
}
|
|
293
332
|
|
|
294
|
-
|
|
333
|
+
console.log();
|
|
295
334
|
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
335
|
+
const logPackageJsonField = (field: string, url: string) => {
|
|
336
|
+
console.log(
|
|
337
|
+
` ${color.bold(JSON.stringify(field))} ${color.dim(
|
|
338
|
+
`(${color.underline(url)})`,
|
|
339
|
+
)}`,
|
|
340
|
+
);
|
|
341
|
+
};
|
|
342
|
+
|
|
343
|
+
if (needsPackageJsonKeys.length > 0) {
|
|
344
|
+
console.log(
|
|
345
|
+
stripIndent`
|
|
346
|
+
Before you publish your package, you will need to add the following key${
|
|
347
|
+
needsPackageJsonKeys.length > 1 ? 's' : ''
|
|
348
|
+
}
|
|
349
|
+
to ${color.cyan(
|
|
350
|
+
relativeDirectoryForDisplay(
|
|
351
|
+
path.relative(
|
|
352
|
+
process.cwd(),
|
|
353
|
+
path.join(packageDirectory, 'package.json'),
|
|
354
|
+
),
|
|
355
|
+
),
|
|
356
|
+
)}:
|
|
357
|
+
`,
|
|
358
|
+
);
|
|
303
359
|
|
|
304
|
-
|
|
305
|
-
commands.push(
|
|
306
|
-
`${packageManager.commands.install()} ${color.dim(
|
|
307
|
-
'# Install all your dependencies',
|
|
308
|
-
)}`,
|
|
309
|
-
);
|
|
310
|
-
}
|
|
360
|
+
console.log();
|
|
311
361
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
`git init && git add -A && git commit -m "Initial commit" ${color.dim(
|
|
316
|
-
'# Start your git history (optional)',
|
|
317
|
-
)}`,
|
|
318
|
-
);
|
|
319
|
-
}
|
|
362
|
+
for (const {field, url} of needsPackageJsonKeys) {
|
|
363
|
+
logPackageJsonField(field, url);
|
|
364
|
+
}
|
|
320
365
|
|
|
321
|
-
|
|
322
|
-
const whatsNext = stripIndent`
|
|
323
|
-
After you update your package.json, there’s ${
|
|
324
|
-
commands.length > 1 ? 'a few more steps' : 'one more step'
|
|
325
|
-
} you’ll need to take
|
|
326
|
-
in order to start building:
|
|
327
|
-
`;
|
|
366
|
+
console.log();
|
|
328
367
|
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
368
|
+
console.log(
|
|
369
|
+
'In that same file, make sure the contents of these fields are right for your package:',
|
|
370
|
+
);
|
|
371
|
+
|
|
372
|
+
console.log();
|
|
373
|
+
} else {
|
|
374
|
+
console.log(
|
|
375
|
+
stripIndent`
|
|
376
|
+
Before you publish your package, make the following fields look right
|
|
377
|
+
in ${color.cyan(
|
|
378
|
+
relativeDirectoryForDisplay(
|
|
379
|
+
path.relative(
|
|
380
|
+
process.cwd(),
|
|
381
|
+
path.join(packageDirectory, 'package.json'),
|
|
382
|
+
),
|
|
383
|
+
),
|
|
384
|
+
)}:
|
|
385
|
+
`,
|
|
386
|
+
);
|
|
387
|
+
|
|
388
|
+
console.log();
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
logPackageJsonField(
|
|
392
|
+
'version',
|
|
393
|
+
'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#version',
|
|
394
|
+
);
|
|
395
|
+
logPackageJsonField(
|
|
396
|
+
'license',
|
|
397
|
+
'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#license',
|
|
398
|
+
);
|
|
399
|
+
logPackageJsonField(
|
|
400
|
+
'exports',
|
|
401
|
+
'https://nodejs.org/api/packages.html#package-entry-points',
|
|
402
|
+
);
|
|
333
403
|
}
|
|
334
404
|
|
|
335
405
|
const followUp = stripIndent`
|
|
@@ -357,6 +427,10 @@ function getArguments() {
|
|
|
357
427
|
'-y': '--yes',
|
|
358
428
|
'--name': String,
|
|
359
429
|
'--directory': String,
|
|
430
|
+
'--description': String,
|
|
431
|
+
'--no-description': Boolean,
|
|
432
|
+
'--repository': String,
|
|
433
|
+
'--no-repository': Boolean,
|
|
360
434
|
'--install': Boolean,
|
|
361
435
|
'--no-install': Boolean,
|
|
362
436
|
'--monorepo': Boolean,
|
|
@@ -443,6 +517,38 @@ async function getDirectory(
|
|
|
443
517
|
return directory;
|
|
444
518
|
}
|
|
445
519
|
|
|
520
|
+
async function getDescription(args: Arguments) {
|
|
521
|
+
if (args['--description']) return args['--description'];
|
|
522
|
+
if (args['--no-description']) return false;
|
|
523
|
+
|
|
524
|
+
const description = await prompt({
|
|
525
|
+
type: 'text',
|
|
526
|
+
message: 'What is a short description of what this package will do?',
|
|
527
|
+
});
|
|
528
|
+
|
|
529
|
+
return description;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
async function getRepository(args: Arguments, {inWorkspace = false} = {}) {
|
|
533
|
+
if (args['--repository']) return args['--repository'];
|
|
534
|
+
if (args['--no-repository']) return false;
|
|
535
|
+
|
|
536
|
+
if (!inWorkspace) return;
|
|
537
|
+
|
|
538
|
+
const {globby} = await import('globby');
|
|
539
|
+
|
|
540
|
+
const files = await globby('**/package.json', {ignore: ['**/node_modules']});
|
|
541
|
+
|
|
542
|
+
for (const file of files) {
|
|
543
|
+
try {
|
|
544
|
+
const json = JSON.parse(await fs.promises.readFile(file, 'utf8'));
|
|
545
|
+
if (json.repository) return json.repository as string | {url: string};
|
|
546
|
+
} catch {
|
|
547
|
+
// noop
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
|
|
446
552
|
async function getPublic(args: Arguments) {
|
|
447
553
|
let isPublic: boolean;
|
|
448
554
|
|
|
@@ -483,10 +589,17 @@ function adjustPackageJson(
|
|
|
483
589
|
packageJson: Record<string, any>,
|
|
484
590
|
{
|
|
485
591
|
name,
|
|
592
|
+
description,
|
|
486
593
|
react,
|
|
487
594
|
isPublic,
|
|
488
595
|
registry,
|
|
489
|
-
}: {
|
|
596
|
+
}: {
|
|
597
|
+
name: string;
|
|
598
|
+
description: string | false;
|
|
599
|
+
react: boolean;
|
|
600
|
+
isPublic: boolean;
|
|
601
|
+
registry?: string;
|
|
602
|
+
},
|
|
490
603
|
) {
|
|
491
604
|
packageJson.name = name;
|
|
492
605
|
|
|
@@ -494,6 +607,12 @@ function adjustPackageJson(
|
|
|
494
607
|
const scope = packageParts[0]!.startsWith('@') ? packageParts[0] : undefined;
|
|
495
608
|
const finalRegistry = registry ?? 'https://registry.npmjs.org';
|
|
496
609
|
|
|
610
|
+
if (description) {
|
|
611
|
+
packageJson.description = description;
|
|
612
|
+
} else {
|
|
613
|
+
delete packageJson.description;
|
|
614
|
+
}
|
|
615
|
+
|
|
497
616
|
if (scope) {
|
|
498
617
|
packageJson.publishConfig[`${scope}/registry`] = finalRegistry;
|
|
499
618
|
} else if (registry) {
|
|
@@ -503,7 +622,26 @@ function adjustPackageJson(
|
|
|
503
622
|
if (isPublic) {
|
|
504
623
|
delete packageJson.private;
|
|
505
624
|
} else {
|
|
625
|
+
delete packageJson.license;
|
|
626
|
+
delete packageJson.repository;
|
|
506
627
|
delete packageJson.publishConfig;
|
|
628
|
+
|
|
629
|
+
// in private packages, we just need to reference the source.
|
|
630
|
+
const newExports: Record<string, string> = {};
|
|
631
|
+
|
|
632
|
+
for (const [key, value] of Object.entries(packageJson.exports)) {
|
|
633
|
+
if (typeof value === 'string') {
|
|
634
|
+
newExports[key] = value;
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
const sourceEntry = (value as any)?.['quilt:source'];
|
|
638
|
+
|
|
639
|
+
if (typeof sourceEntry === 'string') {
|
|
640
|
+
newExports[key] = sourceEntry;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
packageJson.exports = newExports;
|
|
507
645
|
}
|
|
508
646
|
|
|
509
647
|
if (!react) {
|
package/source/shared/prompts.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
|
|
1
3
|
import type {Result as ArgvResult} from 'arg';
|
|
2
4
|
import * as color from 'colorette';
|
|
3
5
|
import {
|
|
@@ -12,6 +14,8 @@ type BaseArguments = ArgvResult<{
|
|
|
12
14
|
'--no-install': BooleanConstructor;
|
|
13
15
|
'--monorepo': BooleanConstructor;
|
|
14
16
|
'--no-monorepo': BooleanConstructor;
|
|
17
|
+
'--in-workspace': BooleanConstructor;
|
|
18
|
+
'--not-in-workspace': BooleanConstructor;
|
|
15
19
|
'--extras': [StringConstructor];
|
|
16
20
|
'--no-extras': BooleanConstructor;
|
|
17
21
|
'--package-manager': StringConstructor;
|
|
@@ -19,7 +23,17 @@ type BaseArguments = ArgvResult<{
|
|
|
19
23
|
|
|
20
24
|
export {prompt};
|
|
21
25
|
|
|
22
|
-
export async function
|
|
26
|
+
export async function getInWorkspace(argv: BaseArguments) {
|
|
27
|
+
if (argv['--in-workspace']) return true;
|
|
28
|
+
if (argv['--not-in-workspace']) return false;
|
|
29
|
+
|
|
30
|
+
return fs.existsSync('quilt.workspace.ts');
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export async function getCreateAsMonorepo(
|
|
34
|
+
argv: BaseArguments,
|
|
35
|
+
{type}: {type: 'app' | 'package'},
|
|
36
|
+
) {
|
|
23
37
|
let createAsMonorepo: boolean;
|
|
24
38
|
|
|
25
39
|
if (argv['--monorepo' || argv['--yes']]) {
|
|
@@ -29,8 +43,7 @@ export async function getCreateAsMonorepo(argv: BaseArguments) {
|
|
|
29
43
|
} else {
|
|
30
44
|
createAsMonorepo = await prompt({
|
|
31
45
|
type: 'confirm',
|
|
32
|
-
message:
|
|
33
|
-
'Do you want to create this app as a monorepo, with room for more projects?',
|
|
46
|
+
message: `Do you want to create this ${type} as a monorepo, with room for more projects?`,
|
|
34
47
|
initial: true,
|
|
35
48
|
});
|
|
36
49
|
}
|
|
@@ -38,7 +51,10 @@ export async function getCreateAsMonorepo(argv: BaseArguments) {
|
|
|
38
51
|
return createAsMonorepo;
|
|
39
52
|
}
|
|
40
53
|
|
|
41
|
-
export async function getShouldInstall(
|
|
54
|
+
export async function getShouldInstall(
|
|
55
|
+
argv: BaseArguments,
|
|
56
|
+
{type}: {type: 'app' | 'package'},
|
|
57
|
+
) {
|
|
42
58
|
let shouldInstall: boolean;
|
|
43
59
|
|
|
44
60
|
if (argv['--install'] || argv['--yes']) {
|
|
@@ -48,8 +64,7 @@ export async function getShouldInstall(argv: BaseArguments) {
|
|
|
48
64
|
} else {
|
|
49
65
|
shouldInstall = await prompt({
|
|
50
66
|
type: 'confirm',
|
|
51
|
-
message:
|
|
52
|
-
'Do you want to install dependencies for this app after creating it?',
|
|
67
|
+
message: `Do you want to install dependencies for this ${type} after creating it?`,
|
|
53
68
|
initial: true,
|
|
54
69
|
});
|
|
55
70
|
}
|
package/source/shared.ts
CHANGED
|
@@ -152,13 +152,20 @@ export async function format(
|
|
|
152
152
|
content: string,
|
|
153
153
|
{as: parser}: {as: BuiltInParserName},
|
|
154
154
|
) {
|
|
155
|
-
const [
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
155
|
+
const [
|
|
156
|
+
{format: rootFormat, default: prettier},
|
|
157
|
+
{default: babel},
|
|
158
|
+
{default: typescript},
|
|
159
|
+
{default: yaml},
|
|
160
|
+
] = await Promise.all([
|
|
161
|
+
import('prettier/standalone'),
|
|
162
|
+
import('prettier/parser-babel'),
|
|
163
|
+
import('prettier/parser-typescript'),
|
|
164
|
+
import('prettier/parser-yaml'),
|
|
165
|
+
]);
|
|
166
|
+
|
|
167
|
+
// CJS workaround
|
|
168
|
+
const format = rootFormat ?? prettier.format;
|
|
162
169
|
|
|
163
170
|
return format(content, {
|
|
164
171
|
arrowParens: 'always',
|
|
@@ -185,3 +192,57 @@ export function mergeDependencies(
|
|
|
185
192
|
|
|
186
193
|
return merged;
|
|
187
194
|
}
|
|
195
|
+
|
|
196
|
+
const PACKAGE_JSON_DEPENDENCY_KEYS = new Set([
|
|
197
|
+
'dependencies',
|
|
198
|
+
'devDependencies',
|
|
199
|
+
'peerDependencies',
|
|
200
|
+
'peerDependenciesMeta',
|
|
201
|
+
]);
|
|
202
|
+
|
|
203
|
+
// Merges a project and workspace package.json together, with the following nitpicky preferences:
|
|
204
|
+
//
|
|
205
|
+
// - Take all the project’s fields in the order they appear by default
|
|
206
|
+
// - Merge the relevant dependencies together
|
|
207
|
+
// - Projects don’t come with `scripts` by default, but that should go before the first dependency list
|
|
208
|
+
// - If there are other keys in the workspace package.json, they should go last, in the order they appeared
|
|
209
|
+
export function mergeWorkspaceAndProjectPackageJsons(
|
|
210
|
+
projectPackageJson: Record<string, unknown>,
|
|
211
|
+
workspacePackageJson: Record<string, unknown>,
|
|
212
|
+
) {
|
|
213
|
+
const newPackageJson: Record<string, unknown> = {};
|
|
214
|
+
const seenKeys = new Set<string>();
|
|
215
|
+
let hasHandledScriptsField = false;
|
|
216
|
+
|
|
217
|
+
for (const [key, value] of Object.entries(projectPackageJson)) {
|
|
218
|
+
seenKeys.add(key);
|
|
219
|
+
|
|
220
|
+
const isDependencyKey = PACKAGE_JSON_DEPENDENCY_KEYS.has(key);
|
|
221
|
+
|
|
222
|
+
if (key === 'scripts' || (isDependencyKey && !hasHandledScriptsField)) {
|
|
223
|
+
newPackageJson.scripts = {
|
|
224
|
+
...(workspacePackageJson.scripts as any),
|
|
225
|
+
...(projectPackageJson.scripts as any),
|
|
226
|
+
};
|
|
227
|
+
hasHandledScriptsField = true;
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
if (isDependencyKey) {
|
|
231
|
+
newPackageJson[key] = mergeDependencies(
|
|
232
|
+
value as any,
|
|
233
|
+
workspacePackageJson[key] as any,
|
|
234
|
+
);
|
|
235
|
+
} else {
|
|
236
|
+
newPackageJson[key] = value;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
for (const [key, value] of Object.entries(workspacePackageJson)) {
|
|
241
|
+
if (seenKeys.has(key)) continue;
|
|
242
|
+
// Merged workspace + project package.json means we are not in a monorepo
|
|
243
|
+
if (key === 'workspaces') continue;
|
|
244
|
+
newPackageJson[key] = value;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
return newPackageJson;
|
|
248
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
#
|
|
1
|
+
# `{{name}}`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
18.13.0
|