@swell/cli 1.0.2 → 2.0.1-alpha.2

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 (105) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +2 -140
  3. package/bin/dev.cmd +3 -0
  4. package/bin/dev.js +7 -0
  5. package/bin/run.cmd +3 -0
  6. package/bin/run.js +7 -0
  7. package/dist/app-command.d.ts +22 -0
  8. package/dist/app-command.js +45 -0
  9. package/dist/commands/app/_pull.d.ts +8 -0
  10. package/dist/commands/app/_pull.js +45 -0
  11. package/dist/commands/app/_uninstall.d.ts +12 -0
  12. package/dist/commands/app/_uninstall.js +45 -0
  13. package/dist/commands/app/info.d.ts +15 -0
  14. package/dist/commands/app/info.js +92 -0
  15. package/dist/commands/app/install.d.ts +17 -0
  16. package/dist/commands/app/install.js +177 -0
  17. package/dist/commands/app/push.d.ts +17 -0
  18. package/dist/commands/app/push.js +158 -0
  19. package/dist/commands/app/version.d.ts +18 -0
  20. package/dist/commands/app/version.js +156 -0
  21. package/dist/commands/app/watch.d.ts +15 -0
  22. package/dist/commands/app/watch.js +110 -0
  23. package/dist/commands/create/app.d.ts +21 -0
  24. package/dist/commands/create/app.js +210 -0
  25. package/dist/commands/create/content.d.ts +19 -0
  26. package/dist/commands/create/content.js +87 -0
  27. package/dist/commands/create/function.d.ts +25 -0
  28. package/dist/commands/create/function.js +191 -0
  29. package/dist/commands/create/index.d.ts +6 -0
  30. package/dist/commands/create/index.js +34 -0
  31. package/dist/commands/create/model.d.ts +19 -0
  32. package/dist/commands/create/model.js +87 -0
  33. package/dist/commands/create/notification.d.ts +25 -0
  34. package/dist/commands/create/notification.js +170 -0
  35. package/dist/commands/login.d.ts +22 -0
  36. package/dist/commands/login.js +77 -0
  37. package/dist/commands/logout.d.ts +8 -0
  38. package/dist/commands/logout.js +45 -0
  39. package/dist/commands/logs.d.ts +23 -0
  40. package/dist/commands/logs.js +207 -0
  41. package/dist/commands/switch.d.ts +10 -0
  42. package/dist/commands/switch.js +41 -0
  43. package/dist/commands/whoami.d.ts +7 -0
  44. package/dist/commands/whoami.js +24 -0
  45. package/dist/create-collection-command.d.ts +26 -0
  46. package/dist/create-collection-command.js +97 -0
  47. package/dist/create-command.d.ts +16 -0
  48. package/dist/create-command.js +59 -0
  49. package/dist/index.d.ts +1 -0
  50. package/dist/index.js +1 -0
  51. package/dist/lib/api.d.ts +13 -0
  52. package/dist/lib/api.js +117 -0
  53. package/dist/lib/app-config.d.ts +29 -0
  54. package/dist/lib/app-config.js +127 -0
  55. package/dist/lib/apps/app-config.d.ts +42 -0
  56. package/dist/lib/apps/app-config.js +167 -0
  57. package/dist/lib/apps/index.d.ts +67 -0
  58. package/dist/lib/apps/index.js +167 -0
  59. package/dist/lib/apps/paths.d.ts +18 -0
  60. package/dist/lib/apps/paths.js +54 -0
  61. package/dist/lib/bundle.d.ts +1 -0
  62. package/dist/lib/bundle.js +40 -0
  63. package/dist/lib/config.d.ts +37 -0
  64. package/dist/lib/config.js +131 -0
  65. package/dist/lib/constants.d.ts +5 -0
  66. package/dist/lib/constants.js +17 -0
  67. package/dist/lib/create/content.d.ts +23 -0
  68. package/dist/lib/create/content.js +40 -0
  69. package/dist/lib/create/function.d.ts +17 -0
  70. package/dist/lib/create/function.js +36 -0
  71. package/dist/lib/create/index.d.ts +13 -0
  72. package/dist/lib/create/index.js +20 -0
  73. package/dist/lib/create/model.d.ts +22 -0
  74. package/dist/lib/create/model.js +30 -0
  75. package/dist/lib/create/notification.d.ts +25 -0
  76. package/dist/lib/create/notification.js +1 -0
  77. package/dist/lib/info.d.ts +38 -0
  78. package/dist/lib/info.js +91 -0
  79. package/dist/lib/logs/index.d.ts +23 -0
  80. package/dist/lib/logs/index.js +88 -0
  81. package/dist/lib/logs/line-output.d.ts +5 -0
  82. package/dist/lib/logs/line-output.js +13 -0
  83. package/dist/lib/logs/output.d.ts +7 -0
  84. package/dist/lib/logs/output.js +8 -0
  85. package/dist/lib/logs/table-output.d.ts +11 -0
  86. package/dist/lib/logs/table-output.js +128 -0
  87. package/dist/lib/sessions.d.ts +9 -0
  88. package/dist/lib/sessions.js +110 -0
  89. package/dist/lib/stores.d.ts +63 -0
  90. package/dist/lib/stores.js +173 -0
  91. package/dist/lib/style.d.ts +24 -0
  92. package/dist/lib/style.js +29 -0
  93. package/dist/lib/swell-function-wrapper.d.ts +88 -0
  94. package/dist/lib/swell-function-wrapper.js +302 -0
  95. package/dist/remote-app-command.d.ts +36 -0
  96. package/dist/remote-app-command.js +367 -0
  97. package/dist/swell-command.d.ts +21 -0
  98. package/dist/swell-command.js +43 -0
  99. package/oclif.manifest.json +1085 -0
  100. package/package.json +81 -43
  101. package/LICENSE +0 -674
  102. package/dist/bin/multipart-parser-85ef9626.js +0 -456
  103. package/dist/bin/swell-0f71f07d.js +0 -30670
  104. package/dist/bin/swell.js +0 -24
  105. package/dist/man/swell.1 +0 -85
