@shopify/create-app 3.58.2 → 3.59.0

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 (74) hide show
  1. package/dist/chunk-3JLUTHGR.js +114 -0
  2. package/dist/chunk-3JNB3A7C.js +14080 -0
  3. package/dist/chunk-4DXNY52K.js +104 -0
  4. package/dist/chunk-4SXWHRL5.js +62 -0
  5. package/dist/chunk-5RH4B5Q7.js +30996 -0
  6. package/dist/chunk-7XQTD3L4.js +213522 -0
  7. package/dist/chunk-ADG25CKO.js +2468 -0
  8. package/dist/chunk-ASLSMEKR.js +18914 -0
  9. package/dist/chunk-BOIUUJSH.js +99 -0
  10. package/dist/chunk-CKY5L2DS.js +37 -0
  11. package/dist/chunk-CPDHSAO5.js +3179 -0
  12. package/dist/chunk-FBB6KUZG.js +821 -0
  13. package/dist/chunk-G6FN5VUE.js +102 -0
  14. package/dist/chunk-GXPKATXW.js +194 -0
  15. package/dist/chunk-H7CRO63U.js +11 -0
  16. package/dist/chunk-JP7Y3CTL.js +72 -0
  17. package/dist/chunk-LKGDG6WW.js +87 -0
  18. package/dist/chunk-M63RTPGR.js +63 -0
  19. package/dist/chunk-ND5WSAZY.js +7817 -0
  20. package/dist/chunk-P4TVG45N.js +900 -0
  21. package/dist/chunk-TMGCRPEZ.js +4283 -0
  22. package/dist/chunk-UVY6LL5H.js +145 -0
  23. package/dist/chunk-VMPTLMJN.js +144 -0
  24. package/dist/chunk-WCNR75S2.js +73 -0
  25. package/dist/chunk-WLJ2CNLG.js +45349 -0
  26. package/dist/chunk-YLEF4RUH.js +144 -0
  27. package/dist/chunk-ZDCQCTOO.js +13764 -0
  28. package/dist/chunk-ZPB26OWQ.js +5605 -0
  29. package/dist/commands/init.d.ts +2 -1
  30. package/dist/commands/init.js +31 -123
  31. package/dist/commands/init.js.map +1 -1
  32. package/dist/commands/init.test.js +123 -0
  33. package/dist/constants-K3R4N3N3.js +19 -0
  34. package/dist/custom-oclif-loader-GA6B7DEF.js +83 -0
  35. package/dist/del-A5YM6R3Y.js +2846 -0
  36. package/dist/devtools-KQM4GF6J.js +3685 -0
  37. package/dist/error-handler-U53E7YKG.js +34 -0
  38. package/dist/hooks/postrun.js +108 -2
  39. package/dist/hooks/prerun.js +77 -2
  40. package/dist/index.js +22 -7
  41. package/dist/lib-76JUGQYQ.js +8 -0
  42. package/dist/local-XVLEGQFE.js +59 -0
  43. package/dist/magic-string.es-6WMSFIAX.js +1291 -0
  44. package/dist/multipart-parser-O2BQODS2.js +359 -0
  45. package/dist/node-package-manager-76YAD3UB.js +68 -0
  46. package/dist/open-B7XFJJCK.js +290 -0
  47. package/dist/out-JZ52TJE3.js +5 -0
  48. package/dist/path-HO4HBKK5.js +28 -0
  49. package/dist/prompts/init.d.ts +4 -3
  50. package/dist/prompts/init.js +23 -118
  51. package/dist/prompts/init.js.map +1 -1
  52. package/dist/prompts/init.test.js +115 -0
  53. package/dist/services/init.d.ts +3 -1
  54. package/dist/services/init.js +25 -139
  55. package/dist/services/init.js.map +1 -1
  56. package/dist/services/init.test.js +18 -0
  57. package/dist/system-XBDENYNR.js +25 -0
  58. package/dist/tsconfig.tsbuildinfo +1 -1
  59. package/dist/ui-ZVCYWXG6.js +49 -0
  60. package/dist/utils/template/cleanup.js +18 -19
  61. package/dist/utils/template/cleanup.test.js +74 -0
  62. package/dist/utils/template/npm.d.ts +2 -1
  63. package/dist/utils/template/npm.js +22 -58
  64. package/dist/utils/template/npm.js.map +1 -1
  65. package/dist/utils/template/npm.test.js +153 -0
  66. package/dist/yoga.wasm +0 -0
  67. package/oclif.manifest.json +1 -1
  68. package/package.json +5 -6
  69. package/dist/constants.d.ts +0 -1
  70. package/dist/constants.js +0 -2
  71. package/dist/constants.js.map +0 -1
  72. package/dist/utils/versions.d.ts +0 -1
  73. package/dist/utils/versions.js +0 -21
  74. package/dist/utils/versions.js.map +0 -1
