@quilted/create 0.1.67 → 0.1.69

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/build/cjs/_virtual/estree.cjs +5 -0
  3. package/build/cjs/cli.cjs +14 -3
  4. package/build/cjs/module.cjs +1 -1
  5. package/build/cjs/node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.cjs +2 -2
  6. package/build/cjs/node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/estree.cjs +70 -0
  7. package/build/cjs/packages/cli-kit/source/prompt.cjs +2 -2
  8. package/build/cjs/packages/events/source/{abort.cjs → abort/AbortError.cjs} +6 -0
  9. package/build/cjs/service.cjs +298 -0
  10. package/build/cjs/shared.cjs +4 -8
  11. package/build/esm/_virtual/estree.mjs +3 -0
  12. package/build/esm/app.mjs +2 -2
  13. package/build/esm/cli.mjs +15 -4
  14. package/build/esm/module.mjs +4 -4
  15. package/build/esm/node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.mjs +2 -2
  16. package/build/esm/node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/estree.mjs +65 -0
  17. package/build/esm/package.mjs +2 -2
  18. package/build/esm/packages/cli-kit/source/prompt.mjs +1 -1
  19. package/build/esm/packages/events/source/{abort.mjs → abort/AbortError.mjs} +6 -0
  20. package/build/esm/service.mjs +276 -0
  21. package/build/esm/shared.mjs +4 -8
  22. package/build/esnext/_virtual/estree.esnext +3 -0
  23. package/build/esnext/module.esnext +2 -2
  24. package/build/esnext/node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/estree.esnext +65 -0
  25. package/build/esnext/packages/cli-kit/source/prompt.esnext +1 -1
  26. package/build/esnext/packages/events/source/{abort.esnext → abort/AbortError.esnext} +6 -0
  27. package/build/esnext/shared.esnext +4 -8
  28. package/build/tsconfig.tsbuildinfo +1 -1
  29. package/build/typescript/help.d.ts +1 -1
  30. package/build/typescript/help.d.ts.map +1 -1
  31. package/build/typescript/service.d.ts +2 -0
  32. package/build/typescript/service.d.ts.map +1 -0
  33. package/build/typescript/shared/prompts.d.ts +1 -1
  34. package/build/typescript/shared/prompts.d.ts.map +1 -1
  35. package/build/typescript/shared.d.ts +1 -1
  36. package/build/typescript/shared.d.ts.map +1 -1
  37. package/package.json +1 -1
  38. package/source/cli.ts +7 -1
  39. package/source/help.ts +1 -1
  40. package/source/module.ts +1 -1
  41. package/source/service.ts +388 -0
  42. package/source/shared/prompts.ts +1 -1
  43. package/source/shared.ts +12 -7
  44. package/templates/app-basic/features/Start/Start.test.tsx +2 -2
  45. package/templates/{app-trpc/tests → app-basic/tests/render}/render.tsx +3 -34
  46. package/templates/app-basic/tests/render/types.ts +29 -0
  47. package/templates/app-basic/tests/render.ts +6 -0
  48. package/templates/app-graphql/features/Start/Start.test.tsx +3 -3
  49. package/templates/app-graphql/tests/render/render.tsx +59 -0
  50. package/templates/app-graphql/tests/render/types.ts +63 -0
  51. package/templates/app-graphql/tests/render.ts +7 -0
  52. package/templates/app-trpc/App.tsx +32 -2
  53. package/templates/{app-basic/tests → app-trpc/tests/render}/render.tsx +12 -37
  54. package/templates/app-trpc/tests/render/types.ts +35 -0
  55. package/templates/app-trpc/tests/render.ts +6 -0
  56. package/templates/service-basic/package.json +12 -0
  57. package/templates/service-basic/quilt.project.ts +9 -0
  58. package/templates/service-basic/service.ts +7 -0
  59. package/templates/service-basic/tsconfig.json +9 -0
  60. package/templates/app-graphql/tests/render.tsx +0 -126
@@ -20,7 +20,7 @@ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLi
20
20
  import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/inlineLists/inlineLists.mjs';
21
21
  import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLineInlineLists/oneLineInlineLists.mjs';
22
22
  import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/stripIndents/stripIndents.mjs';
23
- import parseArguments from './node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.mjs';
23
+ import arg from './node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.mjs';
24
24
  import { prompt } from './packages/cli-kit/source/prompt.mjs';
