@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.
@@ -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 useReact = await getReact(args);
64
- const createAsMonorepo = !inWorkspace && (await packageManager.getCreateAsMonorepo(args));
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 configuration as the base.
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
- - './packages/*'
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
- workspacePackageJson.eslintConfig = projectPackageJson.eslintConfig;
124
- workspacePackageJson.browserslist = projectPackageJson.browserslist;
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(newPackageJson), {
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), {
@@ -166,15 +174,36 @@ async function createProject() {
166
174
  return partOfMonorepo;
167
175
  }
168
176
 
169
- // We need to make some adjustments the project’s package.json and Quilt config
170
- return file !== 'package.json' && file !== 'quilt.project.ts';
177
+ // We need to make some adjustments the project’s package.json, README, and Quilt config
178
+ return file !== 'package.json' && file !== 'quilt.project.ts' && file !== 'README.md';
171
179
  });
180
+ await outputRoot.write(path__namespace.join(packageDirectory, 'package.json'), (await packageTemplate.read('README.md')).replaceAll('{{name}}', packageManager.toValidPackageName(name)));
172
181
  if (partOfMonorepo) {
173
182
  // Write the package’s package.json (the root one was already created)
174
183
  const projectPackageJson = JSON.parse(await packageTemplate.read('package.json'));
175
- projectPackageJson.repository.directory = path__namespace.relative(rootDirectory, packageDirectory);
184
+ if (repository === false) {
185
+ delete projectPackageJson.repository;
186
+ } else {
187
+ const directory = path__namespace.relative(rootDirectory, packageDirectory);
188
+ if (typeof repository === 'string') {
189
+ projectPackageJson.repository = {
190
+ type: 'git',
191
+ url: repository,
192
+ directory
193
+ };
194
+ } else if (repository != null) {
195
+ projectPackageJson.repository = {
196
+ type: 'git',
197
+ ...repository,
198
+ directory
199
+ };
200
+ } else {
201
+ projectPackageJson.repository.directory = directory;
202
+ }
203
+ }
176
204
  adjustPackageJson(projectPackageJson, {
177
205
  name: packageManager.toValidPackageName(name),
206
+ description,
178
207
  react: useReact,
179
208
  isPublic,
180
209
  registry: args['--registry']
@@ -186,45 +215,58 @@ async function createProject() {
186
215
  await Promise.all([packageManager.addToTsConfig(packageDirectory, outputRoot), packageManager.addToPackageManagerWorkspaces(packageDirectory, outputRoot, packageManager$1.type)]);
187
216
  }
188
217
  if (shouldInstall) {
189
- process.stdout.write('\nInstalling dependencies...\n');
218
+ console.log();
190
219
  // TODO: better loading, handle errors
191
220
  await packageManager$1.install();
192
- process.stdout.moveCursor(0, -1);
193
- process.stdout.clearLine(1);
194
- console.log('Installed dependencies.');
195
221
  }
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
222
  console.log();
207
- console.log(packageJsonInstructions);
208
- const commands = [];
209
- if (!inWorkspace && directory !== process.cwd()) {
210
- commands.push(`cd ${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), directory)))} ${index.dim_1('# Move into your new package’s directory')}`);
211
- }
212
- if (!shouldInstall) {
213
- commands.push(`${packageManager$1.commands.install()} ${index.dim_1('# Install all your dependencies')}`);
214
- }
215
- if (!inWorkspace) {
216
- // TODO: change this condition to check if git was initialized already
217
- commands.push(`git init && git add -A && git commit -m "Initial commit" ${index.dim_1('# Start your git history (optional)')}`);
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);
223
+ console.log(index.stripIndent`
224
+ Your new package, ${index.bold_1(name)}, is ready to go! You can edit the code
225
+ for your package in ${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'source'))))}.
226
+ `);
227
+ if (isPublic) {
228
+ const needsPackageJsonKeys = [];
229
+ if (!description) {
230
+ needsPackageJsonKeys.push({
231
+ field: 'description',
232
+ url: 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#description'
233
+ });
234
+ }
235
+ if (repository == null) {
236
+ needsPackageJsonKeys.push({
237
+ field: 'repository.url',
238
+ url: 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#repository'
239
+ });
240
+ }
226
241
  console.log();
227
- console.log(commands.map(command => ` ${command}`).join('\n'));
242
+ const logPackageJsonField = (field, url) => {
243
+ console.log(` ${index.bold_1(JSON.stringify(field))} ${index.dim_1(`(${index.underline_1(url)})`)}`);
244
+ };
245
+ if (needsPackageJsonKeys.length > 0) {
246
+ console.log(index.stripIndent`
247
+ Before you publish your package, you will need to add the following key${needsPackageJsonKeys.length > 1 ? 's' : ''}
248
+ to ${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'package.json'))))}:
249
+ `);
250
+ console.log();
251
+ for (const {
252
+ field,
253
+ url
254
+ } of needsPackageJsonKeys) {
255
+ logPackageJsonField(field, url);
256
+ }
257
+ console.log();
258
+ console.log('In that same file, make sure the contents of these fields are right for your package:');
259
+ console.log();
260
+ } else {
261
+ console.log(index.stripIndent`
262
+ Before you publish your package, make the following fields look right
263
+ in ${index.cyan_1(packageManager.relativeDirectoryForDisplay(path__namespace.relative(process.cwd(), path__namespace.join(packageDirectory, 'package.json'))))}:
264
+ `);
265
+ console.log();
266
+ }
267
+ logPackageJsonField('version', 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#version');
268
+ logPackageJsonField('license', 'https://docs.npmjs.com/cli/v9/configuring-npm/package-json#license');
269
+ logPackageJsonField('exports', 'https://nodejs.org/api/packages.html#package-entry-points');
228
270
  }
229
271
  const followUp = index.stripIndent`
230
272
  Quilt can help you build, test, lint, and type-check your new package. You
@@ -245,6 +287,10 @@ function getArguments() {
245
287
  '-y': '--yes',
246
288
  '--name': String,
247
289
  '--directory': String,
290
+ '--description': String,
291
+ '--no-description': Boolean,
292
+ '--repository': String,
293
+ '--no-repository': Boolean,
248
294
  '--install': Boolean,
249
295
  '--no-install': Boolean,
250
296
  '--monorepo': Boolean,
@@ -311,6 +357,36 @@ async function getDirectory(args, {
311
357
  }
312
358
  return directory;
313
359
  }
360
+ async function getDescription(args) {
361
+ if (args['--description']) return args['--description'];
362
+ if (args['--no-description']) return false;
363
+ const description = await index.prompt({
364
+ type: 'text',
365
+ message: 'What is a short description of what this package will do?'
366
+ });
367
+ return description;
368
+ }
369
+ async function getRepository(args, {
370
+ inWorkspace = false
371
+ } = {}) {
372
+ if (args['--repository']) return args['--repository'];
373
+ if (args['--no-repository']) return false;
374
+ if (!inWorkspace) return;
375
+ const {
376
+ globby
377
+ } = await Promise.resolve().then(function () { return require('./index4.cjs'); });
378
+ const files = await globby('**/package.json', {
379
+ ignore: ['**/node_modules']
380
+ });
381
+ for (const file of files) {
382
+ try {
383
+ const json = JSON.parse(await fs__namespace.promises.readFile(file, 'utf8'));
384
+ if (json.repository) return json.repository;
385
+ } catch {
386
+ // noop
387
+ }
388
+ }
389
+ }
314
390
  async function getPublic(args) {
315
391
  let isPublic;
316
392
  if (args['--public'] || args['--yes']) {
@@ -343,6 +419,7 @@ async function getReact(args) {
343
419
  }
344
420
  function adjustPackageJson(packageJson, {
345
421
  name,
422
+ description,
346
423
  react,
347
424
  isPublic,
348
425
  registry
@@ -351,6 +428,11 @@ function adjustPackageJson(packageJson, {
351
428
  const packageParts = name.split('/');
352
429
  const scope = packageParts[0].startsWith('@') ? packageParts[0] : undefined;
353
430
  const finalRegistry = registry ?? 'https://registry.npmjs.org';
431
+ if (description) {
432
+ packageJson.description = description;
433
+ } else {
434
+ delete packageJson.description;
435
+ }
354
436
  if (scope) {
355
437
  packageJson.publishConfig[`${scope}/registry`] = finalRegistry;
356
438
  } else if (registry) {
@@ -359,7 +441,22 @@ function adjustPackageJson(packageJson, {
359
441
  if (isPublic) {
360
442
  delete packageJson.private;
361
443
  } else {
444
+ delete packageJson.license;
445
+ delete packageJson.repository;
362
446
  delete packageJson.publishConfig;
447
+
448
+ // in private packages, we just need to reference the source.
449
+ const newExports = {};
450
+ for (const [key, value] of Object.entries(packageJson.exports)) {
451
+ if (typeof value === 'string') {
452
+ newExports[key] = value;
453
+ }
454
+ const sourceEntry = value?.['quilt:source'];
455
+ if (typeof sourceEntry === 'string') {
456
+ newExports[key] = sourceEntry;
457
+ }
458
+ }
459
+ packageJson.exports = newExports;
363
460
  }
364
461
  if (!react) {
365
462
  delete packageJson.dependencies['@types/react'];
@@ -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');
@@ -175,7 +175,8 @@ async function format(content, {
175
175
  as: parser
176
176
  }) {
177
177
  const [{
178
- format
178
+ format: rootFormat,
179
+ default: prettier
179
180
  }, {
180
181
  default: babel
181
182
  }, {
@@ -183,6 +184,9 @@ async function format(content, {
183
184
  }, {
184
185
  default: yaml
185
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;
186
190
  return format(content, {
187
191
  arrowParens: 'always',
188
192
  bracketSpacing: false,
@@ -203,6 +207,42 @@ function mergeDependencies(first = {}, second = {}) {
203
207
  }
204
208
  return merged;
205
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 = false;
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
+ }
206
246
 
207
247
  var colorette = {};
208
248
 
@@ -420,7 +460,14 @@ colorette.whiteBright = whiteBright;
420
460
  colorette.yellow = yellow;
421
461
  colorette.yellowBright = yellowBright;
422
462
 
423
- async function getCreateAsMonorepo(argv) {
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
+ }) {
424
471
  let createAsMonorepo;
425
472
  if (argv['--monorepo' ]) {
426
473
  createAsMonorepo = true;
@@ -429,13 +476,15 @@ async function getCreateAsMonorepo(argv) {
429
476
  } else {
430
477
  createAsMonorepo = await index.prompt({
431
478
  type: 'confirm',
432
- message: 'Do you want to create this app as a monorepo, with room for more projects?',
479
+ message: `Do you want to create this ${type} as a monorepo, with room for more projects?`,
433
480
  initial: true
434
481
  });
435
482
  }
436
483
  return createAsMonorepo;
437
484
  }
438
- async function getShouldInstall(argv) {
485
+ async function getShouldInstall(argv, {
486
+ type
487
+ }) {
439
488
  let shouldInstall;
440
489
  if (argv['--install'] || argv['--yes']) {
441
490
  shouldInstall = true;
@@ -444,7 +493,7 @@ async function getShouldInstall(argv) {
444
493
  } else {
445
494
  shouldInstall = await index.prompt({
446
495
  type: 'confirm',
447
- message: 'Do you want to install dependencies for this app after creating it?',
496
+ message: `Do you want to install dependencies for this ${type} after creating it?`,
448
497
  initial: true
449
498
  });
450
499
  }
@@ -604,12 +653,13 @@ exports.emptyDirectory = emptyDirectory;
604
653
  exports.format = format;
605
654
  exports.getCreateAsMonorepo = getCreateAsMonorepo;
606
655
  exports.getExtrasToSetup = getExtrasToSetup;
656
+ exports.getInWorkspace = getInWorkspace;
607
657
  exports.getPackageManager = getPackageManager;
608
658
  exports.getShouldInstall = getShouldInstall;
609
659
  exports.isEmpty = isEmpty;
610
660
  exports.loadTemplate = loadTemplate;
611
661
  exports.magenta_1 = magenta_1;
612
- exports.mergeDependencies = mergeDependencies;
662
+ exports.mergeWorkspaceAndProjectPackageJsons = mergeWorkspaceAndProjectPackageJsons;
613
663
  exports.relativeDirectoryForDisplay = relativeDirectoryForDisplay;
614
664
  exports.toValidPackageName = toValidPackageName;
615
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 getCreateAsMonorepo, a as getShouldInstall, d as getPackageManager, e as getExtrasToSetup, f as emptyDirectory, t as toValidPackageName, h as format, m as mergeDependencies, l as loadTemplate, i as addToTsConfig, j as addToPackageManagerWorkspaces, r as relativeDirectoryForDisplay, k as dim_1, u as underline_1, n as magenta_1, o as isEmpty, p as createOutputTarget } from './shared/package-manager.mjs';
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 = fs.existsSync('quilt.workspace.ts');
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
- const shouldInstall = await getShouldInstall(argv);
235
- const packageManager = await getPackageManager(argv, {
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
- workspacePackageJson.name = toValidPackageName(name);
292
- workspacePackageJson.eslintConfig = projectPackageJson.eslintConfig;
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(workspacePackageJson), {
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,9 @@ 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');
336
+ console.log();
334
337
  // TODO: better loading, handle errors
335
338
  await packageManager.install();
336
- process.stdout.moveCursor(0, -1);
337
- process.stdout.clearLine(1);
338
- console.log('Installed dependencies.');
339
339
  }
340
340
  const commands = [];
341
341
  if (!inWorkspace && directory !== process.cwd()) {
@@ -344,10 +344,6 @@ async function createApp() {
344
344
  if (!shouldInstall) {
345
345
  commands.push(`${packageManager.commands.install()} ${dim_1('# Install all your dependencies')}`);
346
346
  }
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
347
  commands.push(`${packageManager.commands.run('develop')} ${dim_1('# Start the development server')}`);
352
348
  const whatsNext = stripIndent`
353
349
  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