@@ -0,0 +1,5 @@
1
+ import {
2
+ require_out
3
+ } from "./chunk-ZPB26OWQ.js";
4
+ import "./chunk-M63RTPGR.js";
5
+ export default require_out();
@@ -0,0 +1,28 @@
1
+ import {
2
+ basename,
3
+ cwd,
4
+ dirname,
5
+ extname,
6
+ isAbsolutePath,
7
+ joinPath,
8
+ moduleDirectory,
9
+ normalizePath,
10
+ relativePath,
11
+ relativizePath,
12
+ resolvePath
13
+ } from "./chunk-G6FN5VUE.js";
14
+ import "./chunk-GXPKATXW.js";
15
+ import "./chunk-M63RTPGR.js";
16
+ export {
17
+ basename,
18
+ cwd,
19
+ dirname,
20
+ extname,
21
+ isAbsolutePath,
22
+ joinPath,
23
+ moduleDirectory,
24
+ normalizePath,
25
+ relativePath,
26
+ relativizePath,
27
+ resolvePath
28
+ };
@@ -1,4 +1,5 @@
1
- interface InitOptions {
1
+ import { InstallGlobalCLIPromptResult } from '@shopify/cli-kit/node/is-global';
2
+ export interface InitOptions {
2
3
  name?: string;
3
4
  template?: string;
4
5
  flavor?: string;
@@ -8,6 +9,7 @@ interface InitOutput {
8
9
  name: string;
9
10
  template: string;
10
11
  templateType: PredefinedTemplate | 'custom';
12
+ globalCLIResult: InstallGlobalCLIPromptResult;
11
13
  }
12
14
  interface TemplateBranch {
13
15
  branch: string;
@@ -31,8 +33,7 @@ export declare const templates: {
31
33
  readonly php: Template;
32
34
  readonly ruby: Template;
33
35
  };
34
- export type PredefinedTemplate = keyof typeof templates;
35
- export declare const allTemplates: readonly ("remix" | "none" | "node" | "php" | "ruby")[];
36
+ type PredefinedTemplate = keyof typeof templates;
36
37
  export declare const visibleTemplates: readonly ("remix" | "none" | "node" | "php" | "ruby")[];
37
38
  declare const init: (options: InitOptions) => Promise<InitOutput>;
38
39
  export default init;
@@ -1,119 +1,24 @@
1
- import { generateRandomNameForSubdirectory } from '@shopify/cli-kit/node/fs';
2
- import { renderText, renderSelectPrompt, renderTextPrompt } from '@shopify/cli-kit/node/ui';
3
- // Eventually this list should be taken from a remote location
4
- // That way we don't have to update the CLI every time we add a template
5
- export const templates = {
6
- remix: {
7
- url: 'https://github.com/Shopify/shopify-app-template-remix',
8
- label: 'Start with Remix (recommended)',
9
- visible: true,
10
- branches: {
11
- prompt: 'For your Remix template, which language do you want?',
12
- options: {
13
- javascript: { branch: 'javascript', label: 'JavaScript' },
14
- typescript: { branch: 'main', label: 'TypeScript' },
15
- },
16
- },
17
- },
18
- none: {
19
- url: 'https://github.com/Shopify/shopify-app-template-none',
20
- label: 'Start by adding your first extension',
21
- visible: true,
22
- },
23
- node: {
24
- url: 'https://github.com/Shopify/shopify-app-template-node',
25
- visible: false,
26
- },
27
- php: {
28
- url: 'https://github.com/Shopify/shopify-app-template-php',
29
- visible: false,
30
- },
31
- ruby: {
32
- url: 'https://github.com/Shopify/shopify-app-template-ruby',
33
- visible: false,
34
- },
1
+ import {
2
+ init_default,
3
+ isPredefinedTemplate,
4
+ templates,
5
+ visibleTemplates
6
+ } from "../chunk-VMPTLMJN.js";
7
+ import "../chunk-WLJ2CNLG.js";
8
+ import "../chunk-FBB6KUZG.js";
9
+ import "../chunk-YLEF4RUH.js";
10
+ import "../chunk-G6FN5VUE.js";
11
+ import "../chunk-UVY6LL5H.js";
12
+ import "../chunk-7XQTD3L4.js";
13
+ import "../chunk-P4TVG45N.js";
14
+ import "../chunk-ZPB26OWQ.js";
15
+ import "../chunk-WCNR75S2.js";
16
+ import "../chunk-3JLUTHGR.js";
17
+ import "../chunk-GXPKATXW.js";
18
+ import "../chunk-M63RTPGR.js";
19
+ export {
20
+ init_default as default,
21
+ isPredefinedTemplate,
22
+ templates,
23
+ visibleTemplates
35
24
  };
36
- export const allTemplates = Object.keys(templates);
37
- export const visibleTemplates = allTemplates.filter((key) => templates[key].visible);
38
- const templateOptionsInOrder = ['remix', 'none'];
39
- const init = async (options) => {
40
- let name = options.name;
41
- let template = options.template;
42
- const flavor = options.flavor;
43
- const defaults = {
44
- name: await generateRandomNameForSubdirectory({ suffix: 'app', directory: options.directory }),
45
- template: templates.remix.url,
46
- };
47
- let welcomed = false;
48
- if (!name) {
49
- renderText({ text: '\nWelcome. Let’s get started by naming your app project. You can change it later.' });
50
- welcomed = true;
51
- name = await renderTextPrompt({
52
- message: 'Your project name?',
53
- defaultValue: defaults.name,
54
- validate: (value) => {
55
- if (value.length === 0) {
56
- return "App name can't be empty";
57
- }
58
- if (value.length > 30) {
59
- return 'Enter a shorter name (30 character max.)';
60
- }
61
- if (value.toLowerCase().includes('shopify')) {
62
- return "App name can't include the word 'shopify'";
63
- }
64
- },
65
- });
66
- }
67
- if (!template) {
68
- if (!welcomed) {
69
- renderText({ text: '\nWelcome. Let’s get started by choosing a template for your app project.' });
70
- welcomed = true;
71
- }
72
- template = await renderSelectPrompt({
73
- choices: templateOptionsInOrder.map((key) => {
74
- return {
75
- label: templates[key].label || key,
76
- value: key,
77
- };
78
- }),
79
- message: 'Get started building your app:',
80
- defaultValue: allTemplates.find((key) => templates[key].url === defaults.template),
81
- });
82
- }
83
- const answers = {
84
- ...options,
85
- name,
86
- template,
87
- templateType: isPredefinedTemplate(template) ? template : 'custom',
88
- };
89
- let selectedUrl;
90
- let branch;
91
- if (answers.templateType !== 'custom') {
92
- const selectedTemplate = templates[answers.templateType];
93
- selectedUrl = selectedTemplate.url;
94
- if (selectedTemplate.branches) {
95
- if (flavor) {
96
- branch = selectedTemplate.branches.options[flavor]?.branch;
97
- }
98
- else {
99
- branch = await renderSelectPrompt({
100
- message: selectedTemplate.branches.prompt || 'Choose a flavor:',
101
- choices: Object.entries(selectedTemplate.branches.options).map(([_key, branch]) => ({
102
- value: branch.branch,
103
- label: branch.label,
104
- })),
105
- });
106
- }
107
- }
108
- }
109
- if (branch) {
110
- selectedUrl += `#${branch}`;
111
- }
112
- answers.template = selectedUrl || answers.template || defaults.template;
113
- return answers;
114
- };
115
- export default init;
116
- export function isPredefinedTemplate(template) {
117
- return allTemplates.includes(template);
118
- }
119
- //# sourceMappingURL=init.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/prompts/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,iCAAiC,EAAC,MAAM,0BAA0B,CAAA;AAC1E,OAAO,EAAC,UAAU,EAAE,kBAAkB,EAAE,gBAAgB,EAAC,MAAM,0BAA0B,CAAA;AA8BzF,8DAA8D;AAC9D,wEAAwE;AACxE,MAAM,CAAC,MAAM,SAAS,GAAG;IACvB,KAAK,EAAE;QACL,GAAG,EAAE,uDAAuD;QAC5D,KAAK,EAAE,gCAAgC;QACvC,OAAO,EAAE,IAAI;QACb,QAAQ,EAAE;YACR,MAAM,EAAE,sDAAsD;YAC9D,OAAO,EAAE;gBACP,UAAU,EAAE,EAAC,MAAM,EAAE,YAAY,EAAE,KAAK,EAAE,YAAY,EAAC;gBACvD,UAAU,EAAE,EAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,EAAC;aAClD;SACF;KACU;IACb,IAAI,EAAE;QACJ,GAAG,EAAE,sDAAsD;QAC3D,KAAK,EAAE,sCAAsC;QAC7C,OAAO,EAAE,IAAI;KACF;IACb,IAAI,EAAE;QACJ,GAAG,EAAE,sDAAsD;QAC3D,OAAO,EAAE,KAAK;KACH;IACb,GAAG,EAAE;QACH,GAAG,EAAE,qDAAqD;QAC1D,OAAO,EAAE,KAAK;KACH;IACb,IAAI,EAAE;QACJ,GAAG,EAAE,sDAAsD;QAC3D,OAAO,EAAE,KAAK;KACH;CACL,CAAA;AAGV,MAAM,CAAC,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,SAAS,CAAmC,CAAA;AACpF,MAAM,CAAC,MAAM,gBAAgB,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,OAAO,CAAmC,CAAA;AAEtH,MAAM,sBAAsB,GAAG,CAAC,OAAO,EAAE,MAAM,CAAU,CAAA;AAEzD,MAAM,IAAI,GAAG,KAAK,EAAE,OAAoB,EAAuB,EAAE;IAC/D,IAAI,IAAI,GAAG,OAAO,CAAC,IAAI,CAAA;IACvB,IAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IAC/B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAA;IAE7B,MAAM,QAAQ,GAAG;QACf,IAAI,EAAE,MAAM,iCAAiC,CAAC,EAAC,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC,SAAS,EAAC,CAAC;QAC5F,QAAQ,EAAE,SAAS,CAAC,KAAK,CAAC,GAAG;KACrB,CAAA;IAEV,IAAI,QAAQ,GAAG,KAAK,CAAA;IAEpB,IAAI,CAAC,IAAI,EAAE;QACT,UAAU,CAAC,EAAC,IAAI,EAAE,mFAAmF,EAAC,CAAC,CAAA;QACvG,QAAQ,GAAG,IAAI,CAAA;QACf,IAAI,GAAG,MAAM,gBAAgB,CAAC;YAC5B,OAAO,EAAE,oBAAoB;YAC7B,YAAY,EAAE,QAAQ,CAAC,IAAI;YAC3B,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE;oBACtB,OAAO,yBAAyB,CAAA;iBACjC;gBACD,IAAI,KAAK,CAAC,MAAM,GAAG,EAAE,EAAE;oBACrB,OAAO,0CAA0C,CAAA;iBAClD;gBACD,IAAI,KAAK,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,SAAS,CAAC,EAAE;oBAC3C,OAAO,2CAA2C,CAAA;iBACnD;YACH,CAAC;SACF,CAAC,CAAA;KACH;IAED,IAAI,CAAC,QAAQ,EAAE;QACb,IAAI,CAAC,QAAQ,EAAE;YACb,UAAU,CAAC,EAAC,IAAI,EAAE,2EAA2E,EAAC,CAAC,CAAA;YAC/F,QAAQ,GAAG,IAAI,CAAA;SAChB;QACD,QAAQ,GAAG,MAAM,kBAAkB,CAAC;YAClC,OAAO,EAAE,sBAAsB,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBAC1C,OAAO;oBACL,KAAK,EAAE,SAAS,CAAC,GAAG,CAAC,CAAC,KAAK,IAAI,GAAG;oBAClC,KAAK,EAAE,GAAG;iBACX,CAAA;YACH,CAAC,CAAC;YACF,OAAO,EAAE,gCAAgC;YACzC,YAAY,EAAE,YAAY,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,GAAG,KAAK,QAAQ,CAAC,QAAQ,CAAC;SACnF,CAAC,CAAA;KACH;IAED,MAAM,OAAO,GAAe;QAC1B,GAAG,OAAO;QACV,IAAI;QACJ,QAAQ;QACR,YAAY,EAAE,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ;KACnE,CAAA;IAED,IAAI,WAA+B,CAAA;IACnC,IAAI,MAA0B,CAAA;IAC9B,IAAI,OAAO,CAAC,YAAY,KAAK,QAAQ,EAAE;QACrC,MAAM,gBAAgB,GAAG,SAAS,CAAC,OAAO,CAAC,YAAY,CAAC,CAAA;QACxD,WAAW,GAAG,gBAAgB,CAAC,GAAG,CAAA;QAElC,IAAI,gBAAgB,CAAC,QAAQ,EAAE;YAC7B,IAAI,MAAM,EAAE;gBACV,MAAM,GAAG,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,CAAA;aAC3D;iBAAM;gBACL,MAAM,GAAG,MAAM,kBAAkB,CAAC;oBAChC,OAAO,EAAE,gBAAgB,CAAC,QAAQ,CAAC,MAAM,IAAI,kBAAkB;oBAC/D,OAAO,EAAE,MAAM,CAAC,OAAO,CAAC,gBAAgB,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE,CAAC,CAAC;wBAClF,KAAK,EAAE,MAAM,CAAC,MAAM;wBACpB,KAAK,EAAE,MAAM,CAAC,KAAK;qBACpB,CAAC,CAAC;iBACJ,CAAC,CAAA;aACH;SACF;KACF;IAED,IAAI,MAAM,EAAE;QACV,WAAW,IAAI,IAAI,MAAM,EAAE,CAAA;KAC5B;IAED,OAAO,CAAC,QAAQ,GAAG,WAAW,IAAI,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAA;IAEvE,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA;AAED,eAAe,IAAI,CAAA;AAEnB,MAAM,UAAU,oBAAoB,CAAC,QAAgB;IACnD,OAAO,YAAY,CAAC,QAAQ,CAAC,QAA8B,CAAC,CAAA;AAC9D,CAAC","sourcesContent":["import {generateRandomNameForSubdirectory} from '@shopify/cli-kit/node/fs'\nimport {renderText, renderSelectPrompt, renderTextPrompt} from '@shopify/cli-kit/node/ui'\n\ninterface InitOptions {\n name?: string\n template?: string\n flavor?: string\n directory: string\n}\n\ninterface InitOutput {\n name: string\n template: string\n // e.g. 'remix'\n templateType: PredefinedTemplate | 'custom'\n}\n\ninterface TemplateBranch {\n branch: string\n label: string\n}\ninterface Template {\n url: string\n label?: string\n visible: boolean\n branches?: {\n prompt: string\n options: {[key: string]: TemplateBranch}\n }\n}\n\n// Eventually this list should be taken from a remote location\n// That way we don't have to update the CLI every time we add a template\nexport const templates = {\n remix: {\n url: 'https://github.com/Shopify/shopify-app-template-remix',\n label: 'Start with Remix (recommended)',\n visible: true,\n branches: {\n prompt: 'For your Remix template, which language do you want?',\n options: {\n javascript: {branch: 'javascript', label: 'JavaScript'},\n typescript: {branch: 'main', label: 'TypeScript'},\n },\n },\n } as Template,\n none: {\n url: 'https://github.com/Shopify/shopify-app-template-none',\n label: 'Start by adding your first extension',\n visible: true,\n } as Template,\n node: {\n url: 'https://github.com/Shopify/shopify-app-template-node',\n visible: false,\n } as Template,\n php: {\n url: 'https://github.com/Shopify/shopify-app-template-php',\n visible: false,\n } as Template,\n ruby: {\n url: 'https://github.com/Shopify/shopify-app-template-ruby',\n visible: false,\n } as Template,\n} as const\nexport type PredefinedTemplate = keyof typeof templates\n\nexport const allTemplates = Object.keys(templates) as Readonly<PredefinedTemplate[]>\nexport const visibleTemplates = allTemplates.filter((key) => templates[key].visible) as Readonly<PredefinedTemplate[]>\n\nconst templateOptionsInOrder = ['remix', 'none'] as const\n\nconst init = async (options: InitOptions): Promise<InitOutput> => {\n let name = options.name\n let template = options.template\n const flavor = options.flavor\n\n const defaults = {\n name: await generateRandomNameForSubdirectory({suffix: 'app', directory: options.directory}),\n template: templates.remix.url,\n } as const\n\n let welcomed = false\n\n if (!name) {\n renderText({text: '\\nWelcome. Let’s get started by naming your app project. You can change it later.'})\n welcomed = true\n name = await renderTextPrompt({\n message: 'Your project name?',\n defaultValue: defaults.name,\n validate: (value) => {\n if (value.length === 0) {\n return \"App name can't be empty\"\n }\n if (value.length > 30) {\n return 'Enter a shorter name (30 character max.)'\n }\n if (value.toLowerCase().includes('shopify')) {\n return \"App name can't include the word 'shopify'\"\n }\n },\n })\n }\n\n if (!template) {\n if (!welcomed) {\n renderText({text: '\\nWelcome. Let’s get started by choosing a template for your app project.'})\n welcomed = true\n }\n template = await renderSelectPrompt({\n choices: templateOptionsInOrder.map((key) => {\n return {\n label: templates[key].label || key,\n value: key,\n }\n }),\n message: 'Get started building your app:',\n defaultValue: allTemplates.find((key) => templates[key].url === defaults.template),\n })\n }\n\n const answers: InitOutput = {\n ...options,\n name,\n template,\n templateType: isPredefinedTemplate(template) ? template : 'custom',\n }\n\n let selectedUrl: string | undefined\n let branch: string | undefined\n if (answers.templateType !== 'custom') {\n const selectedTemplate = templates[answers.templateType]\n selectedUrl = selectedTemplate.url\n\n if (selectedTemplate.branches) {\n if (flavor) {\n branch = selectedTemplate.branches.options[flavor]?.branch\n } else {\n branch = await renderSelectPrompt({\n message: selectedTemplate.branches.prompt || 'Choose a flavor:',\n choices: Object.entries(selectedTemplate.branches.options).map(([_key, branch]) => ({\n value: branch.branch,\n label: branch.label,\n })),\n })\n }\n }\n }\n\n if (branch) {\n selectedUrl += `#${branch}`\n }\n\n answers.template = selectedUrl || answers.template || defaults.template\n\n return answers\n}\n\nexport default init\n\nexport function isPredefinedTemplate(template: string): template is PredefinedTemplate {\n return allTemplates.includes(template as PredefinedTemplate)\n}\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/prompts/init.ts"],"names":[],"mappings":"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","sourcesContent":["import {generateRandomNameForSubdirectory} from '@shopify/cli-kit/node/fs'\nimport {InstallGlobalCLIPromptResult, installGlobalCLIPrompt} from '@shopify/cli-kit/node/is-global'\nimport {renderText, renderSelectPrompt, renderTextPrompt} from '@shopify/cli-kit/node/ui'\n\nexport interface InitOptions {\n name?: string\n template?: string\n flavor?: string\n directory: string\n}\n\ninterface InitOutput {\n name: string\n template: string\n // e.g. 'remix'\n templateType: PredefinedTemplate | 'custom'\n globalCLIResult: InstallGlobalCLIPromptResult\n}\n\ninterface TemplateBranch {\n branch: string\n label: string\n}\ninterface Template {\n url: string\n label?: string\n visible: boolean\n branches?: {\n prompt: string\n options: {[key: string]: TemplateBranch}\n }\n}\n\n// Eventually this list should be taken from a remote location\n// That way we don't have to update the CLI every time we add a template\nexport const templates = {\n remix: {\n url: 'https://github.com/Shopify/shopify-app-template-remix',\n label: 'Start with Remix (recommended)',\n visible: true,\n branches: {\n prompt: 'For your Remix template, which language do you want?',\n options: {\n javascript: {branch: 'javascript', label: 'JavaScript'},\n typescript: {branch: 'main', label: 'TypeScript'},\n },\n },\n } as Template,\n none: {\n url: 'https://github.com/Shopify/shopify-app-template-none',\n label: 'Start by adding your first extension',\n visible: true,\n } as Template,\n node: {\n url: 'https://github.com/Shopify/shopify-app-template-node',\n visible: false,\n } as Template,\n php: {\n url: 'https://github.com/Shopify/shopify-app-template-php',\n visible: false,\n } as Template,\n ruby: {\n url: 'https://github.com/Shopify/shopify-app-template-ruby',\n visible: false,\n } as Template,\n} as const\ntype PredefinedTemplate = keyof typeof templates\n\nconst allTemplates = Object.keys(templates) as Readonly<PredefinedTemplate[]>\nexport const visibleTemplates = allTemplates.filter((key) => templates[key].visible) as Readonly<PredefinedTemplate[]>\n\nconst templateOptionsInOrder = ['remix', 'none'] as const\n\nconst init = async (options: InitOptions): Promise<InitOutput> => {\n let name = options.name\n let template = options.template\n const flavor = options.flavor\n\n const defaults = {\n name: await generateRandomNameForSubdirectory({suffix: 'app', directory: options.directory}),\n template: templates.remix.url,\n } as const\n\n let welcomed = false\n\n if (!name) {\n renderText({text: '\\nWelcome. Let’s get started by naming your app project. You can change it later.'})\n welcomed = true\n name = await renderTextPrompt({\n message: 'Your project name?',\n defaultValue: defaults.name,\n validate: (value) => {\n if (value.length === 0) {\n return \"App name can't be empty\"\n }\n if (value.length > 30) {\n return 'Enter a shorter name (30 character max.)'\n }\n if (value.toLowerCase().includes('shopify')) {\n return \"App name can't include the word 'shopify'\"\n }\n },\n })\n }\n\n if (!template) {\n if (!welcomed) {\n renderText({text: '\\nWelcome. Let’s get started by choosing a template for your app project.'})\n welcomed = true\n }\n template = await renderSelectPrompt({\n choices: templateOptionsInOrder.map((key) => {\n return {\n label: templates[key].label || key,\n value: key,\n }\n }),\n message: 'Get started building your app:',\n defaultValue: allTemplates.find((key) => templates[key].url === defaults.template),\n })\n }\n\n const answers: InitOutput = {\n ...options,\n name,\n template,\n templateType: isPredefinedTemplate(template) ? template : 'custom',\n globalCLIResult: {install: false, alreadyInstalled: false},\n }\n\n let selectedUrl: string | undefined\n let branch: string | undefined\n if (answers.templateType !== 'custom') {\n const selectedTemplate = templates[answers.templateType]\n selectedUrl = selectedTemplate.url\n\n if (selectedTemplate.branches) {\n if (flavor) {\n branch = selectedTemplate.branches.options[flavor]?.branch\n } else {\n branch = await renderSelectPrompt({\n message: selectedTemplate.branches.prompt || 'Choose a flavor:',\n choices: Object.entries(selectedTemplate.branches.options).map(([_key, branch]) => ({\n value: branch.branch,\n label: branch.label,\n })),\n })\n }\n }\n }\n\n if (branch) {\n selectedUrl += `#${branch}`\n }\n\n answers.template = selectedUrl || answers.template || defaults.template\n\n answers.globalCLIResult = await installGlobalCLIPrompt()\n\n return answers\n}\n\nexport default init\n\nexport function isPredefinedTemplate(template: string): template is PredefinedTemplate {\n return allTemplates.includes(template as PredefinedTemplate)\n}\n"]}
@@ -0,0 +1,115 @@
1
+ import {
2
+ init_default
3
+ } from "../chunk-VMPTLMJN.js";
4
+ import {
5
+ installGlobalCLIPrompt,
6
+ renderSelectPrompt,
7
+ renderText,
8
+ renderTextPrompt
9
+ } from "../chunk-WLJ2CNLG.js";
10
+ import "../chunk-FBB6KUZG.js";
11
+ import "../chunk-YLEF4RUH.js";
12
+ import "../chunk-G6FN5VUE.js";
13
+ import "../chunk-UVY6LL5H.js";
14
+ import "../chunk-7XQTD3L4.js";
15
+ import "../chunk-P4TVG45N.js";
16
+ import "../chunk-ZPB26OWQ.js";
17
+ import "../chunk-WCNR75S2.js";
18
+ import {
19
+ beforeEach,
20
+ describe,
21
+ globalExpect,
22
+ test,
23
+ vi
24
+ } from "../chunk-3JNB3A7C.js";
25
+ import "../chunk-3JLUTHGR.js";
26
+ import "../chunk-GXPKATXW.js";
27
+ import {
28
+ init_cjs_shims
29
+ } from "../chunk-M63RTPGR.js";
30
+
31
+ // src/prompts/init.test.ts
32
+ init_cjs_shims();
33
+ vi.mock("@shopify/cli-kit/node/ui");
34
+ vi.mock("@shopify/cli-kit/node/is-global");
35
+ var globalCLIResult = { install: true, alreadyInstalled: false };
36
+ describe("init", () => {
37
+ beforeEach(() => {
38
+ vi.mocked(installGlobalCLIPrompt).mockResolvedValue(globalCLIResult);
39
+ });
40
+ test("when name is not passed", async () => {
41
+ const answers = {
42
+ name: "app"
43
+ };
44
+ const options = { template: "template", directory: "/" };
45
+ vi.mocked(renderTextPrompt).mockResolvedValueOnce(answers.name);
46
+ const got = await init_default(options);
47
+ globalExpect(renderText).toHaveBeenCalledWith({
48
+ text: "\nWelcome. Let\u2019s get started by naming your app project. You can change it later."
49
+ });
50
+ globalExpect(renderTextPrompt).toHaveBeenCalledWith({
51
+ message: "Your project name?",
52
+ defaultValue: globalExpect.stringMatching(/^\w+-\w+-app$/),
53
+ validate: globalExpect.any(Function)
54
+ });
55
+ globalExpect(got).toEqual({ ...options, ...answers, templateType: "custom", globalCLIResult });
56
+ });
57
+ test("when name is passed", async () => {
58
+ const answers = {
59
+ template: "https://github.com/Shopify/shopify-app-template-remix"
60
+ };
61
+ const options = { name: "app", directory: "/" };
62
+ const got = await init_default(options);
63
+ globalExpect(renderText).toHaveBeenCalledWith({
64
+ text: "\nWelcome. Let\u2019s get started by choosing a template for your app project."
65
+ });
66
+ globalExpect(renderTextPrompt).not.toHaveBeenCalled();
67
+ globalExpect(got).toEqual({ ...options, ...answers, templateType: "custom", globalCLIResult });
68
+ });
69
+ test("it renders the label for the template options", async () => {
70
+ const answers = {
71
+ name: "app",
72
+ template: "https://github.com/Shopify/shopify-app-template-none"
73
+ };
74
+ const options = { directory: "/" };
75
+ vi.mocked(renderTextPrompt).mockResolvedValueOnce(answers.name);
76
+ vi.mocked(renderSelectPrompt).mockResolvedValueOnce("none");
77
+ const got = await init_default(options);
78
+ globalExpect(renderSelectPrompt).toHaveBeenCalledWith({
79
+ choices: [
80
+ { label: "Start with Remix (recommended)", value: "remix" },
81
+ { label: "Start by adding your first extension", value: "none" }
82
+ ],
83
+ message: "Get started building your app:",
84
+ defaultValue: "remix"
85
+ });
86
+ globalExpect(got).toEqual({ ...options, ...answers, templateType: "none", globalCLIResult });
87
+ });
88
+ test("it renders branches for templates that have them", async () => {
89
+ const answers = {
90
+ name: "app",
91
+ template: "https://github.com/Shopify/shopify-app-template-remix#javascript"
92
+ };
93
+ const options = { directory: "/" };
94
+ vi.mocked(renderTextPrompt).mockResolvedValueOnce(answers.name);
95
+ vi.mocked(renderSelectPrompt).mockResolvedValueOnce("remix");
96
+ vi.mocked(renderSelectPrompt).mockResolvedValueOnce("javascript");
97
+ const got = await init_default(options);
98
+ globalExpect(renderSelectPrompt).toHaveBeenCalledWith({
99
+ choices: [
100
+ { label: "Start with Remix (recommended)", value: "remix" },
101
+ { label: "Start by adding your first extension", value: "none" }
102
+ ],
103
+ message: "Get started building your app:",
104
+ defaultValue: "remix"
105
+ });
106
+ globalExpect(renderSelectPrompt).toHaveBeenCalledWith({
107
+ choices: [
108
+ { label: "JavaScript", value: "javascript" },
109
+ { label: "TypeScript", value: "main" }
110
+ ],
111
+ message: "For your Remix template, which language do you want?"
112
+ });
113
+ globalExpect(got).toEqual({ ...options, ...answers, templateType: "remix", globalCLIResult });
114
+ });
115
+ });
@@ -1,9 +1,11 @@
1
+ import { PackageManager } from '@shopify/cli-kit/node/node-package-manager';
1
2
  interface InitOptions {
2
3
  name: string;
3
4
  directory: string;
4
5
  template: string;
5
- packageManager: string | undefined;
6
+ packageManager: PackageManager;
6
7
  local: boolean;
8
+ useGlobalCLI: boolean;
7
9
  }
8
10
  declare function init(options: InitOptions): Promise<void>;
9
11
  export default init;
@@ -1,139 +1,25 @@
1
- import { getDeepInstallNPMTasks, updateCLIDependencies } from '../utils/template/npm.js';
2
- import cleanup from '../utils/template/cleanup.js';
3
- import { findUpAndReadPackageJson, packageManager, packageManagerFromUserAgent, UnknownPackageManagerError, writePackageJSON, } from '@shopify/cli-kit/node/node-package-manager';
4
- import { renderSuccess, renderTasks } from '@shopify/cli-kit/node/ui';
5
- import { parseGitHubRepositoryReference } from '@shopify/cli-kit/node/github';
6
- import { hyphenate } from '@shopify/cli-kit/common/string';
7
- import { recursiveLiquidTemplateCopy } from '@shopify/cli-kit/node/liquid';
8
- import { isShopify } from '@shopify/cli-kit/node/context/local';
9
- import { downloadGitRepository, initializeGitRepository } from '@shopify/cli-kit/node/git';
10
- import { appendFile, fileExists, fileExistsSync, inTemporaryDirectory, mkdir, moveFile, writeFile, } from '@shopify/cli-kit/node/fs';
11
- import { joinPath } from '@shopify/cli-kit/node/path';
12
- import { username } from '@shopify/cli-kit/node/os';
13
- import { AbortError } from '@shopify/cli-kit/node/error';
14
- import { formatPackageManagerCommand } from '@shopify/cli-kit/node/output';
15
- async function init(options) {
16
- const packageManager = inferPackageManager(options.packageManager);
17
- const hyphenizedName = hyphenate(options.name);
18
- const outputDirectory = joinPath(options.directory, hyphenizedName);
19
- const githubRepo = parseGitHubRepositoryReference(options.template);
20
- await ensureAppDirectoryIsAvailable(outputDirectory, hyphenizedName);
21
- await inTemporaryDirectory(async (tmpDir) => {
22
- const templateDownloadDir = joinPath(tmpDir, 'download');
23
- const templatePathDir = githubRepo.filePath
24
- ? joinPath(templateDownloadDir, githubRepo.filePath)
25
- : templateDownloadDir;
26
- const templateScaffoldDir = joinPath(tmpDir, 'app');
27
- const repoUrl = githubRepo.branch ? `${githubRepo.baseURL}#${githubRepo.branch}` : githubRepo.baseURL;
28
- await mkdir(templateDownloadDir);
29
- const tasks = [
30
- {
31
- title: `Downloading template from ${repoUrl}`,
32
- task: async () => {
33
- await downloadGitRepository({
34
- repoUrl,
35
- destination: templateDownloadDir,
36
- shallow: true,
37
- });
38
- },
39
- },
40
- ];
41
- tasks.push({
42
- title: 'Parsing liquid',
43
- task: async () => {
44
- await recursiveLiquidTemplateCopy(templatePathDir, templateScaffoldDir, {
45
- dependency_manager: packageManager,
46
- app_name: options.name,
47
- });
48
- },
49
- }, {
50
- title: 'Updating package.json',
51
- task: async () => {
52
- const packageJSON = (await findUpAndReadPackageJson(templateScaffoldDir)).content;
53
- packageJSON.name = hyphenizedName;
54
- packageJSON.author = (await username()) ?? '';
55
- packageJSON.private = true;
56
- const workspacesFolders = ['extensions/*'].concat(detectAdditionalWorkspacesFolders(templateScaffoldDir));
57
- switch (packageManager) {
58
- case 'npm':
59
- case 'yarn':
60
- case 'bun':
61
- packageJSON.workspaces = workspacesFolders;
62
- break;
63
- case 'pnpm': {
64
- const workspacesContent = workspacesFolders.map((folder) => ` - '${folder}'`).join(`\n`);
65
- await writeFile(joinPath(templateScaffoldDir, 'pnpm-workspace.yaml'), `packages:\n${workspacesContent}`);
66
- // Ensure that the installation of dependencies doesn't fail when using
67
- // pnpm due to missing peerDependencies.
68
- await appendFile(joinPath(templateScaffoldDir, '.npmrc'), `auto-install-peers=true\n`);
69
- break;
70
- }
71
- case 'unknown':
72
- throw new UnknownPackageManagerError();
73
- }
74
- await updateCLIDependencies({ packageJSON, local: options.local, directory: templateScaffoldDir });
75
- await writePackageJSON(templateScaffoldDir, packageJSON);
76
- },
77
- });
78
- if (await isShopify()) {
79
- tasks.push({
80
- title: "[Shopifolks-only] Configuring the project's NPM registry",
81
- task: async () => {
82
- const npmrcPath = joinPath(templateScaffoldDir, '.npmrc');
83
- const npmrcContent = `@shopify:registry=https://registry.npmjs.org\n`;
84
- await appendFile(npmrcPath, npmrcContent);
85
- },
86
- });
87
- }
88
- tasks.push({
89
- title: 'Installing dependencies',
90
- task: async () => {
91
- await getDeepInstallNPMTasks({ from: templateScaffoldDir, packageManager });
92
- },
93
- }, {
94
- title: 'Cleaning up',
95
- task: async () => {
96
- await cleanup(templateScaffoldDir);
97
- },
98
- }, {
99
- title: 'Initializing a Git repository...',
100
- task: async () => {
101
- await initializeGitRepository(templateScaffoldDir);
102
- },
103
- });
104
- await renderTasks(tasks);
105
- await moveFile(templateScaffoldDir, outputDirectory);
106
- });
107
- renderSuccess({
108
- headline: [{ userInput: hyphenizedName }, 'is ready for you to build!'],
109
- nextSteps: [
110
- ['Run', { command: `cd ${hyphenizedName}` }],
111
- ['For extensions, run', { command: formatPackageManagerCommand(packageManager, 'generate extension') }],
112
- ['To see your app, run', { command: formatPackageManagerCommand(packageManager, 'dev') }],
113
- ],
114
- reference: [
115
- { link: { label: 'Shopify docs', url: 'https://shopify.dev' } },
116
- [
117
- 'For an overview of commands, run',
118
- { command: `${formatPackageManagerCommand(packageManager, 'shopify app', '--help')}` },
119
- ],
120
- ],
121
- });
122
- }
123
- function inferPackageManager(optionsPackageManager) {
124
- if (optionsPackageManager && packageManager.includes(optionsPackageManager)) {
125
- return optionsPackageManager;
126
- }
127
- const usedPackageManager = packageManagerFromUserAgent();
128
- return usedPackageManager === 'unknown' ? 'npm' : usedPackageManager;
129
- }
130
- async function ensureAppDirectoryIsAvailable(directory, name) {
131
- const exists = await fileExists(directory);
132
- if (exists)
133
- throw new AbortError(`\nA directory with this name (${name}) already exists.\nChoose a new name for your app.`);
134
- }
135
- function detectAdditionalWorkspacesFolders(directory) {
136
- return ['web', 'web/frontend'].filter((folder) => fileExistsSync(joinPath(directory, folder)));
137
- }
138
- export default init;
139
- //# sourceMappingURL=init.js.map
1
+ import {
2
+ init_default
3
+ } from "../chunk-ND5WSAZY.js";
4
+ import "../chunk-CKY5L2DS.js";
5
+ import "../chunk-4SXWHRL5.js";
6
+ import "../chunk-5RH4B5Q7.js";
7
+ import "../chunk-H7CRO63U.js";
8
+ import "../chunk-TMGCRPEZ.js";
9
+ import "../chunk-JP7Y3CTL.js";
10
+ import "../chunk-ZDCQCTOO.js";
11
+ import "../chunk-WLJ2CNLG.js";
12
+ import "../chunk-FBB6KUZG.js";
13
+ import "../chunk-YLEF4RUH.js";
14
+ import "../chunk-G6FN5VUE.js";
15
+ import "../chunk-UVY6LL5H.js";
16
+ import "../chunk-7XQTD3L4.js";
17
+ import "../chunk-P4TVG45N.js";
18
+ import "../chunk-ZPB26OWQ.js";
19
+ import "../chunk-WCNR75S2.js";
20
+ import "../chunk-3JLUTHGR.js";
21
+ import "../chunk-GXPKATXW.js";
22
+ import "../chunk-M63RTPGR.js";
23
+ export {
24
+ init_default as default
25
+ };
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/services/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAE,qBAAqB,EAAC,MAAM,0BAA0B,CAAA;AACtF,OAAO,OAAO,MAAM,8BAA8B,CAAA;AAClD,OAAO,EACL,wBAAwB,EACxB,cAAc,EAEd,2BAA2B,EAC3B,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,4CAA4C,CAAA;AACnD,OAAO,EAAC,aAAa,EAAE,WAAW,EAAO,MAAM,0BAA0B,CAAA;AACzE,OAAO,EAAC,8BAA8B,EAAC,MAAM,8BAA8B,CAAA;AAC3E,OAAO,EAAC,SAAS,EAAC,MAAM,gCAAgC,CAAA;AACxD,OAAO,EAAC,2BAA2B,EAAC,MAAM,8BAA8B,CAAA;AACxE,OAAO,EAAC,SAAS,EAAC,MAAM,qCAAqC,CAAA;AAC7D,OAAO,EAAC,qBAAqB,EAAE,uBAAuB,EAAC,MAAM,2BAA2B,CAAA;AACxF,OAAO,EACL,UAAU,EACV,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,KAAK,EACL,QAAQ,EACR,SAAS,GACV,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,QAAQ,EAAC,MAAM,4BAA4B,CAAA;AACnD,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAC,2BAA2B,EAAC,MAAM,8BAA8B,CAAA;AAUxE,KAAK,UAAU,IAAI,CAAC,OAAoB;IACtC,MAAM,cAAc,GAAmB,mBAAmB,CAAC,OAAO,CAAC,cAAc,CAAC,CAAA;IAClF,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;IACnE,MAAM,UAAU,GAAG,8BAA8B,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAEnE,MAAM,6BAA6B,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA;IAEpE,MAAM,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QACxD,MAAM,eAAe,GAAG,UAAU,CAAC,QAAQ;YACzC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,EAAE,UAAU,CAAC,QAAQ,CAAC;YACpD,CAAC,CAAC,mBAAmB,CAAA;QACvB,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACnD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAA;QAErG,MAAM,KAAK,CAAC,mBAAmB,CAAC,CAAA;QAChC,MAAM,KAAK,GAAoB;YAC7B;gBACE,KAAK,EAAE,6BAA6B,OAAO,EAAE;gBAC7C,IAAI,EAAE,KAAK,IAAI,EAAE;oBACf,MAAM,qBAAqB,CAAC;wBAC1B,OAAO;wBACP,WAAW,EAAE,mBAAmB;wBAChC,OAAO,EAAE,IAAI;qBACd,CAAC,CAAA;gBACJ,CAAC;aACF;SACF,CAAA;QAED,KAAK,CAAC,IAAI,CACR;YACE,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,2BAA2B,CAAC,eAAe,EAAE,mBAAmB,EAAE;oBACtE,kBAAkB,EAAE,cAAc;oBAClC,QAAQ,EAAE,OAAO,CAAC,IAAI;iBACvB,CAAC,CAAA;YACJ,CAAC;SACF,EACD;YACE,KAAK,EAAE,uBAAuB;YAC9B,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,WAAW,GAAG,CAAC,MAAM,wBAAwB,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAA;gBACjF,WAAW,CAAC,IAAI,GAAG,cAAc,CAAA;gBACjC,WAAW,CAAC,MAAM,GAAG,CAAC,MAAM,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAA;gBAC7C,WAAW,CAAC,OAAO,GAAG,IAAI,CAAA;gBAC1B,MAAM,iBAAiB,GAAG,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,iCAAiC,CAAC,mBAAmB,CAAC,CAAC,CAAA;gBAEzG,QAAQ,cAAc,EAAE;oBACtB,KAAK,KAAK,CAAC;oBACX,KAAK,MAAM,CAAC;oBACZ,KAAK,KAAK;wBACR,WAAW,CAAC,UAAU,GAAG,iBAAiB,CAAA;wBAC1C,MAAK;oBACP,KAAK,MAAM,CAAC,CAAC;wBACX,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;wBACxF,MAAM,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,EAAE,cAAc,iBAAiB,EAAE,CAAC,CAAA;wBACxG,uEAAuE;wBACvE,wCAAwC;wBACxC,MAAM,UAAU,CAAC,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,2BAA2B,CAAC,CAAA;wBACtF,MAAK;qBACN;oBACD,KAAK,SAAS;wBACZ,MAAM,IAAI,0BAA0B,EAAE,CAAA;iBACzC;gBAED,MAAM,qBAAqB,CAAC,EAAC,WAAW,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAC,CAAC,CAAA;gBAChG,MAAM,gBAAgB,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;YAC1D,CAAC;SACF,CACF,CAAA;QAED,IAAI,MAAM,SAAS,EAAE,EAAE;YACrB,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,0DAA0D;gBACjE,IAAI,EAAE,KAAK,IAAI,EAAE;oBACf,MAAM,SAAS,GAAG,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAA;oBACzD,MAAM,YAAY,GAAG,gDAAgD,CAAA;oBACrE,MAAM,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;gBAC3C,CAAC;aACF,CAAC,CAAA;SACH;QAED,KAAK,CAAC,IAAI,CACR;YACE,KAAK,EAAE,yBAAyB;YAChC,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,sBAAsB,CAAC,EAAC,IAAI,EAAE,mBAAmB,EAAE,cAAc,EAAC,CAAC,CAAA;YAC3E,CAAC;SACF,EACD;YACE,KAAK,EAAE,aAAa;YACpB,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAA;YACpC,CAAC;SACF,EACD;YACE,KAAK,EAAE,kCAAkC;YACzC,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,uBAAuB,CAAC,mBAAmB,CAAC,CAAA;YACpD,CAAC;SACF,CACF,CAAA;QAED,MAAM,WAAW,CAAC,KAAK,CAAC,CAAA;QAExB,MAAM,QAAQ,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,aAAa,CAAC;QACZ,QAAQ,EAAE,CAAC,EAAC,SAAS,EAAE,cAAc,EAAC,EAAE,4BAA4B,CAAC;QACrE,SAAS,EAAE;YACT,CAAC,KAAK,EAAE,EAAC,OAAO,EAAE,MAAM,cAAc,EAAE,EAAC,CAAC;YAC1C,CAAC,qBAAqB,EAAE,EAAC,OAAO,EAAE,2BAA2B,CAAC,cAAc,EAAE,oBAAoB,CAAC,EAAC,CAAC;YACrG,CAAC,sBAAsB,EAAE,EAAC,OAAO,EAAE,2BAA2B,CAAC,cAAc,EAAE,KAAK,CAAC,EAAC,CAAC;SACxF;QACD,SAAS,EAAE;YACT,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,qBAAqB,EAAC,EAAC;YAC3D;gBACE,kCAAkC;gBAClC,EAAC,OAAO,EAAE,GAAG,2BAA2B,CAAC,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,EAAC;aACrF;SACF;KACF,CAAC,CAAA;AACJ,CAAC;AAED,SAAS,mBAAmB,CAAC,qBAAyC;IACpE,IAAI,qBAAqB,IAAI,cAAc,CAAC,QAAQ,CAAC,qBAAuC,CAAC,EAAE;QAC7F,OAAO,qBAAuC,CAAA;KAC/C;IACD,MAAM,kBAAkB,GAAG,2BAA2B,EAAE,CAAA;IACxD,OAAO,kBAAkB,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,kBAAkB,CAAA;AACtE,CAAC;AAED,KAAK,UAAU,6BAA6B,CAAC,SAAiB,EAAE,IAAY;IAC1E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAA;IAC1C,IAAI,MAAM;QACR,MAAM,IAAI,UAAU,CAAC,iCAAiC,IAAI,oDAAoD,CAAC,CAAA;AACnH,CAAC;AAED,SAAS,iCAAiC,CAAC,SAAiB;IAC1D,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAChG,CAAC;AAED,eAAe,IAAI,CAAA","sourcesContent":["import {getDeepInstallNPMTasks, updateCLIDependencies} from '../utils/template/npm.js'\nimport cleanup from '../utils/template/cleanup.js'\nimport {\n findUpAndReadPackageJson,\n packageManager,\n PackageManager,\n packageManagerFromUserAgent,\n UnknownPackageManagerError,\n writePackageJSON,\n} from '@shopify/cli-kit/node/node-package-manager'\nimport {renderSuccess, renderTasks, Task} from '@shopify/cli-kit/node/ui'\nimport {parseGitHubRepositoryReference} from '@shopify/cli-kit/node/github'\nimport {hyphenate} from '@shopify/cli-kit/common/string'\nimport {recursiveLiquidTemplateCopy} from '@shopify/cli-kit/node/liquid'\nimport {isShopify} from '@shopify/cli-kit/node/context/local'\nimport {downloadGitRepository, initializeGitRepository} from '@shopify/cli-kit/node/git'\nimport {\n appendFile,\n fileExists,\n fileExistsSync,\n inTemporaryDirectory,\n mkdir,\n moveFile,\n writeFile,\n} from '@shopify/cli-kit/node/fs'\nimport {joinPath} from '@shopify/cli-kit/node/path'\nimport {username} from '@shopify/cli-kit/node/os'\nimport {AbortError} from '@shopify/cli-kit/node/error'\nimport {formatPackageManagerCommand} from '@shopify/cli-kit/node/output'\n\ninterface InitOptions {\n name: string\n directory: string\n template: string\n packageManager: string | undefined\n local: boolean\n}\n\nasync function init(options: InitOptions) {\n const packageManager: PackageManager = inferPackageManager(options.packageManager)\n const hyphenizedName = hyphenate(options.name)\n const outputDirectory = joinPath(options.directory, hyphenizedName)\n const githubRepo = parseGitHubRepositoryReference(options.template)\n\n await ensureAppDirectoryIsAvailable(outputDirectory, hyphenizedName)\n\n await inTemporaryDirectory(async (tmpDir) => {\n const templateDownloadDir = joinPath(tmpDir, 'download')\n const templatePathDir = githubRepo.filePath\n ? joinPath(templateDownloadDir, githubRepo.filePath)\n : templateDownloadDir\n const templateScaffoldDir = joinPath(tmpDir, 'app')\n const repoUrl = githubRepo.branch ? `${githubRepo.baseURL}#${githubRepo.branch}` : githubRepo.baseURL\n\n await mkdir(templateDownloadDir)\n const tasks: Task<unknown>[] = [\n {\n title: `Downloading template from ${repoUrl}`,\n task: async () => {\n await downloadGitRepository({\n repoUrl,\n destination: templateDownloadDir,\n shallow: true,\n })\n },\n },\n ]\n\n tasks.push(\n {\n title: 'Parsing liquid',\n task: async () => {\n await recursiveLiquidTemplateCopy(templatePathDir, templateScaffoldDir, {\n dependency_manager: packageManager,\n app_name: options.name,\n })\n },\n },\n {\n title: 'Updating package.json',\n task: async () => {\n const packageJSON = (await findUpAndReadPackageJson(templateScaffoldDir)).content\n packageJSON.name = hyphenizedName\n packageJSON.author = (await username()) ?? ''\n packageJSON.private = true\n const workspacesFolders = ['extensions/*'].concat(detectAdditionalWorkspacesFolders(templateScaffoldDir))\n\n switch (packageManager) {\n case 'npm':\n case 'yarn':\n case 'bun':\n packageJSON.workspaces = workspacesFolders\n break\n case 'pnpm': {\n const workspacesContent = workspacesFolders.map((folder) => ` - '${folder}'`).join(`\\n`)\n await writeFile(joinPath(templateScaffoldDir, 'pnpm-workspace.yaml'), `packages:\\n${workspacesContent}`)\n // Ensure that the installation of dependencies doesn't fail when using\n // pnpm due to missing peerDependencies.\n await appendFile(joinPath(templateScaffoldDir, '.npmrc'), `auto-install-peers=true\\n`)\n break\n }\n case 'unknown':\n throw new UnknownPackageManagerError()\n }\n\n await updateCLIDependencies({packageJSON, local: options.local, directory: templateScaffoldDir})\n await writePackageJSON(templateScaffoldDir, packageJSON)\n },\n },\n )\n\n if (await isShopify()) {\n tasks.push({\n title: \"[Shopifolks-only] Configuring the project's NPM registry\",\n task: async () => {\n const npmrcPath = joinPath(templateScaffoldDir, '.npmrc')\n const npmrcContent = `@shopify:registry=https://registry.npmjs.org\\n`\n await appendFile(npmrcPath, npmrcContent)\n },\n })\n }\n\n tasks.push(\n {\n title: 'Installing dependencies',\n task: async () => {\n await getDeepInstallNPMTasks({from: templateScaffoldDir, packageManager})\n },\n },\n {\n title: 'Cleaning up',\n task: async () => {\n await cleanup(templateScaffoldDir)\n },\n },\n {\n title: 'Initializing a Git repository...',\n task: async () => {\n await initializeGitRepository(templateScaffoldDir)\n },\n },\n )\n\n await renderTasks(tasks)\n\n await moveFile(templateScaffoldDir, outputDirectory)\n })\n\n renderSuccess({\n headline: [{userInput: hyphenizedName}, 'is ready for you to build!'],\n nextSteps: [\n ['Run', {command: `cd ${hyphenizedName}`}],\n ['For extensions, run', {command: formatPackageManagerCommand(packageManager, 'generate extension')}],\n ['To see your app, run', {command: formatPackageManagerCommand(packageManager, 'dev')}],\n ],\n reference: [\n {link: {label: 'Shopify docs', url: 'https://shopify.dev'}},\n [\n 'For an overview of commands, run',\n {command: `${formatPackageManagerCommand(packageManager, 'shopify app', '--help')}`},\n ],\n ],\n })\n}\n\nfunction inferPackageManager(optionsPackageManager: string | undefined): PackageManager {\n if (optionsPackageManager && packageManager.includes(optionsPackageManager as PackageManager)) {\n return optionsPackageManager as PackageManager\n }\n const usedPackageManager = packageManagerFromUserAgent()\n return usedPackageManager === 'unknown' ? 'npm' : usedPackageManager\n}\n\nasync function ensureAppDirectoryIsAvailable(directory: string, name: string): Promise<void> {\n const exists = await fileExists(directory)\n if (exists)\n throw new AbortError(`\\nA directory with this name (${name}) already exists.\\nChoose a new name for your app.`)\n}\n\nfunction detectAdditionalWorkspacesFolders(directory: string) {\n return ['web', 'web/frontend'].filter((folder) => fileExistsSync(joinPath(directory, folder)))\n}\n\nexport default init\n"]}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/services/init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,sBAAsB,EAAE,qBAAqB,EAAC,MAAM,0BAA0B,CAAA;AACtF,OAAO,OAAO,MAAM,8BAA8B,CAAA;AAClD,OAAO,EACL,wBAAwB,EAExB,0BAA0B,EAC1B,gBAAgB,GACjB,MAAM,4CAA4C,CAAA;AACnD,OAAO,EAAC,UAAU,EAAE,aAAa,EAAE,WAAW,EAAO,MAAM,0BAA0B,CAAA;AACrF,OAAO,EAAC,8BAA8B,EAAC,MAAM,8BAA8B,CAAA;AAC3E,OAAO,EAAC,SAAS,EAAC,MAAM,gCAAgC,CAAA;AACxD,OAAO,EAAC,2BAA2B,EAAC,MAAM,8BAA8B,CAAA;AACxE,OAAO,EAAC,SAAS,EAAC,MAAM,qCAAqC,CAAA;AAC7D,OAAO,EAAC,qBAAqB,EAAE,uBAAuB,EAAC,MAAM,2BAA2B,CAAA;AACxF,OAAO,EACL,UAAU,EACV,UAAU,EACV,cAAc,EACd,oBAAoB,EACpB,KAAK,EACL,QAAQ,EACR,SAAS,GACV,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAC,QAAQ,EAAC,MAAM,4BAA4B,CAAA;AACnD,OAAO,EAAC,QAAQ,EAAC,MAAM,0BAA0B,CAAA;AACjD,OAAO,EAAC,UAAU,EAAC,MAAM,6BAA6B,CAAA;AACtD,OAAO,EAAC,2BAA2B,EAAC,MAAM,8BAA8B,CAAA;AAWxE,KAAK,UAAU,IAAI,CAAC,OAAoB;IACtC,MAAM,cAAc,GAAmB,OAAO,CAAC,cAAc,CAAA;IAC7D,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAA;IAC9C,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,CAAC,SAAS,EAAE,cAAc,CAAC,CAAA;IACnE,MAAM,UAAU,GAAG,8BAA8B,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAEnE,MAAM,6BAA6B,CAAC,eAAe,EAAE,cAAc,CAAC,CAAA;IAEpE,UAAU,CAAC;QACT,IAAI,EAAE;YACJ,2BAA2B;YAC3B,EAAC,OAAO,EAAE,cAAc,EAAC;YACzB,WAAW;YACX,EAAC,OAAO,EAAE,mBAAmB,EAAC;YAC9B,6CAA6C;SAC9C;KACF,CAAC,CAAA;IAEF,MAAM,oBAAoB,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QACxD,MAAM,eAAe,GAAG,UAAU,CAAC,QAAQ;YACzC,CAAC,CAAC,QAAQ,CAAC,mBAAmB,EAAE,UAAU,CAAC,QAAQ,CAAC;YACpD,CAAC,CAAC,mBAAmB,CAAA;QACvB,MAAM,mBAAmB,GAAG,QAAQ,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;QACnD,MAAM,OAAO,GAAG,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,OAAO,CAAA;QAErG,MAAM,KAAK,CAAC,mBAAmB,CAAC,CAAA;QAChC,MAAM,KAAK,GAAoB;YAC7B;gBACE,KAAK,EAAE,6BAA6B,OAAO,EAAE;gBAC7C,IAAI,EAAE,KAAK,IAAI,EAAE;oBACf,MAAM,qBAAqB,CAAC;wBAC1B,OAAO;wBACP,WAAW,EAAE,mBAAmB;wBAChC,OAAO,EAAE,IAAI;qBACd,CAAC,CAAA;gBACJ,CAAC;aACF;SACF,CAAA;QAED,KAAK,CAAC,IAAI,CACR;YACE,KAAK,EAAE,gBAAgB;YACvB,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,2BAA2B,CAAC,eAAe,EAAE,mBAAmB,EAAE;oBACtE,kBAAkB,EAAE,cAAc;oBAClC,QAAQ,EAAE,OAAO,CAAC,IAAI;iBACvB,CAAC,CAAA;YACJ,CAAC;SACF,EACD;YACE,KAAK,EAAE,uBAAuB;YAC9B,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,WAAW,GAAG,CAAC,MAAM,wBAAwB,CAAC,mBAAmB,CAAC,CAAC,CAAC,OAAO,CAAA;gBACjF,WAAW,CAAC,IAAI,GAAG,cAAc,CAAA;gBACjC,WAAW,CAAC,MAAM,GAAG,CAAC,MAAM,QAAQ,EAAE,CAAC,IAAI,EAAE,CAAA;gBAC7C,WAAW,CAAC,OAAO,GAAG,IAAI,CAAA;gBAC1B,MAAM,iBAAiB,GAAG,CAAC,cAAc,CAAC,CAAC,MAAM,CAAC,iCAAiC,CAAC,mBAAmB,CAAC,CAAC,CAAA;gBAEzG,QAAQ,cAAc,EAAE;oBACtB,KAAK,KAAK,CAAC;oBACX,KAAK,MAAM,CAAC;oBACZ,KAAK,KAAK;wBACR,WAAW,CAAC,UAAU,GAAG,iBAAiB,CAAA;wBAC1C,MAAK;oBACP,KAAK,MAAM,CAAC,CAAC;wBACX,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,OAAO,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;wBACxF,MAAM,SAAS,CAAC,QAAQ,CAAC,mBAAmB,EAAE,qBAAqB,CAAC,EAAE,cAAc,iBAAiB,EAAE,CAAC,CAAA;wBACxG,uEAAuE;wBACvE,wCAAwC;wBACxC,MAAM,UAAU,CAAC,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,EAAE,2BAA2B,CAAC,CAAA;wBACtF,MAAK;qBACN;oBACD,KAAK,SAAS;wBACZ,MAAM,IAAI,0BAA0B,EAAE,CAAA;iBACzC;gBAED,MAAM,qBAAqB,CAAC;oBAC1B,WAAW;oBACX,KAAK,EAAE,OAAO,CAAC,KAAK;oBACpB,SAAS,EAAE,mBAAmB;oBAC9B,YAAY,EAAE,OAAO,CAAC,YAAY;iBACnC,CAAC,CAAA;gBACF,MAAM,gBAAgB,CAAC,mBAAmB,EAAE,WAAW,CAAC,CAAA;YAC1D,CAAC;SACF,CACF,CAAA;QAED,IAAI,MAAM,SAAS,EAAE,EAAE;YACrB,KAAK,CAAC,IAAI,CAAC;gBACT,KAAK,EAAE,0DAA0D;gBACjE,IAAI,EAAE,KAAK,IAAI,EAAE;oBACf,MAAM,SAAS,GAAG,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAA;oBACzD,MAAM,YAAY,GAAG,gDAAgD,CAAA;oBACrE,MAAM,UAAU,CAAC,SAAS,EAAE,YAAY,CAAC,CAAA;gBAC3C,CAAC;aACF,CAAC,CAAA;SACH;QAED,KAAK,CAAC,IAAI,CACR;YACE,KAAK,EAAE,gCAAgC,cAAc,EAAE;YACvD,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,sBAAsB,CAAC,EAAC,IAAI,EAAE,mBAAmB,EAAE,cAAc,EAAC,CAAC,CAAA;YAC3E,CAAC;SACF,EACD;YACE,KAAK,EAAE,aAAa;YACpB,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAA;YACpC,CAAC;SACF,EACD;YACE,KAAK,EAAE,kCAAkC;YACzC,IAAI,EAAE,KAAK,IAAI,EAAE;gBACf,MAAM,uBAAuB,CAAC,mBAAmB,CAAC,CAAA;YACpD,CAAC;SACF,CACF,CAAA;QAED,MAAM,WAAW,CAAC,KAAK,CAAC,CAAA;QAExB,MAAM,QAAQ,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAA;IACtD,CAAC,CAAC,CAAA;IAEF,aAAa,CAAC;QACZ,QAAQ,EAAE,CAAC,EAAC,SAAS,EAAE,cAAc,EAAC,EAAE,4BAA4B,CAAC;QACrE,SAAS,EAAE;YACT,CAAC,KAAK,EAAE,EAAC,OAAO,EAAE,MAAM,cAAc,EAAE,EAAC,CAAC;YAC1C,CAAC,qBAAqB,EAAE,EAAC,OAAO,EAAE,2BAA2B,CAAC,cAAc,EAAE,gCAAgC,CAAC,EAAC,CAAC;YACjH,CAAC,sBAAsB,EAAE,EAAC,OAAO,EAAE,2BAA2B,CAAC,cAAc,EAAE,iBAAiB,CAAC,EAAC,CAAC;SACpG;QACD,SAAS,EAAE;YACT,EAAC,IAAI,EAAE,EAAC,KAAK,EAAE,cAAc,EAAE,GAAG,EAAE,qBAAqB,EAAC,EAAC;YAC3D;gBACE,kCAAkC;gBAClC,EAAC,OAAO,EAAE,GAAG,2BAA2B,CAAC,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,EAAC;aACrF;SACF;KACF,CAAC,CAAA;AACJ,CAAC;AAED,KAAK,UAAU,6BAA6B,CAAC,SAAiB,EAAE,IAAY;IAC1E,MAAM,MAAM,GAAG,MAAM,UAAU,CAAC,SAAS,CAAC,CAAA;IAC1C,IAAI,MAAM;QACR,MAAM,IAAI,UAAU,CAAC,iCAAiC,IAAI,oDAAoD,CAAC,CAAA;AACnH,CAAC;AAED,SAAS,iCAAiC,CAAC,SAAiB;IAC1D,OAAO,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,CAAC,CAAA;AAChG,CAAC;AAED,eAAe,IAAI,CAAA","sourcesContent":["import {getDeepInstallNPMTasks, updateCLIDependencies} from '../utils/template/npm.js'\nimport cleanup from '../utils/template/cleanup.js'\nimport {\n findUpAndReadPackageJson,\n PackageManager,\n UnknownPackageManagerError,\n writePackageJSON,\n} from '@shopify/cli-kit/node/node-package-manager'\nimport {renderInfo, renderSuccess, renderTasks, Task} from '@shopify/cli-kit/node/ui'\nimport {parseGitHubRepositoryReference} from '@shopify/cli-kit/node/github'\nimport {hyphenate} from '@shopify/cli-kit/common/string'\nimport {recursiveLiquidTemplateCopy} from '@shopify/cli-kit/node/liquid'\nimport {isShopify} from '@shopify/cli-kit/node/context/local'\nimport {downloadGitRepository, initializeGitRepository} from '@shopify/cli-kit/node/git'\nimport {\n appendFile,\n fileExists,\n fileExistsSync,\n inTemporaryDirectory,\n mkdir,\n moveFile,\n writeFile,\n} from '@shopify/cli-kit/node/fs'\nimport {joinPath} from '@shopify/cli-kit/node/path'\nimport {username} from '@shopify/cli-kit/node/os'\nimport {AbortError} from '@shopify/cli-kit/node/error'\nimport {formatPackageManagerCommand} from '@shopify/cli-kit/node/output'\n\ninterface InitOptions {\n name: string\n directory: string\n template: string\n packageManager: PackageManager\n local: boolean\n useGlobalCLI: boolean\n}\n\nasync function init(options: InitOptions) {\n const packageManager: PackageManager = options.packageManager\n const hyphenizedName = hyphenate(options.name)\n const outputDirectory = joinPath(options.directory, hyphenizedName)\n const githubRepo = parseGitHubRepositoryReference(options.template)\n\n await ensureAppDirectoryIsAvailable(outputDirectory, hyphenizedName)\n\n renderInfo({\n body: [\n `Initializing project with`,\n {command: packageManager},\n `\\nUse the`,\n {command: `--package-manager`},\n `flag to select a different package manager.`,\n ],\n })\n\n await inTemporaryDirectory(async (tmpDir) => {\n const templateDownloadDir = joinPath(tmpDir, 'download')\n const templatePathDir = githubRepo.filePath\n ? joinPath(templateDownloadDir, githubRepo.filePath)\n : templateDownloadDir\n const templateScaffoldDir = joinPath(tmpDir, 'app')\n const repoUrl = githubRepo.branch ? `${githubRepo.baseURL}#${githubRepo.branch}` : githubRepo.baseURL\n\n await mkdir(templateDownloadDir)\n const tasks: Task<unknown>[] = [\n {\n title: `Downloading template from ${repoUrl}`,\n task: async () => {\n await downloadGitRepository({\n repoUrl,\n destination: templateDownloadDir,\n shallow: true,\n })\n },\n },\n ]\n\n tasks.push(\n {\n title: 'Parsing liquid',\n task: async () => {\n await recursiveLiquidTemplateCopy(templatePathDir, templateScaffoldDir, {\n dependency_manager: packageManager,\n app_name: options.name,\n })\n },\n },\n {\n title: 'Updating package.json',\n task: async () => {\n const packageJSON = (await findUpAndReadPackageJson(templateScaffoldDir)).content\n packageJSON.name = hyphenizedName\n packageJSON.author = (await username()) ?? ''\n packageJSON.private = true\n const workspacesFolders = ['extensions/*'].concat(detectAdditionalWorkspacesFolders(templateScaffoldDir))\n\n switch (packageManager) {\n case 'npm':\n case 'yarn':\n case 'bun':\n packageJSON.workspaces = workspacesFolders\n break\n case 'pnpm': {\n const workspacesContent = workspacesFolders.map((folder) => ` - '${folder}'`).join(`\\n`)\n await writeFile(joinPath(templateScaffoldDir, 'pnpm-workspace.yaml'), `packages:\\n${workspacesContent}`)\n // Ensure that the installation of dependencies doesn't fail when using\n // pnpm due to missing peerDependencies.\n await appendFile(joinPath(templateScaffoldDir, '.npmrc'), `auto-install-peers=true\\n`)\n break\n }\n case 'unknown':\n throw new UnknownPackageManagerError()\n }\n\n await updateCLIDependencies({\n packageJSON,\n local: options.local,\n directory: templateScaffoldDir,\n useGlobalCLI: options.useGlobalCLI,\n })\n await writePackageJSON(templateScaffoldDir, packageJSON)\n },\n },\n )\n\n if (await isShopify()) {\n tasks.push({\n title: \"[Shopifolks-only] Configuring the project's NPM registry\",\n task: async () => {\n const npmrcPath = joinPath(templateScaffoldDir, '.npmrc')\n const npmrcContent = `@shopify:registry=https://registry.npmjs.org\\n`\n await appendFile(npmrcPath, npmrcContent)\n },\n })\n }\n\n tasks.push(\n {\n title: `Installing dependencies with ${packageManager}`,\n task: async () => {\n await getDeepInstallNPMTasks({from: templateScaffoldDir, packageManager})\n },\n },\n {\n title: 'Cleaning up',\n task: async () => {\n await cleanup(templateScaffoldDir)\n },\n },\n {\n title: 'Initializing a Git repository...',\n task: async () => {\n await initializeGitRepository(templateScaffoldDir)\n },\n },\n )\n\n await renderTasks(tasks)\n\n await moveFile(templateScaffoldDir, outputDirectory)\n })\n\n renderSuccess({\n headline: [{userInput: hyphenizedName}, 'is ready for you to build!'],\n nextSteps: [\n ['Run', {command: `cd ${hyphenizedName}`}],\n ['For extensions, run', {command: formatPackageManagerCommand(packageManager, 'shopify app generate extension')}],\n ['To see your app, run', {command: formatPackageManagerCommand(packageManager, 'shopify app dev')}],\n ],\n reference: [\n {link: {label: 'Shopify docs', url: 'https://shopify.dev'}},\n [\n 'For an overview of commands, run',\n {command: `${formatPackageManagerCommand(packageManager, 'shopify app', '--help')}`},\n ],\n ],\n })\n}\n\nasync function ensureAppDirectoryIsAvailable(directory: string, name: string): Promise<void> {\n const exists = await fileExists(directory)\n if (exists)\n throw new AbortError(`\\nA directory with this name (${name}) already exists.\\nChoose a new name for your app.`)\n}\n\nfunction detectAdditionalWorkspacesFolders(directory: string) {\n return ['web', 'web/frontend'].filter((folder) => fileExistsSync(joinPath(directory, folder)))\n}\n\nexport default init\n"]}
@@ -0,0 +1,18 @@
1
+ import {
2
+ describe,
3
+ globalExpect,
4
+ test
5
+ } from "../chunk-3JNB3A7C.js";
6
+ import "../chunk-3JLUTHGR.js";
7
+ import "../chunk-GXPKATXW.js";
8
+ import {
9
+ init_cjs_shims
10
+ } from "../chunk-M63RTPGR.js";
11
+
12
+ // src/services/init.test.ts
13
+ init_cjs_shims();
14
+ describe("init", () => {
15
+ test("successfully initializes the app", () => {
16
+ globalExpect(true).toBe(true);
17
+ });
18
+ });
@@ -0,0 +1,25 @@
1
+ import {
2
+ captureOutput,
3
+ exec,
4
+ openURL,
5
+ sleep,
6
+ terminalSupportsRawMode
7
+ } from "./chunk-WLJ2CNLG.js";
8
+ import "./chunk-FBB6KUZG.js";
9
+ import "./chunk-YLEF4RUH.js";
10
+ import "./chunk-G6FN5VUE.js";
11
+ import "./chunk-UVY6LL5H.js";
12
+ import "./chunk-7XQTD3L4.js";
13
+ import "./chunk-P4TVG45N.js";
14
+ import "./chunk-ZPB26OWQ.js";
15
+ import "./chunk-WCNR75S2.js";
16
+ import "./chunk-3JLUTHGR.js";
17
+ import "./chunk-GXPKATXW.js";
18
+ import "./chunk-M63RTPGR.js";
19
+ export {
20
+ captureOutput,
21
+ exec,
22
+ openURL,
23
+ sleep,
24
+ terminalSupportsRawMode
25
+ };