@@ -0,0 +1,210 @@
1
+ import path from 'path';
2
+ import { exec } from 'child_process';
3
+ import { promisify } from 'util';
4
+ import { confirm, input, select } from '@inquirer/prompts';
5
+ import { Args, Flags } from '@oclif/core';
6
+ import ora from 'ora';
7
+ import { appConfigFileExists, newConfig } from '../../lib/app-config.js';
8
+ import style from '../../lib/style.js';
9
+ import { SwellCommand } from '../../swell-command.js';
10
+ import { toAppName, toAppId } from '../../lib/create/index.js';
11
+ import { getAllConfigPaths, writeJsonFile } from '../../lib/apps/index.js';
12
+ const execAsync = promisify(exec);
13
+ export default class CreateApp extends SwellCommand {
14
+ static args = {
15
+ id: Args.string({
16
+ default: '',
17
+ description: `id of the app to create`,
18
+ }),
19
+ };
20
+ static flags = {
21
+ pkg: Flags.string({
22
+ char: 'p',
23
+ default: 'npm',
24
+ description: `use npm or yarn to install default dependencies, or none to disable`,
25
+ options: ['npm', 'yarn', 'none'],
26
+ }),
27
+ yes: Flags.boolean({
28
+ char: 'y',
29
+ description: `accept all default values`,
30
+ }),
31
+ };
32
+ static description = 'Initialize an app with config file and folder structure.';
33
+ static examples = [
34
+ {
35
+ command: 'swell create app',
36
+ description: 'Create app following command prompts.',
37
+ },
38
+ {
39
+ command: 'swell create app my_app -y',
40
+ description: 'Create app and accept all default values.',
41
+ },
42
+ {
43
+ command: 'swell create app -p yarn',
44
+ description: 'Create app with yarn package manager instead of npm by default.',
45
+ },
46
+ {
47
+ command: 'swell create app -p none',
48
+ description: 'Create app without installing TypeScript bindings, etc.',
49
+ },
50
+ ];
51
+ async run() {
52
+ const { args, flags } = await this.parse(CreateApp);
53
+ const { id } = args;
54
+ const { pkg, yes } = flags;
55
+ let confirmYes = yes && id;
56
+ const name = confirmYes
57
+ ? toAppName(id)
58
+ : await input({
59
+ message: 'App name',
60
+ default: id ? toAppName(id) : '',
61
+ validate: (answer) => answer.length > 2,
62
+ });
63
+ let appId = toAppId(id || '');
64
+ if (!appId) {
65
+ appId = await input({
66
+ message: 'App ID',
67
+ default: toAppId(name),
68
+ validate: (answer) => answer.length > 2,
69
+ });
70
+ appId = toAppId(appId);
71
+ confirmYes = yes && appId;
72
+ }
73
+ const description = confirmYes
74
+ ? ''
75
+ : await input({
76
+ message: 'Describe what the app does',
77
+ default: 'Something special',
78
+ });
79
+ const type = confirmYes
80
+ ? 'admin'
81
+ : await select({
82
+ message: 'What is the primary purpose of the app?',
83
+ choices: [
84
+ { name: 'Admin', value: 'admin' },
85
+ { name: 'Integration', value: 'integration' },
86
+ { name: 'Storefront', value: 'storefront' },
87
+ ],
88
+ });
89
+ const appConfigJson = {
90
+ id: appId,
91
+ version: '1.0.0',
92
+ name,
93
+ description,
94
+ type,
95
+ permissions: [],
96
+ };
97
+ const config = newConfig(appId);
98
+ if (!confirmYes && appConfigFileExists(config.path)) {
99
+ const continueCreateApp = await confirm({
100
+ message: `An app already exists in the target folder ${appId}. Overwrite?`,
101
+ });
102
+ if (!continueCreateApp) {
103
+ return;
104
+ }
105
+ }
106
+ this.log(`\nCreating app ${style.appConfigValue(name)} in ${config.path}`);
107
+ this.log(`\n${JSON.stringify(appConfigJson, null, 4)}\n`);
108
+ const confirmCreateApp = confirmYes
109
+ ? true
110
+ : await confirm({
111
+ message: 'Ok to continue?',
112
+ });
113
+ if (!confirmCreateApp) {
114
+ return;
115
+ }
116
+ !confirmYes && this.log();
117
+ const spinner = ora();
118
+ spinner.start('Creating app...');
119
+ config.clear();
120
+ config.set(appConfigJson);
121
+ if (pkg !== 'none') {
122
+ await this.tryPackageSetup(appId, config, pkg);
123
+ }
124
+ await this.createAppConfigFolders(config);
125
+ spinner.succeed(`${style.appConfigValue(name)} app created.`);
126
+ this.log('\nNext steps:');
127
+ this.log(`Run ${style.command('swell app push')} to push configurations to your test store.`);
128
+ this.log(`Run ${style.command('swell app install')} to install the app in another store or environment.`);
129
+ }
130
+ async tryPackageSetup(name, config, pkg) {
131
+ try {
132
+ await this.setupPackage(name, config, pkg);
133
+ }
134
+ catch (err) {
135
+ this.log(`There was an error setting up the package manager: ${err.message}`);
136
+ }
137
+ }
138
+ async setupPackage(name, config, pkg) {
139
+ const execAsync = promisify(exec);
140
+ const packageJson = {
141
+ name,
142
+ version: config.get('version'),
143
+ description: config.get('description'),
144
+ scripts: {},
145
+ devDependencies: {
146
+ '@swell/app-types': '^1.0.5',
147
+ },
148
+ };
149
+ const tsConfig = {
150
+ compilerOptions: {
151
+ target: 'esnext',
152
+ module: 'esnext',
153
+ lib: ['esnext', 'webworker'],
154
+ types: ['@swell/app-types'],
155
+ },
156
+ include: ['**/*.ts'],
157
+ exclude: ['node_modules'],
158
+ };
159
+ await writeJsonFile(path.join(path.dirname(config.path), 'package.json'), packageJson);
160
+ await writeJsonFile(path.join(path.dirname(config.path), 'tsconfig.json'), tsConfig);
161
+ try {
162
+ const packageManager = await this.findPackageManager(pkg);
163
+ await execAsync(`${packageManager} install`, {
164
+ cwd: path.dirname(config.path),
165
+ });
166
+ }
167
+ catch (err) {
168
+ this.error(err.message);
169
+ }
170
+ }
171
+ async findPackageManager(pkg) {
172
+ let packageManager = pkg ? pkg : '';
173
+ // Determine if system has yarn or npm install
174
+ if (packageManager) {
175
+ if (await this.doesPackageManagerExist(packageManager)) {
176
+ return packageManager;
177
+ }
178
+ }
179
+ else {
180
+ if (await this.doesPackageManagerExist('npm')) {
181
+ return 'npm';
182
+ }
183
+ else if (await this.doesPackageManagerExist('yarn')) {
184
+ return 'yarn';
185
+ }
186
+ }
187
+ }
188
+ async doesPackageManagerExist(packageManager) {
189
+ try {
190
+ await execAsync(`${packageManager} --version`);
191
+ return true;
192
+ }
193
+ catch (err) {
194
+ this.debug(`Could not find ${packageManager} on your system. Please install ${packageManager} and try again.`);
195
+ return false;
196
+ }
197
+ }
198
+ async createAppConfigFolders(config) {
199
+ for (const type of getAllConfigPaths()) {
200
+ // Create a config folder
201
+ await execAsync(`mkdir -p ${type}`, {
202
+ cwd: path.dirname(config.path),
203
+ });
204
+ // Create gitkeep file
205
+ await execAsync(`touch ${path.join(type, '.gitkeep')}`, {
206
+ cwd: path.dirname(config.path),
207
+ });
208
+ }
209
+ }
210
+ }
@@ -0,0 +1,19 @@
1
+ import { CreateCollectionCommand } from '../../create-collection-command.js';
2
+ import { ConfigType } from '../../lib/apps/index.js';
3
+ export default class CreateContent extends CreateCollectionCommand {
4
+ static description: string;
5
+ static examples: {
6
+ command: string;
7
+ description: string;
8
+ }[];
9
+ static flags: {
10
+ label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
12
+ fields: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
13
+ views: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
14
+ overwrite: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
15
+ };
16
+ static summary: string;
17
+ createType: ConfigType;
18
+ run(): Promise<void>;
19
+ }
@@ -0,0 +1,87 @@
1
+ import { checkbox } from '@inquirer/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import { CreateCollectionCommand } from '../../create-collection-command.js';
4
+ import { ConfigType } from '../../lib/apps/index.js';
5
+ import { parseFields, parseViews, } from '../../lib/create/content.js';
6
+ import { toFileName } from '../../lib/create/index.js';
7
+ export default class CreateContent extends CreateCollectionCommand {
8
+ static description = `This command assists in generating UI model configuration files. CLI will prompt for values when flags are not present.`;
9
+ static examples = [
10
+ {
11
+ command: 'swell create content',
12
+ description: 'Create content model interactively.',
13
+ },
14
+ {
15
+ command: 'swell create content visitors -v list,edit,new',
16
+ description: 'Specify views delimited by semicolons.',
17
+ },
18
+ {
19
+ command: 'swell create content visitors -f name:short_text,description:long_text,verified:boolean,visitor_count:integer,photo:image,orders:collection',
20
+ description: 'Specify fields with types delimited by semicolons',
21
+ },
22
+ {
23
+ command: 'swell create content visitors -o -f verified:short_text -v list,edit,new -d "Visitor Views"',
24
+ description: 'Specify fields, views, and description.',
25
+ },
26
+ ];
27
+ static flags = {
28
+ label: Flags.string({
29
+ char: 'l',
30
+ default: '',
31
+ description: 'content model label',
32
+ }),
33
+ description: Flags.string({
34
+ char: 'd',
35
+ default: '',
36
+ description: 'content model description',
37
+ }),
38
+ fields: Flags.string({
39
+ char: 'f',
40
+ default: '',
41
+ description: 'list of content model fields delimited by commas',
42
+ }),
43
+ views: Flags.string({
44
+ char: 'v',
45
+ default: '',
46
+ description: 'list of content model views delimited by commas, i.e. list,edit,new',
47
+ }),
48
+ overwrite: Flags.boolean({
49
+ default: false,
50
+ description: 'overwrite existing content model configuration file',
51
+ }),
52
+ };
53
+ static summary = 'Initialize a content UI model config file with properties in the content folder.';
54
+ createType = ConfigType.CONTENT;
55
+ async run() {
56
+ const { flags } = await this.parse(CreateContent);
57
+ const { label, description, collection } = await this.promptCollection();
58
+ const fileName = toFileName(collection);
59
+ const fileBody = {
60
+ collection,
61
+ };
62
+ const { fields, overwrite, views } = flags;
63
+ if (label) {
64
+ fileBody.label = label;
65
+ }
66
+ fileBody.description = description;
67
+ fileBody.fields = fields ? parseFields(fields.split(',')) : [];
68
+ if (views) {
69
+ fileBody.views = views ? parseViews(views.split(',')) : [];
70
+ }
71
+ else {
72
+ const viewsInput = await checkbox({
73
+ message: 'Which views does your content have?',
74
+ choices: [
75
+ { name: 'List view', value: 'list' },
76
+ { name: 'Edit view', value: 'edit' },
77
+ { name: 'New view', value: 'new' },
78
+ ],
79
+ });
80
+ fileBody.views = parseViews(viewsInput);
81
+ }
82
+ await this.createFile({
83
+ fileBody,
84
+ fileName,
85
+ }, overwrite);
86
+ }
87
+ }
@@ -0,0 +1,25 @@
1
+ import { CreateCommand } from '../../create-command.js';
2
+ import { ConfigType } from '../../lib/apps/index.js';
3
+ export default class CreateFunction extends CreateCommand {
4
+ static args: {
5
+ functionName: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>;
6
+ trigger: import("@oclif/core/lib/interfaces/parser.js").Arg<string | undefined, Record<string, unknown>>;
7
+ };
8
+ static description: string;
9
+ static examples: {
10
+ command: string;
11
+ description: string;
12
+ }[];
13
+ static flags: {
14
+ description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
15
+ events: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
16
+ route: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
17
+ schedule: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
18
+ overwrite: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
19
+ };
20
+ static summary: string;
21
+ createType: ConfigType;
22
+ run(): Promise<void>;
23
+ private gatherInput;
24
+ private writeFunctionFile;
25
+ }
@@ -0,0 +1,191 @@
1
+ import { input, select } from '@inquirer/prompts';
2
+ import { Args, Flags } from '@oclif/core';
3
+ import { CreateCommand } from '../../create-command.js';
4
+ import { ConfigType } from '../../lib/apps/index.js';
5
+ import { getFunctionTemplate, } from '../../lib/create/function.js';
6
+ import { toFunctionFileName } from '../../lib/create/index.js';
7
+ const PERMITTED_TRIGGERS = ['cron', 'model', 'route'];
8
+ export default class CreateFunction extends CreateCommand {
9
+ static args = {
10
+ functionName: Args.string({
11
+ description: 'function name, used in an http route if applicable',
12
+ }),
13
+ trigger: Args.string({
14
+ description: `function trigger type`,
15
+ options: PERMITTED_TRIGGERS,
16
+ }),
17
+ };
18
+ static description = `This command assists in generating functions scripts. CLI will prompt for values when flags are not present.`;
19
+ static examples = [
20
+ {
21
+ command: 'swell create function',
22
+ description: 'Create function script interactively.',
23
+ },
24
+ {
25
+ command: 'swell create function orders-subscriptions-created.ts model --events order.created,subscription.created',
26
+ description: 'Specify model event trigger of the function.',
27
+ },
28
+ {
29
+ command: 'swell create function get-frontend-data.ts route --route public',
30
+ description: 'Specify public API access.',
31
+ },
32
+ {
33
+ command: 'swell create function process-metrics.ts cron --schedule "0 0 * * *"',
34
+ description: 'Specify schedule of the cron function.',
35
+ },
36
+ ];
37
+ static flags = {
38
+ description: Flags.string({
39
+ char: 'd',
40
+ default: '',
41
+ description: 'function description',
42
+ }),
43
+ events: Flags.string({
44
+ char: 'e',
45
+ default: '',
46
+ description: 'list of data model events used with model trigger, delimited by commas',
47
+ }),
48
+ route: Flags.string({
49
+ char: 'r',
50
+ default: 'public',
51
+ description: 'access type used with route trigger',
52
+ options: ['public', 'private'],
53
+ }),
54
+ schedule: Flags.string({
55
+ char: 's',
56
+ default: '',
57
+ description: 'crontab value used with cron trigger',
58
+ }),
59
+ overwrite: Flags.boolean({
60
+ default: false,
61
+ description: 'overwrite existing function file',
62
+ }),
63
+ };
64
+ static summary = 'Initialize a functions script in JavaScript or TypeScript.';
65
+ createType = ConfigType.FUNCTION;
66
+ async run() {
67
+ const { args, flags } = await this.parse(CreateFunction);
68
+ const { functionName, trigger } = args;
69
+ const { description, events, route, schedule, overwrite } = flags;
70
+ let writeFunctionFileParams = {
71
+ description,
72
+ events,
73
+ route,
74
+ functionName: functionName || '',
75
+ language: (functionName?.includes('.ts')
76
+ ? 'ts'
77
+ : 'js'),
78
+ schedule,
79
+ trigger: trigger,
80
+ };
81
+ writeFunctionFileParams = {
82
+ ...writeFunctionFileParams,
83
+ ...(await this.gatherInput(writeFunctionFileParams)),
84
+ };
85
+ await this.writeFunctionFile(writeFunctionFileParams, overwrite);
86
+ }
87
+ async gatherInput(params) {
88
+ let language = params.language;
89
+ if (!language) {
90
+ language = await select({
91
+ choices: [
92
+ {
93
+ name: 'TypeScript',
94
+ value: 'ts',
95
+ },
96
+ {
97
+ name: 'JavaScript',
98
+ value: 'js',
99
+ },
100
+ ],
101
+ message: 'What language are you using?',
102
+ });
103
+ }
104
+ let trigger = params.trigger;
105
+ if (!trigger) {
106
+ trigger = await select({
107
+ choices: [
108
+ {
109
+ name: 'Event',
110
+ value: 'model',
111
+ },
112
+ {
113
+ name: 'Schedule',
114
+ value: 'cron',
115
+ },
116
+ {
117
+ name: 'HTTP',
118
+ value: 'route',
119
+ },
120
+ ],
121
+ message: 'How will your function be triggered?',
122
+ });
123
+ }
124
+ let events = params.events;
125
+ if (trigger === 'model' && !events) {
126
+ events = await input({
127
+ message: 'Enter event types separated by a comma',
128
+ default: 'product.created, etc...',
129
+ });
130
+ if (events === 'product.created, etc...') {
131
+ events = '';
132
+ }
133
+ }
134
+ let schedule = params.schedule;
135
+ if (trigger === 'cron' && !schedule) {
136
+ schedule = await input({
137
+ message: 'Enter the crontab value',
138
+ default: '0 0 * * *',
139
+ });
140
+ }
141
+ let route = params.route;
142
+ if (trigger === 'route' && !route) {
143
+ route = await select({
144
+ message: 'Should tbe route be public (public_key) or private (secret_key)?',
145
+ choices: [
146
+ { name: 'Public', value: 'public' },
147
+ { name: 'Private', value: 'private' },
148
+ ],
149
+ });
150
+ }
151
+ let functionName = params.functionName;
152
+ if (!functionName) {
153
+ functionName = await input({
154
+ message: 'What will the endpoint be?',
155
+ default: functionName,
156
+ });
157
+ }
158
+ let description = params.description;
159
+ if (!description) {
160
+ await input({
161
+ default: 'Does a thing when another other thing happens',
162
+ message: 'Describe what the function does',
163
+ });
164
+ }
165
+ return {
166
+ description,
167
+ events: events || '',
168
+ route: route || '',
169
+ functionName,
170
+ language,
171
+ schedule: schedule || '',
172
+ trigger,
173
+ };
174
+ }
175
+ async writeFunctionFile({ description, events, route, functionName, language, schedule, trigger, }, overwrite) {
176
+ const fileName = toFunctionFileName(functionName);
177
+ await this.createFile({
178
+ extension: language,
179
+ fileBody: getFunctionTemplate({
180
+ description,
181
+ events,
182
+ route,
183
+ functionName,
184
+ language,
185
+ schedule,
186
+ trigger,
187
+ }),
188
+ fileName,
189
+ }, overwrite);
190
+ }
191
+ }
@@ -0,0 +1,6 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class Create extends Command {
3
+ static description: string;
4
+ static examples: string[];
5
+ run(): Promise<void>;
6
+ }
@@ -0,0 +1,34 @@
1
+ import { select } from '@inquirer/prompts';
2
+ import { Command } from '@oclif/core';
3
+ export default class Create extends Command {
4
+ static description = 'Scaffold apps, models, functions, and notifications.';
5
+ static examples = ['<%= config.bin %> <%= command.id %>'];
6
+ async run() {
7
+ const createTarget = await select({
8
+ choices: [
9
+ {
10
+ name: 'App',
11
+ value: 'app',
12
+ },
13
+ {
14
+ name: 'Model',
15
+ value: 'model',
16
+ },
17
+ {
18
+ name: 'Content',
19
+ value: 'content',
20
+ },
21
+ {
22
+ name: 'Function',
23
+ value: 'function',
24
+ },
25
+ {
26
+ name: 'Notification',
27
+ value: 'notification',
28
+ },
29
+ ],
30
+ message: 'What do you want to create?',
31
+ });
32
+ this.log(JSON.stringify(createTarget));
33
+ }
34
+ }
@@ -0,0 +1,19 @@
1
+ import { CreateCollectionCommand } from '../../create-collection-command.js';
2
+ import { ConfigType } from '../../lib/apps/index.js';
3
+ export default class CreateModel extends CreateCollectionCommand {
4
+ static description: string;
5
+ static examples: {
6
+ command: string;
7
+ description: string;
8
+ }[];
9
+ static flags: {
10
+ label: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
11
+ description: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
12
+ fields: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
13
+ events: import("@oclif/core/lib/interfaces/parser.js").OptionFlag<string, import("@oclif/core/lib/interfaces/parser.js").CustomOptions>;
14
+ overwrite: import("@oclif/core/lib/interfaces/parser.js").BooleanFlag<boolean>;
15
+ };
16
+ static summary: string;
17
+ createType: ConfigType;
18
+ run(): Promise<void>;
19
+ }
@@ -0,0 +1,87 @@
1
+ import { checkbox } from '@inquirer/prompts';
2
+ import { Flags } from '@oclif/core';
3
+ import { CreateCollectionCommand } from '../../create-collection-command.js';
4
+ import { ConfigType } from '../../lib/apps/index.js';
5
+ import { toFileName } from '../../lib/create/index.js';
6
+ import { parseEvents, parseFields, } from '../../lib/create/model.js';
7
+ export default class CreateModel extends CreateCollectionCommand {
8
+ static description = `This command assists in generating data model configuration files. CLI will prompt for values when flags are not present.`;
9
+ static examples = [
10
+ {
11
+ command: 'swell create model',
12
+ description: 'Create data model configuration interactively.',
13
+ },
14
+ {
15
+ command: 'swell create model visitors -e created,updated,deleted.',
16
+ description: 'Specify events of the data model.',
17
+ },
18
+ {
19
+ command: 'swell create model visitors -f first_name:string,last_name:string,photo:file,visit_count:int,visits:link',
20
+ description: 'Specify fields of the data model.',
21
+ },
22
+ {
23
+ command: 'swell create model visitors -f first_name:string,last_name:string,photo:file,visit_count:int,visits:link -d "Visitors Tracking" -o -e created,updated,deleted',
24
+ description: 'Scaffold a data model configuration with args and flags.',
25
+ },
26
+ ];
27
+ static flags = {
28
+ label: Flags.string({
29
+ char: 'l',
30
+ default: '',
31
+ description: 'data model label, i.e. Products',
32
+ }),
33
+ description: Flags.string({
34
+ char: 'd',
35
+ default: '',
36
+ description: 'data model description',
37
+ }),
38
+ fields: Flags.string({
39
+ char: 'f',
40
+ default: '',
41
+ description: 'list of data model fields delimited by commas',
42
+ }),
43
+ events: Flags.string({
44
+ char: 'e',
45
+ default: 'created,updated,deleted',
46
+ description: 'list of data model events delimited by commas',
47
+ }),
48
+ overwrite: Flags.boolean({
49
+ default: false,
50
+ description: 'Overwrite existing data model configuration file.',
51
+ }),
52
+ };
53
+ static summary = 'Initialize a data model config file with properties in the models folder.';
54
+ createType = ConfigType.MODEL;
55
+ async run() {
56
+ const { flags } = await this.parse(CreateModel);
57
+ const { label, description, collection } = await this.promptCollection();
58
+ const fileName = toFileName(collection);
59
+ const fileBody = {
60
+ collection,
61
+ };
62
+ const { events, fields, overwrite } = flags;
63
+ if (label) {
64
+ fileBody.label = label;
65
+ }
66
+ fileBody.description = description;
67
+ fileBody.fields = fields ? parseFields(fields.split(',')) : {};
68
+ if (fileBody.events) {
69
+ fileBody.events = events ? parseEvents(events.split(',')) : {};
70
+ }
71
+ else {
72
+ const eventsInput = await checkbox({
73
+ message: 'Which events should be captured by default?',
74
+ choices: [
75
+ { name: 'created', value: 'created' },
76
+ { name: 'updated', value: 'updated' },
77
+ { name: 'deleted', value: 'deleted' },
78
+ ],
79
+ });
80
+ fileBody.events = parseEvents(eventsInput);
81
+ }
82
+ await this.createFile({
83
+ fileBody,
84
+ fileName,
85
+ }, overwrite);
86
+ }
87
+ }