25
25
  import { cyan as cyan_1, dim as dim_1, bold as bold_1, underline as underline_1, magenta as magenta_1 } from './node_modules/.pnpm/colorette@2.0.19/node_modules/colorette/index.mjs';
26
26
 
@@ -276,7 +276,7 @@ async function createProject() {
276
276
  // Argument handling
277
277
 
278
278
  function getArguments() {
279
- const args = parseArguments({
279
+ const args = arg({
280
280
  '--yes': Boolean,
281
281
  '-y': '--yes',
282
282
  '--name': String,
@@ -1,5 +1,5 @@
1
1
  import prompts from '../../../node_modules/.pnpm/prompts@2.4.2/node_modules/prompts/index.mjs';
2
- import { AbortError } from '../../events/source/abort.mjs';
2
+ import { AbortError } from '../../events/source/abort/AbortError.mjs';
3
3
 
4
4
  async function prompt(prompt) {
5
5
  const result = await prompts({
@@ -1,4 +1,10 @@
1
1
  // @see https://github.com/nodejs/node/blob/master/lib/internal/errors.js#L822-L834
2
+ /**
3
+ * An `Error` that indicates that an operation was aborted before
4
+ * it finished.
5
+ *
6
+ * @see https://github.com/nodejs/node/blob/5c65565108c626884c5c722bb512c7c1e5c1c809/lib/internal/errors.js#L843-L855
7
+ */
2
8
  class AbortError extends Error {
3
9
  static test(error) {
4
10
  return error != null && error.code === 'ABORT_ERR';
@@ -0,0 +1,276 @@
1
+ import * as fs from 'node:fs';
2
+ import * as path from 'node:path';
3
+ import arg from './node_modules/.pnpm/arg@5.0.2/node_modules/arg/index.mjs';
4
+ import { cyan as cyan_1, dim as dim_1, underline as underline_1, magenta as magenta_1, bold as bold_1 } from './node_modules/.pnpm/colorette@2.0.19/node_modules/colorette/index.mjs';
5
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/TemplateTag/TemplateTag.mjs';
6
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/commaLists/commaLists.mjs';
7
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/commaListsAnd/commaListsAnd.mjs';
8
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/commaListsOr/commaListsOr.mjs';
9
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/html/html.mjs';
10
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/safeHtml/safeHtml.mjs';
11
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLine/oneLine.mjs';
12
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLineTrim/oneLineTrim.mjs';
13
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLineCommaLists/oneLineCommaLists.mjs';
14
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLineCommaListsOr/oneLineCommaListsOr.mjs';
15
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLineCommaListsAnd/oneLineCommaListsAnd.mjs';
16
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/inlineLists/inlineLists.mjs';
17
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLineInlineLists/oneLineInlineLists.mjs';
18
+ import stripIndent from './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/stripIndent/stripIndent.mjs';
19
+ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/stripIndents/stripIndents.mjs';
20
+ import { printHelp } from './help.mjs';
21
+ import { toValidPackageName, emptyDirectory, relativeDirectoryForDisplay, format, mergeWorkspaceAndProjectPackageJsons, loadTemplate, isEmpty, createOutputTarget } from './shared.mjs';
22
+ import { getInWorkspace, getCreateAsMonorepo, getExtrasToSetup, getShouldInstall, getPackageManager } from './shared/prompts.mjs';
23
+ import { addToTsConfig } from './shared/tsconfig.mjs';
24
+ import { addToPackageManagerWorkspaces } from './shared/package-manager.mjs';
25
+ import { prompt } from './packages/cli-kit/source/prompt.mjs';
26
+
27
+ async function createService() {
28
+ const argv = getArgv();
29
+ if (argv['--help']) {
30
+ printHelp({
31
+ kind: 'service',
32
+ packageManager: argv['--package-manager']?.toLowerCase()
33
+ });
34
+ return;
35
+ }
36
+ const inWorkspace = await getInWorkspace(argv);
37
+ const name = await getName(argv);
38
+ const directory = await getDirectory(argv, {
39
+ name
40
+ });
41
+ const entry = await getEntry(argv, {
42
+ name
43
+ });
44
+ const createAsMonorepo = !inWorkspace && (await getCreateAsMonorepo(argv, {
45
+ type: 'service',
46
+ default: false
47
+ }));
48
+ const setupExtras = await getExtrasToSetup(argv, {
49
+ inWorkspace
50
+ });
51
+ const shouldInstall = await getShouldInstall(argv);
52
+ const packageManager = await getPackageManager(argv, {
53
+ root: directory
54
+ });
55
+ const partOfMonorepo = inWorkspace || createAsMonorepo;
56
+ const serviceDirectory = createAsMonorepo ? path.join(directory, toValidPackageName(name)) : directory;
57
+ if (fs.existsSync(directory)) {
58
+ await emptyDirectory(directory);
59
+ if (serviceDirectory !== directory) {
60
+ fs.mkdirSync(serviceDirectory, {
61
+ recursive: true
62
+ });
63
+ }
64
+ } else {
65
+ fs.mkdirSync(serviceDirectory, {
66
+ recursive: true
67
+ });
68
+ }
69
+ const rootDirectory = inWorkspace ? process.cwd() : directory;
70
+ const outputRoot = createOutputTarget(rootDirectory);
71
+ const serviceTemplate = loadTemplate('service-basic');
72
+ const workspaceTemplate = loadTemplate('workspace');
73
+
74
+ // If we aren’t already in a workspace, copy the workspace files over, which
75
+ // are needed if we are making a monorepo or not.
76
+ if (!inWorkspace) {
77
+ await workspaceTemplate.copy(directory, file => {
78
+ // When this is a single project, we use the project’s Quilt configuration as the base.
79
+ if (file === 'quilt.workspace.ts') return createAsMonorepo;
80
+
81
+ // We need to make some adjustments to the root package.json
82
+ if (file === 'package.json') return false;
83
+ return true;
84
+ });
85
+
86
+ // If we are creating a monorepo, we need to add the root package.json and
87
+ // package manager workspace configuration.
88
+ if (createAsMonorepo) {
89
+ const serviceRelativeToRoot = relativeDirectoryForDisplay(path.relative(directory, serviceDirectory));
90
+ const workspacePackageJson = JSON.parse(await workspaceTemplate.read('package.json'));
91
+ workspacePackageJson.name = toValidPackageName(name);
92
+ workspacePackageJson.workspaces = [serviceRelativeToRoot, './packages/*'];
93
+ if (packageManager.type === 'pnpm') {
94
+ await outputRoot.write('pnpm-workspace.yaml', await format(`
95
+ packages:
96
+ - '${serviceRelativeToRoot}'
97
+ - './packages/*'
98
+ `, {
99
+ as: 'yaml'
100
+ }));
101
+ }
102
+ await outputRoot.write('package.json', await format(JSON.stringify(workspacePackageJson), {
103
+ as: 'json-stringify'
104
+ }));
105
+ } else {
106
+ const [projectPackageJson, projectTSConfig, workspacePackageJson] = await Promise.all([serviceTemplate.read('package.json').then(content => JSON.parse(content)), serviceTemplate.read('tsconfig.json').then(content => JSON.parse(content)), workspaceTemplate.read('package.json').then(content => JSON.parse(content))]);
107
+ const combinedPackageJson = mergeWorkspaceAndProjectPackageJsons(projectPackageJson, workspacePackageJson);
108
+ adjustPackageJson(combinedPackageJson, {
109
+ name,
110
+ entry
111
+ });
112
+ delete combinedPackageJson.workspaces;
113
+ let quiltProject = await serviceTemplate.read('quilt.project.ts');
114
+ quiltProject = quiltProject.replace('quiltService', 'quiltWorkspace, quiltService').replace('quiltService(', 'quiltWorkspace(), quiltService(').replace('service.ts', entry.replace(/^\.[/]/, ''));
115
+ await outputRoot.write('quilt.project.ts', await format(quiltProject, {
116
+ as: 'typescript'
117
+ }));
118
+ await outputRoot.write('package.json', await format(JSON.stringify(combinedPackageJson), {
119
+ as: 'json-stringify'
120
+ }));
121
+ await outputRoot.write('tsconfig.json', await format(JSON.stringify(projectTSConfig), {
122
+ as: 'json'
123
+ }));
124
+ }
125
+ if (setupExtras.has('github')) {
126
+ await loadTemplate('github').copy(directory);
127
+ }
128
+ if (setupExtras.has('vscode')) {
129
+ await loadTemplate('vscode').copy(directory);
130
+ }
131
+ }
132
+ await serviceTemplate.copy(serviceDirectory, file => {
133
+ // If we are in a monorepo, we can use all the template files as they are
134
+ if (file === 'tsconfig.json') {
135
+ return partOfMonorepo;
136
+ }
137
+
138
+ // We will adjust the entry file and quilt project file
139
+ if (file === 'service.ts' || file === 'quilt.project.ts') {
140
+ return false;
141
+ }
142
+
143
+ // We need to make some adjustments the project’s package.json
144
+ return file !== 'package.json';
145
+ });
146
+ await outputRoot.write(path.join(serviceDirectory, entry), await serviceTemplate.read('service.ts'));
147
+ let quiltProject = await serviceTemplate.read('quilt.project.ts');
148
+ quiltProject = quiltProject.replace('service.ts', entry.replace(/^\.[/]/, ''));
149
+ await outputRoot.write(path.join(serviceDirectory, 'quilt.project.ts'), await format(quiltProject, {
150
+ as: 'typescript'
151
+ }));
152
+ if (partOfMonorepo) {
153
+ // Write the app’s package.json (the root one was already created)
154
+ const projectPackageJson = JSON.parse(await serviceTemplate.read('package.json'));
155
+ adjustPackageJson(projectPackageJson, {
156
+ name,
157
+ entry
158
+ });
159
+ await outputRoot.write(path.join(serviceDirectory, 'package.json'), await format(JSON.stringify(projectPackageJson), {
160
+ as: 'json-stringify'
161
+ }));
162
+ await Promise.all([addToTsConfig(serviceDirectory, outputRoot), addToPackageManagerWorkspaces(serviceDirectory, outputRoot, packageManager.type)]);
163
+ }
164
+ if (shouldInstall) {
165
+ console.log();
166
+ // TODO: better loading, handle errors
167
+ await packageManager.install();
168
+ }
169
+ const commands = [];
170
+ if (!inWorkspace && directory !== process.cwd()) {
171
+ commands.push(`cd ${cyan_1(relativeDirectoryForDisplay(path.relative(process.cwd(), directory)))} ${dim_1('# Move into your new service’s directory')}`);
172
+ }
173
+ if (!shouldInstall) {
174
+ commands.push(`${packageManager.commands.install()} ${dim_1('# Install all your dependencies')}`);
175
+ }
176
+ if (commands.length === 0) {
177
+ console.log();
178
+ console.log('Your new service is ready to go!');
179
+ } else {
180
+ const whatsNext = stripIndent`
181
+ Your new service is ready to go! There’s just ${commands.length > 1 ? 'a few more steps' : 'one more step'} you’ll need to take
182
+ in order to start developing:
183
+ `;
184
+ console.log();
185
+ console.log(whatsNext);
186
+ console.log();
187
+ console.log(commands.map(command => ` ${command}`).join('\n'));
188
+ }
189
+ const followUp = stripIndent`
190
+ Quilt can also help you build, develop, test, lint, and type-check your new service.
191
+ You can learn more about building services with Quilt by reading the documentation:
192
+ ${underline_1(magenta_1('https://github.com/lemonmade/quilt/tree/main/documentation'))}
193
+
194
+ Have fun! 🎉
195
+ `;
196
+ console.log();
197
+ console.log(followUp);
198
+ }
199
+
200
+ // Argument handling
201
+
202
+ function getArgv() {
203
+ const argv = arg({
204
+ '--yes': Boolean,
205
+ '-y': '--yes',
206
+ '--name': String,
207
+ '--directory': String,
208
+ '--entry': String,
209
+ '--install': Boolean,
210
+ '--no-install': Boolean,
211
+ '--monorepo': Boolean,
212
+ '--no-monorepo': Boolean,
213
+ '--package-manager': String,
214
+ '--extras': [String],
215
+ '--no-extras': Boolean,
216
+ '--help': Boolean,
217
+ '-h': '--help'
218
+ }, {
219
+ permissive: true
220
+ });
221
+ return argv;
222
+ }
223
+ async function getName(argv) {
224
+ let {
225
+ '--name': name
226
+ } = argv;
227
+ if (name == null) {
228
+ name = await prompt({
229
+ type: 'text',
230
+ message: 'What would you like to name your new service?',
231
+ initial: 'my-service'
232
+ });
233
+ }
234
+ return name;
235
+ }
236
+ async function getEntry(argv, {
237
+ name
238
+ }) {
239
+ if (argv['--entry']) {
240
+ return argv['--entry'];
241
+ }
242
+ return `${toValidPackageName(name)}.ts`;
243
+ }
244
+ async function getDirectory(argv, {
245
+ name
246
+ }) {
247
+ let directory = path.resolve(argv['--directory'] ?? toValidPackageName(name));
248
+ while (!argv['--yes']) {
249
+ if (fs.existsSync(directory) && !(await isEmpty(directory))) {
250
+ const relativeDirectory = path.relative(process.cwd(), directory);
251
+ const empty = await prompt({
252
+ type: 'confirm',
253
+ message: `Directory ${bold_1(relativeDirectoryForDisplay(relativeDirectory))} is not empty, is it safe to empty it?`,
254
+ initial: true
255
+ });
256
+ if (empty) break;
257
+ const promptDirectory = await prompt({
258
+ type: 'text',
259
+ message: 'What directory do you want to create your new service in?'
260
+ });
261
+ directory = path.resolve(promptDirectory);
262
+ } else {
263
+ break;
264
+ }
265
+ }
266
+ return directory;
267
+ }
268
+ function adjustPackageJson(packageJson, {
269
+ name
270
+ }) {
271
+ packageJson.name = name;
272
+ packageJson.main = `./build/runtime/runtime.js`;
273
+ return packageJson;
274
+ }
275
+
276
+ export { createService };
@@ -106,13 +106,9 @@ async function format(content, {
106
106
  const [{
107
107
  format: rootFormat,
108
108
  default: prettier
109
- }, {
110
- default: babel
111
- }, {
112
- default: typescript
113
- }, {
114
- default: yaml
115
- }] = await Promise.all([import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/standalone.mjs').then(function (n) { return n.s; }), import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/babel.mjs').then(function (n) { return n.b; }), import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/typescript.mjs').then(function (n) { return n.t; }), import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/yaml.mjs').then(function (n) { return n.y; })]);
109
+ }, babel, typescript, yaml, estree] = await Promise.all([import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/standalone.mjs').then(function (n) { return n.s; }), import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/babel.mjs').then(function (n) { return n.b; }), import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/typescript.mjs').then(function (n) { return n.t; }), import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/yaml.mjs').then(function (n) { return n.y; }),
110
+ // @ts-expect-error Types are not generated correctly for this entry
111
+ import('./node_modules/.pnpm/prettier@3.0.0/node_modules/prettier/plugins/estree.mjs').then(function (n) { return n.e; })]);
116
112
 
117
113
  // CJS workaround
118
114
  const format = rootFormat ?? prettier.format;
@@ -122,7 +118,7 @@ async function format(content, {
122
118
  singleQuote: true,
123
119
  trailingComma: 'all',
124
120
  parser,
125
- plugins: [babel, typescript, yaml]
121
+ plugins: [babel, typescript, yaml, estree]
126
122
  });
127
123
  }
128
124
  function mergeDependencies(first = {}, second = {}) {
@@ -0,0 +1,3 @@
1
+ var estree = {exports: {}};
2
+
3
+ export { estree as __module };
@@ -18,7 +18,7 @@ import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/oneLi
18
18
  import stripIndent from './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/stripIndent/stripIndent.esnext';
19
19
  import './node_modules/.pnpm/common-tags@1.8.2/node_modules/common-tags/es/stripIndents/stripIndents.esnext';
20
20
  import { printHelp } from './help.esnext';
21
- import { emptyDirectory, relativeDirectoryForDisplay, toValidPackageName, format, mergeWorkspaceAndProjectPackageJsons, loadTemplate, isEmpty, createOutputTarget } from './shared.esnext';
21
+ import { toValidPackageName, emptyDirectory, relativeDirectoryForDisplay, format, mergeWorkspaceAndProjectPackageJsons, loadTemplate, isEmpty, createOutputTarget } from './shared.esnext';
22
22
  import { getInWorkspace, getCreateAsMonorepo, getExtrasToSetup, getShouldInstall, getPackageManager } from './shared/prompts.esnext';
23
23
  import { addToTsConfig } from './shared/tsconfig.esnext';
24
24
  import { addToPackageManagerWorkspaces } from './shared/package-manager.esnext';
@@ -54,7 +54,7 @@ async function createModule() {
54
54
  root: directory
55
55
  });
56
56
  const partOfMonorepo = inWorkspace || createAsMonorepo;
57
- const moduleDirectory = createAsMonorepo ? path.join(directory, 'app') : directory;
57
+ const moduleDirectory = createAsMonorepo ? path.join(directory, toValidPackageName(name)) : directory;
58
58
  if (fs.existsSync(directory)) {
59
59
  await emptyDirectory(directory);
60
60
  if (moduleDirectory !== directory) {