@quilted/create 0.1.35 → 0.1.37
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 +16 -21
- package/build/cjs/index4.cjs +7635 -0
- package/build/cjs/package.cjs +124 -63
- package/build/cjs/shared/package-manager.cjs +61 -9
- package/build/esm/app.mjs +17 -22
- package/build/esm/index4.mjs +7626 -0
- package/build/esm/package.mjs +126 -65
- package/build/esm/shared/package-manager.mjs +61 -10
- 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 +19 -28
- package/source/package.ts +174 -102
- package/source/shared/prompts.ts +21 -6
- package/source/shared.ts +69 -7
- package/templates/app-basic/server.tsx +9 -5
- package/templates/package/quilt.project.ts +1 -1
- package/templates/workspace/package.json +4 -0
package/build/cjs/package.cjs
CHANGED
|
@@ -34,6 +34,11 @@ async function createProject() {
|
|
|
34
34
|
const args = getArguments();
|
|
35
35
|
if (args['--help']) {
|
|
36
36
|
const additionalOptions = index.stripIndent`
|
|
37
|
+
${index.cyan_1(`--description`)}, ${index.cyan_1(`--no-description`)}
|
|
38
|
+
A short description of the package. If you don’t provide this option, the command will ask
|
|
39
|
+
you for a description later.
|
|
40
|
+
${index.dim_1(`@see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#description`)}
|
|
41
|
+
|
|
37
42
|
${index.cyan_1(`--react`)}, ${index.cyan_1(`--no-react`)}
|
|
38
43
|
Whether this package will use React. If you don’t provide this option, the command
|
|
39
44
|
will ask you about it later.
|
|
@@ -42,6 +47,11 @@ async function createProject() {
|
|
|
42
47
|
Whether this package will be published for other projects to install. If you do not
|
|
43
48
|
provide this option, the command will ask you about it later.
|
|
44
49
|
|
|
50
|
+
${index.cyan_1(`--repository`)}, ${index.cyan_1(`--no-repository`)}
|
|
51
|
+
The URL of a git repository where your code lives. If you do not provide this option,
|
|
52
|
+
this command will try to guess the correct repository to use based on existing packages.
|
|
53
|
+
${index.dim_1(`@see https://docs.npmjs.com/cli/v9/configuring-npm/package-json#repository`)}
|
|
54
|
+
|
|
45
55
|
${index.cyan_1(`--registry`)}
|
|
46
56
|
The package registry to publish this package to. This option only applies if you create
|
|
47
57
|
a public package. If you do not provide this option, it will use the default NPM registry.
|
|
@@ -53,22 +63,30 @@ async function createProject() {
|
|
|
53
63
|
});
|
|
54
64
|
return;
|
|
55
65
|
}
|
|
56
|
-
const inWorkspace = fs__namespace.existsSync('quilt.workspace.ts');
|
|
57
66
|
const name = await getName(args);
|
|
67
|
+
const description = await getDescription(args);
|
|
68
|
+
const inWorkspace = await packageManager.getInWorkspace(args);
|
|
58
69
|
const directory = await getDirectory(args, {
|
|
59
70
|
name,
|
|
60
71
|
inWorkspace
|
|
61
72
|
});
|
|
62
73
|
const isPublic = await getPublic(args);
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
const shouldInstall = await packageManager.getShouldInstall(args);
|
|
66
|
-
const packageManager$1 = await packageManager.getPackageManager(args, {
|
|
67
|
-
root: directory
|
|
74
|
+
const repository = await getRepository(args, {
|
|
75
|
+
inWorkspace
|
|
68
76
|
});
|
|
77
|
+
const useReact = await getReact(args);
|
|
78
|
+
const createAsMonorepo = !inWorkspace && (await packageManager.getCreateAsMonorepo(args, {
|
|
79
|
+
type: 'package'
|
|
80
|
+
}));
|
|
69
81
|
const setupExtras = await packageManager.getExtrasToSetup(args, {
|
|
70
82
|
inWorkspace
|
|
71
83
|
});
|
|
84
|
+
const shouldInstall = await packageManager.getShouldInstall(args, {
|
|
85
|
+
type: 'package'
|
|
86
|
+
});
|
|
87
|
+
const packageManager$1 = await packageManager.getPackageManager(args, {
|
|
88
|
+
root: directory
|
|
89
|
+
});
|
|
72
90
|
const partOfMonorepo = inWorkspace || createAsMonorepo;
|
|
73
91
|
const packageDirectory = createAsMonorepo ? path__namespace.join(directory, `packages/${packageManager.toValidPackageName(name.split('/').pop())}`) : directory;
|
|
74
92
|
if (fs__namespace.existsSync(directory)) {
|
|
@@ -88,12 +106,15 @@ async function createProject() {
|
|
|
88
106
|
const packageTemplate = packageManager.loadTemplate('package');
|
|
89
107
|
const workspaceTemplate = packageManager.loadTemplate('workspace');
|
|
90
108
|
let quiltProject = await packageTemplate.read('quilt.project.ts');
|
|
109
|
+
if (!useReact) {
|
|
110
|
+
quiltProject = quiltProject.replace('quiltPackage()', 'quiltPackage({react: false})');
|
|
111
|
+
}
|
|
91
112
|
|
|
92
113
|
// If we aren’t already in a workspace, copy the workspace files over, which
|
|
93
114
|
// are needed if we are making a monorepo or not.
|
|
94
115
|
if (!inWorkspace) {
|
|
95
116
|
await workspaceTemplate.copy(directory, file => {
|
|
96
|
-
// When this is a single project, we use the project’s Quilt
|
|
117
|
+
// When this is a single project, we use the project’s Quilt configuration as the base.
|
|
97
118
|
if (file === 'quilt.workspace.ts') return createAsMonorepo;
|
|
98
119
|
|
|
99
120
|
// We need to make some adjustments to the root package.json
|
|
@@ -103,41 +124,28 @@ async function createProject() {
|
|
|
103
124
|
// If we are creating a monorepo, we need to add the root package.json and
|
|
104
125
|
// package manager workspace configuration.
|
|
105
126
|
if (createAsMonorepo) {
|
|
127
|
+
const packageRelativeToRoot = path__namespace.relative(rootDirectory, packageDirectory);
|
|
128
|
+
const packageGlobRelativeToRoot = packageManager.relativeDirectoryForDisplay(path__namespace.join(packageRelativeToRoot, '*'));
|
|
106
129
|
const workspacePackageJson = JSON.parse(await workspaceTemplate.read('package.json'));
|
|
107
130
|
workspacePackageJson.name = packageManager.toValidPackageName(name);
|
|
131
|
+
workspacePackageJson.workspaces = [packageGlobRelativeToRoot];
|
|
108
132
|
if (packageManager$1.type === 'pnpm') {
|
|
109
133
|
await outputRoot.write('pnpm-workspace.yaml', await packageManager.format(`
|
|
110
134
|
packages:
|
|
111
|
-
- '
|
|
135
|
+
- '${packageGlobRelativeToRoot}'
|
|
112
136
|
`, {
|
|
113
137
|
as: 'yaml'
|
|
114
138
|
}));
|
|
115
|
-
} else {
|
|
116
|
-
workspacePackageJson.workspaces = ['packages/*'];
|
|
117
139
|
}
|
|
118
140
|
await outputRoot.write('package.json', await packageManager.format(JSON.stringify(workspacePackageJson), {
|
|
119
141
|
as: 'json-stringify'
|
|
120
142
|
}));
|
|
121
143
|
} else {
|
|
122
144
|
const [projectPackageJson, projectTSConfig, workspacePackageJson] = await Promise.all([packageTemplate.read('package.json').then(content => JSON.parse(content)), packageTemplate.read('tsconfig.json').then(content => JSON.parse(content)), workspaceTemplate.read('package.json').then(content => JSON.parse(content))]);
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
const newPackageJson = {};
|
|
126
|
-
|
|
127
|
-
// We want to put the project’s dependencies in the package.json, respecting
|
|
128
|
-
// the preferred ordering (dependencies, peer dependencies, dev dependencies).
|
|
129
|
-
for (const [key, value] of Object.entries(projectPackageJson)) {
|
|
130
|
-
if (key !== 'devDependencies') {
|
|
131
|
-
newPackageJson[key] = value;
|
|
132
|
-
continue;
|
|
133
|
-
}
|
|
134
|
-
newPackageJson.dependencies = projectPackageJson.dependencies;
|
|
135
|
-
newPackageJson.peerDependencies = projectPackageJson.peerDependencies;
|
|
136
|
-
newPackageJson.peerDependenciesMeta = projectPackageJson.peerDependenciesMeta;
|
|
137
|
-
newPackageJson.devDependencies = packageManager.mergeDependencies(workspacePackageJson.devDependencies, projectPackageJson.devDependencies);
|
|
138
|
-
}
|
|
139
|
-
adjustPackageJson(newPackageJson, {
|
|
145
|
+
const mergedPackageJson = packageManager.mergeWorkspaceAndProjectPackageJsons(projectPackageJson, workspacePackageJson);
|
|
146
|
+
adjustPackageJson(mergedPackageJson, {
|
|
140
147
|
name: packageManager.toValidPackageName(name),
|
|
148
|
+
description,
|
|
141
149
|
react: useReact,
|
|
142
150
|
isPublic,
|
|
143
151
|
registry: args['--registry']
|
|
@@ -146,7 +154,7 @@ async function createProject() {
|
|
|
146
154
|
await outputRoot.write('quilt.project.ts', await packageManager.format(quiltProject, {
|
|
147
155
|
as: 'typescript'
|
|
148
156
|
}));
|
|
149
|
-
await outputRoot.write('package.json', await packageManager.format(JSON.stringify(
|
|
157
|
+
await outputRoot.write('package.json', await packageManager.format(JSON.stringify(mergedPackageJson), {
|
|
150
158
|
as: 'json-stringify'
|
|
151
159
|
}));
|
|
152
160
|
await outputRoot.write('tsconfig.json', await packageManager.format(JSON.stringify(projectTSConfig), {
|
|
@@ -172,9 +180,29 @@ async function createProject() {
|
|
|
172
180
|
if (partOfMonorepo) {
|
|
173
181
|
// Write the package’s package.json (the root one was already created)
|
|
174
182
|
const projectPackageJson = JSON.parse(await packageTemplate.read('package.json'));
|
|
175
|
-
|
|
183
|
+
if (repository === false) {
|
|
184
|
+
delete projectPackageJson.repository;
|
|
185
|
+
} else {
|
|
186
|
+
const directory = path__namespace.relative(rootDirectory, packageDirectory);
|
|
187
|
+
if (typeof repository === 'string') {
|
|
188
|
+
projectPackageJson.repository = {
|
|
189
|
+
type: 'git',
|
|
190
|
+
url: repository,
|
|
191
|
+
directory
|
|
192
|
+
};
|
|
193
|
+
} else if (repository != null) {
|
|
194
|
+
projectPackageJson.repository = {
|
|
195
|
+
type: 'git',
|
|
196
|
+
...repository,
|
|
197
|
+
directory
|
|
198
|
+
};
|
|
199
|
+
} else {
|
|
200
|
+
projectPackageJson.repository.directory = directory;
|
|
201
|
+
}
|
|
202
|
+
}
|
|
176
203
|
adjustPackageJson(projectPackageJson, {
|
|
177
204
|
name: packageManager.toValidPackageName(name),
|
|
205
|
+
description,
|
|
178
206
|
react: useReact,
|
|
179
207
|
isPublic,
|
|
180
208
|
registry: args['--registry']
|
|
@@ -186,45 +214,36 @@ async function createProject() {
|
|
|
186
214
|
await Promise.all([packageManager.addToTsConfig(packageDirectory, outputRoot), packageManager.addToPackageManagerWorkspaces(packageDirectory, outputRoot, packageManager$1.type)]);
|
|
187
215
|
}
|
|
188
216
|
if (shouldInstall) {
|
|
189
|
-
process.stdout.write('\nInstalling dependencies...\n');
|
|
190
217
|
// TODO: better loading, handle errors
|
|
191
218
|
await packageManager$1.install();
|
|
192
|
-
process.stdout.moveCursor(0, -1);
|
|
193
|
-
process.stdout.clearLine(1);
|
|
194
|
-
console.log('Installed dependencies.');
|
|
195
219
|
}
|
|
196
|
-
const packageJsonInstructions = index.stripIndent`
|
|
197
|
-
Your new package is ready to go! However, before you go too much further,
|
|
198
|
-
you should update the following fields in ${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'package.json'))))}:
|
|
199
|
-
|
|
200
|
-
- ${index.bold_1(`"description"`)}, where you provide a description of what your package does
|
|
201
|
-
- ${index.bold_1(`"repository"`)}, where you should include the ${index.bold_1(`"url"`)} of your project’s repo
|
|
202
|
-
|
|
203
|
-
Before you publish your package, you will also want to update the ${index.bold_1(`"version"`)}
|
|
204
|
-
field in the package.json file.
|
|
205
|
-
`;
|
|
206
220
|
console.log();
|
|
207
|
-
console.log(
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
if (commands.length > 0) {
|
|
220
|
-
const whatsNext = index.stripIndent`
|
|
221
|
-
After you update your package.json, there’s ${commands.length > 1 ? 'a few more steps' : 'one more step'} you’ll need to take
|
|
222
|
-
in order to start building:
|
|
223
|
-
`;
|
|
224
|
-
console.log();
|
|
225
|
-
console.log(whatsNext);
|
|
221
|
+
console.log(index.stripIndent`
|
|
222
|
+
Your new package, ${index.bold_1(name)}, is ready to go! You can edit the code for your package in
|
|
223
|
+
${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'source'))))}.
|
|
224
|
+
`);
|
|
225
|
+
if (isPublic) {
|
|
226
|
+
const needsPackageJsonKeys = [];
|
|
227
|
+
if (!description) {
|
|
228
|
+
needsPackageJsonKeys.push('description');
|
|
229
|
+
}
|
|
230
|
+
if (repository == null) {
|
|
231
|
+
needsPackageJsonKeys.push('repository.url');
|
|
232
|
+
}
|
|
226
233
|
console.log();
|
|
227
|
-
|
|
234
|
+
if (needsPackageJsonKeys.length > 0) {
|
|
235
|
+
console.log(index.stripIndent`
|
|
236
|
+
Before you publish your package, you will need to add the ${needsPackageJsonKeys.map(key => index.bold_1(JSON.stringify(key))).join(' and ')} key${needsPackageJsonKeys.length > 1 ? 's' : ''}
|
|
237
|
+
to ${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'package.json'))))}. In that same file, make sure the contents of the
|
|
238
|
+
${index.bold_1('"version"')}, ${index.bold_1('"exports"')}, and ${index.bold_1('"license"')} fields are correct for your package.
|
|
239
|
+
`);
|
|
240
|
+
} else {
|
|
241
|
+
console.log(index.stripIndent`
|
|
242
|
+
Before you publish your package, make sure the content of the
|
|
243
|
+
${index.bold_1('"version"')}, ${index.bold_1('exports')}, and ${index.bold_1('license')} fields in
|
|
244
|
+
${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'package.json'))))} are correct for your package.
|
|
245
|
+
`);
|
|
246
|
+
}
|
|
228
247
|
}
|
|
229
248
|
const followUp = index.stripIndent`
|
|
230
249
|
Quilt can help you build, test, lint, and type-check your new package. You
|
|
@@ -245,6 +264,10 @@ function getArguments() {
|
|
|
245
264
|
'-y': '--yes',
|
|
246
265
|
'--name': String,
|
|
247
266
|
'--directory': String,
|
|
267
|
+
'--description': String,
|
|
268
|
+
'--no-description': Boolean,
|
|
269
|
+
'--repository': String,
|
|
270
|
+
'--no-repository': Boolean,
|
|
248
271
|
'--install': Boolean,
|
|
249
272
|
'--no-install': Boolean,
|
|
250
273
|
'--monorepo': Boolean,
|
|
@@ -311,6 +334,36 @@ async function getDirectory(args, {
|
|
|
311
334
|
}
|
|
312
335
|
return directory;
|
|
313
336
|
}
|
|
337
|
+
async function getDescription(args) {
|
|
338
|
+
if (args['--description']) return args['--description'];
|
|
339
|
+
if (args['--no-description']) return false;
|
|
340
|
+
const description = await index.prompt({
|
|
341
|
+
type: 'text',
|
|
342
|
+
message: 'What is a short description of what this package will do?'
|
|
343
|
+
});
|
|
344
|
+
return description;
|
|
345
|
+
}
|
|
346
|
+
async function getRepository(args, {
|
|
347
|
+
inWorkspace = false
|
|
348
|
+
} = {}) {
|
|
349
|
+
if (args['--repository']) return args['--repository'];
|
|
350
|
+
if (args['--no-repository']) return false;
|
|
351
|
+
if (!inWorkspace) return;
|
|
352
|
+
const {
|
|
353
|
+
globby
|
|
354
|
+
} = await Promise.resolve().then(function () { return require('./index4.cjs'); });
|
|
355
|
+
const files = await globby('**/package.json', {
|
|
356
|
+
ignore: ['**/node_modules']
|
|
357
|
+
});
|
|
358
|
+
for (const file of files) {
|
|
359
|
+
try {
|
|
360
|
+
const json = JSON.parse(await fs__namespace.promises.readFile(file, 'utf8'));
|
|
361
|
+
if (json.repository) return json.repository;
|
|
362
|
+
} catch {
|
|
363
|
+
// noop
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
314
367
|
async function getPublic(args) {
|
|
315
368
|
let isPublic;
|
|
316
369
|
if (args['--public'] || args['--yes']) {
|
|
@@ -343,6 +396,7 @@ async function getReact(args) {
|
|
|
343
396
|
}
|
|
344
397
|
function adjustPackageJson(packageJson, {
|
|
345
398
|
name,
|
|
399
|
+
description,
|
|
346
400
|
react,
|
|
347
401
|
isPublic,
|
|
348
402
|
registry
|
|
@@ -351,6 +405,11 @@ function adjustPackageJson(packageJson, {
|
|
|
351
405
|
const packageParts = name.split('/');
|
|
352
406
|
const scope = packageParts[0].startsWith('@') ? packageParts[0] : undefined;
|
|
353
407
|
const finalRegistry = registry ?? 'https://registry.npmjs.org';
|
|
408
|
+
if (description) {
|
|
409
|
+
packageJson.description = description;
|
|
410
|
+
} else {
|
|
411
|
+
delete packageJson.description;
|
|
412
|
+
}
|
|
354
413
|
if (scope) {
|
|
355
414
|
packageJson.publishConfig[`${scope}/registry`] = finalRegistry;
|
|
356
415
|
} else if (registry) {
|
|
@@ -358,6 +417,8 @@ function adjustPackageJson(packageJson, {
|
|
|
358
417
|
}
|
|
359
418
|
if (isPublic) {
|
|
360
419
|
delete packageJson.private;
|
|
420
|
+
delete packageJson.license;
|
|
421
|
+
delete packageJson.repository;
|
|
361
422
|
} else {
|
|
362
423
|
delete packageJson.publishConfig;
|
|
363
424
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
+
var fs = require('node:fs');
|
|
3
4
|
var require$$0 = require('node:tty');
|
|
4
5
|
var index = require('../index.cjs');
|
|
5
|
-
var fs = require('node:fs');
|
|
6
6
|
var node_child_process = require('node:child_process');
|
|
7
7
|
var path = require('node:path');
|
|
8
8
|
var node_url = require('node:url');
|
|
@@ -43,12 +43,14 @@ function createPackageManagerRunner(type, {
|
|
|
43
43
|
},
|
|
44
44
|
async install() {
|
|
45
45
|
node_child_process.execSync(`${type} install`, {
|
|
46
|
-
cwd: root
|
|
46
|
+
cwd: root,
|
|
47
|
+
stdio: 'inherit'
|
|
47
48
|
});
|
|
48
49
|
},
|
|
49
50
|
async run(command, args) {
|
|
50
51
|
node_child_process.execSync(`${type} ${command} ${args.join(' ')}`, {
|
|
51
|
-
cwd: root
|
|
52
|
+
cwd: root,
|
|
53
|
+
stdio: 'inherit'
|
|
52
54
|
});
|
|
53
55
|
}
|
|
54
56
|
};
|
|
@@ -173,7 +175,8 @@ async function format(content, {
|
|
|
173
175
|
as: parser
|
|
174
176
|
}) {
|
|
175
177
|
const [{
|
|
176
|
-
format
|
|
178
|
+
format: rootFormat,
|
|
179
|
+
default: prettier
|
|
177
180
|
}, {
|
|
178
181
|
default: babel
|
|
179
182
|
}, {
|
|
@@ -181,6 +184,9 @@ async function format(content, {
|
|
|
181
184
|
}, {
|
|
182
185
|
default: yaml
|
|
183
186
|
}] = await Promise.all([Promise.resolve().then(function () { return require('../standalone.cjs'); }).then(function (n) { return n.standalone; }), Promise.resolve().then(function () { return require('../parser-babel.cjs'); }).then(function (n) { return n.parserBabel; }), Promise.resolve().then(function () { return require('../parser-typescript.cjs'); }).then(function (n) { return n.parserTypescript; }), Promise.resolve().then(function () { return require('../parser-yaml.cjs'); }).then(function (n) { return n.parserYaml; })]);
|
|
187
|
+
|
|
188
|
+
// CJS workaround
|
|
189
|
+
const format = rootFormat ?? prettier.format;
|
|
184
190
|
return format(content, {
|
|
185
191
|
arrowParens: 'always',
|
|
186
192
|
bracketSpacing: false,
|
|
@@ -201,6 +207,42 @@ function mergeDependencies(first = {}, second = {}) {
|
|
|
201
207
|
}
|
|
202
208
|
return merged;
|
|
203
209
|
}
|
|
210
|
+
const PACKAGE_JSON_DEPENDENCY_KEYS = new Set(['dependencies', 'devDependencies', 'peerDependencies', 'peerDependenciesMeta']);
|
|
211
|
+
|
|
212
|
+
// Merges a project and workspace package.json together, with the following nitpicky preferences:
|
|
213
|
+
//
|
|
214
|
+
// - Take all the project’s fields in the order they appear by default
|
|
215
|
+
// - Merge the relevant dependencies together
|
|
216
|
+
// - Projects don’t come with `scripts` by default, but that should go before the first dependency list
|
|
217
|
+
// - If there are other keys in the workspace package.json, they should go last, in the order they appeared
|
|
218
|
+
function mergeWorkspaceAndProjectPackageJsons(projectPackageJson, workspacePackageJson) {
|
|
219
|
+
const newPackageJson = {};
|
|
220
|
+
const seenKeys = new Set();
|
|
221
|
+
let hasHandledScriptsField = workspacePackageJson.scripts != null && projectPackageJson.scripts == null;
|
|
222
|
+
for (const [key, value] of Object.entries(projectPackageJson)) {
|
|
223
|
+
seenKeys.add(key);
|
|
224
|
+
const isDependencyKey = PACKAGE_JSON_DEPENDENCY_KEYS.has(key);
|
|
225
|
+
if (key === 'scripts' || isDependencyKey && !hasHandledScriptsField) {
|
|
226
|
+
newPackageJson.scripts = {
|
|
227
|
+
...workspacePackageJson.scripts,
|
|
228
|
+
...projectPackageJson.scripts
|
|
229
|
+
};
|
|
230
|
+
hasHandledScriptsField = true;
|
|
231
|
+
}
|
|
232
|
+
if (isDependencyKey) {
|
|
233
|
+
newPackageJson[key] = mergeDependencies(value, workspacePackageJson[key]);
|
|
234
|
+
} else {
|
|
235
|
+
newPackageJson[key] = value;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
for (const [key, value] of Object.entries(workspacePackageJson)) {
|
|
239
|
+
if (seenKeys.has(key)) continue;
|
|
240
|
+
// Merged workspace + project package.json means we are not in a monorepo
|
|
241
|
+
if (key === 'workspaces') continue;
|
|
242
|
+
newPackageJson[key] = value;
|
|
243
|
+
}
|
|
244
|
+
return newPackageJson;
|
|
245
|
+
}
|
|
204
246
|
|
|
205
247
|
var colorette = {};
|
|
206
248
|
|
|
@@ -418,7 +460,14 @@ colorette.whiteBright = whiteBright;
|
|
|
418
460
|
colorette.yellow = yellow;
|
|
419
461
|
colorette.yellowBright = yellowBright;
|
|
420
462
|
|
|
421
|
-
async function
|
|
463
|
+
async function getInWorkspace(argv) {
|
|
464
|
+
if (argv['--in-workspace']) return true;
|
|
465
|
+
if (argv['--not-in-workspace']) return false;
|
|
466
|
+
return fs__namespace.existsSync('quilt.workspace.ts');
|
|
467
|
+
}
|
|
468
|
+
async function getCreateAsMonorepo(argv, {
|
|
469
|
+
type
|
|
470
|
+
}) {
|
|
422
471
|
let createAsMonorepo;
|
|
423
472
|
if (argv['--monorepo' ]) {
|
|
424
473
|
createAsMonorepo = true;
|
|
@@ -427,13 +476,15 @@ async function getCreateAsMonorepo(argv) {
|
|
|
427
476
|
} else {
|
|
428
477
|
createAsMonorepo = await index.prompt({
|
|
429
478
|
type: 'confirm',
|
|
430
|
-
message:
|
|
479
|
+
message: `Do you want to create this ${type} as a monorepo, with room for more projects?`,
|
|
431
480
|
initial: true
|
|
432
481
|
});
|
|
433
482
|
}
|
|
434
483
|
return createAsMonorepo;
|
|
435
484
|
}
|
|
436
|
-
async function getShouldInstall(argv
|
|
485
|
+
async function getShouldInstall(argv, {
|
|
486
|
+
type
|
|
487
|
+
}) {
|
|
437
488
|
let shouldInstall;
|
|
438
489
|
if (argv['--install'] || argv['--yes']) {
|
|
439
490
|
shouldInstall = true;
|
|
@@ -442,7 +493,7 @@ async function getShouldInstall(argv) {
|
|
|
442
493
|
} else {
|
|
443
494
|
shouldInstall = await index.prompt({
|
|
444
495
|
type: 'confirm',
|
|
445
|
-
message:
|
|
496
|
+
message: `Do you want to install dependencies for this ${type} after creating it?`,
|
|
446
497
|
initial: true
|
|
447
498
|
});
|
|
448
499
|
}
|
|
@@ -602,12 +653,13 @@ exports.emptyDirectory = emptyDirectory;
|
|
|
602
653
|
exports.format = format;
|
|
603
654
|
exports.getCreateAsMonorepo = getCreateAsMonorepo;
|
|
604
655
|
exports.getExtrasToSetup = getExtrasToSetup;
|
|
656
|
+
exports.getInWorkspace = getInWorkspace;
|
|
605
657
|
exports.getPackageManager = getPackageManager;
|
|
606
658
|
exports.getShouldInstall = getShouldInstall;
|
|
607
659
|
exports.isEmpty = isEmpty;
|
|
608
660
|
exports.loadTemplate = loadTemplate;
|
|
609
661
|
exports.magenta_1 = magenta_1;
|
|
610
|
-
exports.
|
|
662
|
+
exports.mergeWorkspaceAndProjectPackageJsons = mergeWorkspaceAndProjectPackageJsons;
|
|
611
663
|
exports.relativeDirectoryForDisplay = relativeDirectoryForDisplay;
|
|
612
664
|
exports.toValidPackageName = toValidPackageName;
|
|
613
665
|
exports.underline_1 = underline_1;
|
package/build/esm/app.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
-
import { c as cyan_1, b as bold_1, g as
|
|
3
|
+
import { c as cyan_1, b as bold_1, g as getInWorkspace, a as getCreateAsMonorepo, d as getExtrasToSetup, e as getShouldInstall, f as getPackageManager, h as emptyDirectory, r as relativeDirectoryForDisplay, t as toValidPackageName, i as format, m as mergeWorkspaceAndProjectPackageJsons, l as loadTemplate, j as addToTsConfig, k as addToPackageManagerWorkspaces, n as dim_1, u as underline_1, o as magenta_1, p as isEmpty, q as createOutputTarget } from './shared/package-manager.mjs';
|
|
4
4
|
import { s as stripIndent, p as printHelp, a as prompt } from './index.mjs';
|
|
5
5
|
import 'node:tty';
|
|
6
6
|
import 'node:child_process';
|
|
@@ -222,7 +222,7 @@ async function createApp() {
|
|
|
222
222
|
});
|
|
223
223
|
return;
|
|
224
224
|
}
|
|
225
|
-
const inWorkspace =
|
|
225
|
+
const inWorkspace = await getInWorkspace(argv);
|
|
226
226
|
const name = await getName(argv, {
|
|
227
227
|
inWorkspace
|
|
228
228
|
});
|
|
@@ -230,14 +230,18 @@ async function createApp() {
|
|
|
230
230
|
name
|
|
231
231
|
});
|
|
232
232
|
const template = await getTemplate(argv);
|
|
233
|
-
const createAsMonorepo = !inWorkspace && (await getCreateAsMonorepo(argv
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
root: directory
|
|
237
|
-
});
|
|
233
|
+
const createAsMonorepo = !inWorkspace && (await getCreateAsMonorepo(argv, {
|
|
234
|
+
type: 'app'
|
|
235
|
+
}));
|
|
238
236
|
const setupExtras = await getExtrasToSetup(argv, {
|
|
239
237
|
inWorkspace
|
|
240
238
|
});
|
|
239
|
+
const shouldInstall = await getShouldInstall(argv, {
|
|
240
|
+
type: 'app'
|
|
241
|
+
});
|
|
242
|
+
const packageManager = await getPackageManager(argv, {
|
|
243
|
+
root: directory
|
|
244
|
+
});
|
|
241
245
|
const partOfMonorepo = inWorkspace || createAsMonorepo;
|
|
242
246
|
const appDirectory = createAsMonorepo ? path.join(directory, 'app') : directory;
|
|
243
247
|
if (fs.existsSync(directory)) {
|
|
@@ -271,33 +275,32 @@ async function createApp() {
|
|
|
271
275
|
// If we are creating a monorepo, we need to add the root package.json and
|
|
272
276
|
// package manager workspace configuration.
|
|
273
277
|
if (createAsMonorepo) {
|
|
278
|
+
const appRelativeToRoot = relativeDirectoryForDisplay(path.relative(directory, appDirectory));
|
|
274
279
|
const workspacePackageJson = JSON.parse(await workspaceTemplate.read('package.json'));
|
|
275
280
|
workspacePackageJson.name = toValidPackageName(name);
|
|
281
|
+
workspacePackageJson.workspaces = [appRelativeToRoot, './packages/*'];
|
|
276
282
|
if (packageManager.type === 'pnpm') {
|
|
277
283
|
await outputRoot.write('pnpm-workspace.yaml', await format(`
|
|
278
284
|
packages:
|
|
285
|
+
- '${appRelativeToRoot}'
|
|
279
286
|
- './packages/*'
|
|
280
287
|
`, {
|
|
281
288
|
as: 'yaml'
|
|
282
289
|
}));
|
|
283
|
-
} else {
|
|
284
|
-
workspacePackageJson.workspaces = ['packages/*'];
|
|
285
290
|
}
|
|
286
291
|
await outputRoot.write('package.json', await format(JSON.stringify(workspacePackageJson), {
|
|
287
292
|
as: 'json-stringify'
|
|
288
293
|
}));
|
|
289
294
|
} else {
|
|
290
295
|
const [projectPackageJson, projectTSConfig, workspacePackageJson] = await Promise.all([appTemplate.read('package.json').then(content => JSON.parse(content)), appTemplate.read('tsconfig.json').then(content => JSON.parse(content)), workspaceTemplate.read('package.json').then(content => JSON.parse(content))]);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
workspacePackageJson.browserslist = projectPackageJson.browserslist;
|
|
294
|
-
workspacePackageJson.devDependencies = mergeDependencies(workspacePackageJson.devDependencies, projectPackageJson.devDependencies);
|
|
296
|
+
const combinedPackageJson = mergeWorkspaceAndProjectPackageJsons(projectPackageJson, workspacePackageJson);
|
|
297
|
+
combinedPackageJson.name = toValidPackageName(name);
|
|
295
298
|
let quiltProject = await appTemplate.read('quilt.project.ts');
|
|
296
299
|
quiltProject = quiltProject.replace('quiltApp', 'quiltWorkspace, quiltApp').replace('quiltApp(', 'quiltWorkspace(), quiltApp(');
|
|
297
300
|
await outputRoot.write('quilt.project.ts', await format(quiltProject, {
|
|
298
301
|
as: 'typescript'
|
|
299
302
|
}));
|
|
300
|
-
await outputRoot.write('package.json', await format(JSON.stringify(
|
|
303
|
+
await outputRoot.write('package.json', await format(JSON.stringify(combinedPackageJson), {
|
|
301
304
|
as: 'json-stringify'
|
|
302
305
|
}));
|
|
303
306
|
await outputRoot.write('tsconfig.json', await format(JSON.stringify(projectTSConfig), {
|
|
@@ -330,12 +333,8 @@ async function createApp() {
|
|
|
330
333
|
await Promise.all([addToTsConfig(appDirectory, outputRoot), addToPackageManagerWorkspaces(appDirectory, outputRoot, packageManager.type)]);
|
|
331
334
|
}
|
|
332
335
|
if (shouldInstall) {
|
|
333
|
-
process.stdout.write('\nInstalling dependencies...\n');
|
|
334
336
|
// TODO: better loading, handle errors
|
|
335
337
|
await packageManager.install();
|
|
336
|
-
process.stdout.moveCursor(0, -1);
|
|
337
|
-
process.stdout.clearLine(1);
|
|
338
|
-
console.log('Installed dependencies.');
|
|
339
338
|
}
|
|
340
339
|
const commands = [];
|
|
341
340
|
if (!inWorkspace && directory !== process.cwd()) {
|
|
@@ -344,10 +343,6 @@ async function createApp() {
|
|
|
344
343
|
if (!shouldInstall) {
|
|
345
344
|
commands.push(`${packageManager.commands.install()} ${dim_1('# Install all your dependencies')}`);
|
|
346
345
|
}
|
|
347
|
-
if (!inWorkspace) {
|
|
348
|
-
// TODO: change this condition to check if git was initialized already
|
|
349
|
-
commands.push(`git init && git add -A && git commit -m "Initial commit" ${dim_1('# Start your git history (optional)')}`);
|
|
350
|
-
}
|
|
351
346
|
commands.push(`${packageManager.commands.run('develop')} ${dim_1('# Start the development server')}`);
|
|
352
347
|
const whatsNext = stripIndent`
|
|
353
348
|
Your new app is ready to go! There’s just ${commands.length > 1 ? 'a few more steps' : 'one more step'} you’ll need to take
|