@swell/cli 2.9.4 → 2.9.5

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 (80) hide show
  1. package/dist/app-command.d.ts +2 -3
  2. package/dist/app-command.js +3 -6
  3. package/dist/commands/app/dev.d.ts +2 -2
  4. package/dist/commands/app/dev.js +49 -33
  5. package/dist/commands/app/frontend/dev.js +12 -6
  6. package/dist/commands/app/push.d.ts +1 -0
  7. package/dist/commands/app/push.js +3 -3
  8. package/dist/commands/app/release.js +2 -2
  9. package/dist/commands/create/app.d.ts +1 -1
  10. package/dist/commands/create/app.js +1 -1
  11. package/dist/commands/create/frontend.js +3 -3
  12. package/dist/commands/create/tests.js +10 -8
  13. package/dist/commands/inspect/extensions.js +4 -4
  14. package/dist/commands/schema.js +21 -18
  15. package/dist/commands/theme/dev.js +5 -5
  16. package/dist/commands/theme/push.d.ts +1 -0
  17. package/dist/commands/theme/push.js +3 -3
  18. package/dist/create-app-command.js +2 -2
  19. package/dist/create-config-command.d.ts +1 -1
  20. package/dist/create-config-command.js +3 -3
  21. package/dist/help/custom-help.d.ts +1 -1
  22. package/dist/help/types.d.ts +1 -1
  23. package/dist/lib/api.d.ts +1 -0
  24. package/dist/lib/api.js +1 -1
  25. package/dist/lib/app-config.d.ts +13 -8
  26. package/dist/lib/app-config.js +25 -23
  27. package/dist/lib/apps/app-config.d.ts +5 -5
  28. package/dist/lib/apps/app-config.js +53 -37
  29. package/dist/lib/apps/index.d.ts +15 -14
  30. package/dist/lib/apps/index.js +40 -23
  31. package/dist/lib/apps/paths.d.ts +1 -1
  32. package/dist/lib/apps/paths.js +3 -3
  33. package/dist/lib/bundle.js +26 -17
  34. package/dist/lib/config.d.ts +8 -8
  35. package/dist/lib/config.js +8 -10
  36. package/dist/lib/constants.d.ts +9 -9
  37. package/dist/lib/create/content.d.ts +6 -6
  38. package/dist/lib/create/content.js +7 -8
  39. package/dist/lib/create/function.d.ts +5 -6
  40. package/dist/lib/create/function.js +7 -8
  41. package/dist/lib/create/index.d.ts +8 -9
  42. package/dist/lib/create/index.js +7 -8
  43. package/dist/lib/create/model.d.ts +4 -4
  44. package/dist/lib/create/model.js +4 -5
  45. package/dist/lib/create/notification.d.ts +2 -3
  46. package/dist/lib/create/setting.d.ts +4 -4
  47. package/dist/lib/create/setting.js +3 -4
  48. package/dist/lib/create/tests/types.d.ts +3 -4
  49. package/dist/lib/create/tests.d.ts +1 -2
  50. package/dist/lib/create/tests.js +12 -13
  51. package/dist/lib/create/webhook.d.ts +6 -6
  52. package/dist/lib/create/webhook.js +15 -10
  53. package/dist/lib/function-source-analysis.js +3 -3
  54. package/dist/lib/info.d.ts +1 -1
  55. package/dist/lib/logs/index.d.ts +1 -0
  56. package/dist/lib/logs/line-output.d.ts +1 -0
  57. package/dist/lib/logs/line-output.js +12 -4
  58. package/dist/lib/logs/output.d.ts +1 -0
  59. package/dist/lib/logs/table-output.d.ts +1 -0
  60. package/dist/lib/logs/table-output.js +8 -5
  61. package/dist/lib/package-manager.d.ts +5 -5
  62. package/dist/lib/package-manager.js +9 -7
  63. package/dist/lib/proxy.js +4 -3
  64. package/dist/lib/sessions.d.ts +1 -2
  65. package/dist/lib/sessions.js +1 -2
  66. package/dist/lib/stores.d.ts +6 -6
  67. package/dist/lib/stores.js +5 -6
  68. package/dist/lib/swell-function-wrapper.d.ts +1 -193
  69. package/dist/lib/swell-function-wrapper.js +1 -1
  70. package/dist/lib/theme-sync.js +0 -5
  71. package/dist/push-app-command.d.ts +7 -6
  72. package/dist/push-app-command.js +35 -37
  73. package/dist/remote-app-command.d.ts +6 -4
  74. package/dist/remote-app-command.js +39 -25
  75. package/dist/swell-api-command.d.ts +1 -0
  76. package/dist/swell-api-command.js +3 -3
  77. package/dist/types/index.d.ts +94 -0
  78. package/dist/types/index.js +4 -0
  79. package/oclif.manifest.json +1 -1
  80. package/package.json +3 -3
@@ -1,6 +1,6 @@
1
1
  import * as esbuild from 'esbuild';
2
- import fs from 'node:fs';
3
- import path from 'node:path';
2
+ import * as fs from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
4
  import { fileURLToPath } from 'node:url';
5
5
  export async function bundleFunction(filePath) {
6
6
  try {
@@ -17,23 +17,24 @@ export async function bundleFunction(filePath) {
17
17
  const { metafile: { inputs }, outputFiles: [{ text: origCode }], } = buildResult;
18
18
  // TODO: make a separate method to get dependencies for watch command
19
19
  const dependencies = Object.keys(inputs).filter((input) => !input.startsWith('node_modules/'));
20
- let code = origCode
21
- .split('\n')
22
- .map((line) => line.trim().startsWith('module.exports')
23
- ? line.replace('module.exports', 'var moduleExports')
24
- : line)
25
- .join('\n');
20
+ let code = replaceModuleExports(origCode);
26
21
  // Remove comments with to get a unique hash in the API
27
22
  // Because esbuild puts the file name as a comment
28
23
  code = code.replaceAll(/^\n?\/\/.*/gm, '');
29
24
  // eslint-disable-next-line no-new-func
30
25
  const evalFn = new Function(`${code}\nreturn { ...moduleExports }`);
31
26
  const { config, ...moduleExports } = evalFn();
32
- code = await minifyCode(code + getSwellFunctionWrapper());
27
+ code = await getSwellFunctionWrapper()
28
+ .then((wrapper) => minifyCode(code + wrapper, {
29
+ format: 'cjs',
30
+ platform: 'node',
31
+ target: ['chrome58'],
32
+ }))
33
+ .then(replaceModuleExports);
33
34
  return { code, config, dependencies, moduleExports };
34
35
  }
35
36
  catch (error) {
36
- throw new Error(`Unable to compile function ${filePath}: ${error.message}`);
37
+ throw new Error(`Unable to compile function "${filePath}": ${error.message}`, { cause: error });
37
38
  }
38
39
  }
39
40
  export async function bundleWorkflow(filePath, analysis) {
@@ -59,12 +60,12 @@ export async function bundleWorkflow(filePath, analysis) {
59
60
  return { code, config: analysis.config, dependencies };
60
61
  }
61
62
  catch (error) {
62
- throw new Error(`Unable to compile workflow ${filePath}: ${error.message}`);
63
+ throw new Error(`Unable to compile workflow "${filePath}": ${error.message}`, { cause: error });
63
64
  }
64
65
  }
65
66
  export async function bundleComponent(filePath) {
66
67
  try {
67
- const content = fs.readFileSync(filePath, 'utf8');
68
+ const content = await fs.readFile(filePath, 'utf8');
68
69
  const stdinLoader = filePath.endsWith('.tsx') ? 'tsx' : 'jsx';
69
70
  const buildResult = await esbuild.build({
70
71
  stdin: {
@@ -98,13 +99,13 @@ export async function bundleComponent(filePath) {
98
99
  return { code, config };
99
100
  }
100
101
  catch (error) {
101
- throw new Error(`Unable to compile component ${filePath}: ${error.message}`);
102
+ throw new Error(`Unable to compile component "${filePath}": ${error.message}`, { cause: error });
102
103
  }
103
104
  }
104
- function getSwellFunctionWrapper() {
105
+ async function getSwellFunctionWrapper() {
105
106
  const __filename = fileURLToPath(import.meta.url);
106
107
  const __dirname = path.dirname(__filename);
107
- return fs.readFileSync(path.join(__dirname, './swell-function-wrapper.js'), 'utf8');
108
+ return fs.readFile(path.join(__dirname, './swell-function-wrapper.js'), 'utf8');
108
109
  }
109
110
  function getSwellWorkflowEntrypoint(filePath) {
110
111
  const workflowImport = `./${path.basename(filePath)}`;
@@ -392,9 +393,10 @@ function formatError(error) {
392
393
  }
393
394
  `;
394
395
  }
395
- async function minifyCode(code) {
396
+ async function minifyCode(code, options) {
396
397
  try {
397
398
  const result = await esbuild.transform(code, {
399
+ ...options,
398
400
  minifyIdentifiers: false,
399
401
  minifySyntax: false,
400
402
  minifyWhitespace: true,
@@ -402,6 +404,13 @@ async function minifyCode(code) {
402
404
  return result.code;
403
405
  }
404
406
  catch (error) {
405
- throw new Error('Compilation error:', error.message);
407
+ throw new Error(`Code minification failed: ${error.message}`, {
408
+ cause: error,
409
+ });
406
410
  }
407
411
  }
412
+ function replaceModuleExports(code) {
413
+ return code
414
+ .replaceAll(/^module\.exports\b/gm, 'var moduleExports')
415
+ .replaceAll(/\bmodule\.exports\b/gm, 'moduleExports');
416
+ }
@@ -1,8 +1,8 @@
1
- declare const env: any;
2
- declare function setEnv(name: string, reviewBranch?: string): {
3
- [key: string]: string;
4
- };
5
- declare function ensureLoggedIn(storeId: string): Promise<any>;
1
+ import Conf from 'conf';
2
+ import type { Store, User } from '../types/index.js';
3
+ export declare const env: Conf<Record<string, string | undefined>>;
4
+ export declare function setEnv(name: string, reviewBranch?: string): Record<string, string | undefined>;
5
+ declare function ensureLoggedIn(storeId: string): string;
6
6
  declare function get(key: string): any;
7
7
  declare function getAll(): any;
8
8
  declare function getDefaultStore(): string;
@@ -12,7 +12,7 @@ declare function getDefaultStorefront(appPath: string): {
12
12
  id: string;
13
13
  };
14
14
  declare function setDefaultStorefront(appPath: string, storefrontId: string, env?: string): void;
15
- declare function getSessionId(storeId: string): any;
15
+ declare function getSessionId(storeId: string): string | undefined;
16
16
  /**
17
17
  * Set store data for later access.
18
18
  *
@@ -27,7 +27,7 @@ declare function getSessionId(storeId: string): any;
27
27
  * @returns {void}
28
28
  */
29
29
  declare function setStore(store: Store): void;
30
- declare function getUser(): any;
30
+ declare function getUser(): User;
31
31
  declare function setUser(user: User): void;
32
32
  declare function clear(): void;
33
33
  declare const config: {
@@ -44,4 +44,4 @@ declare const config: {
44
44
  setStore: typeof setStore;
45
45
  setUser: typeof setUser;
46
46
  };
47
- export { config as default, env, setEnv };
47
+ export default config;
@@ -27,13 +27,13 @@ const configStore = new Configstore('swell', {
27
27
  }, {
28
28
  configPath,
29
29
  });
30
- const env = new Conf({
30
+ export const env = new Conf({
31
31
  configName: 'env',
32
32
  cwd: path.join(configDir, '.swell'),
33
33
  projectName: 'swell',
34
34
  projectSuffix: '',
35
35
  });
36
- function setEnv(name, reviewBranch) {
36
+ export function setEnv(name, reviewBranch) {
37
37
  let newEnv = {};
38
38
  if (name.startsWith('prod')) {
39
39
  newEnv = { ...prodEnv };
@@ -78,7 +78,7 @@ function selectAttributes(object, attributes) {
78
78
  return acc;
79
79
  }, {});
80
80
  }
81
- async function ensureLoggedIn(storeId) {
81
+ function ensureLoggedIn(storeId) {
82
82
  const currentStore = storeId || getDefaultStore();
83
83
  const sessionId = getSessionId(currentStore);
84
84
  // still not logged in
@@ -121,14 +121,12 @@ function setDefaultStorefront(appPath, storefrontId, env) {
121
121
  id: storefrontId,
122
122
  env,
123
123
  };
124
- return configStore.set('defaultStorefronts', defaultStorefronts);
124
+ configStore.set('defaultStorefronts', defaultStorefronts);
125
125
  }
126
126
  function getSessionId(storeId) {
127
127
  if (!configStore.has('stores'))
128
128
  return;
129
- const store = configStore
130
- .get('stores')
131
- .find((store) => store.storeId === storeId);
129
+ const store = configStore.get('stores').find((store) => store.storeId === storeId);
132
130
  return store?.sessionId;
133
131
  }
134
132
  /**
@@ -159,14 +157,14 @@ function setStore(store) {
159
157
  else {
160
158
  stores[storeIndex] = storeConfig;
161
159
  }
162
- return configStore.set('stores', stores);
160
+ configStore.set('stores', stores);
163
161
  }
164
162
  function getUser() {
165
163
  return configStore.get('user');
166
164
  }
167
165
  function setUser(user) {
168
166
  const userConfig = selectAttributes(user, ['name', 'email']);
169
- return configStore.set('user', userConfig);
167
+ configStore.set('user', userConfig);
170
168
  }
171
169
  function clear() {
172
170
  return configStore.clear();
@@ -185,4 +183,4 @@ const config = {
185
183
  setStore,
186
184
  setUser,
187
185
  };
188
- export { config as default, env, setEnv };
186
+ export default config;
@@ -1,9 +1,9 @@
1
- export declare const API_BASE_URL: any;
2
- export declare const LOCAL_PROXY_PROVIDER: any;
3
- export declare const SCHEMAS_BASE_URL: any;
4
- export declare function getAdminApiBaseUrl(storeId: string): any;
5
- export declare function getFrontendApiBaseUrl(storeId: string): any;
6
- export declare function getLoginHost(storeId?: string): any;
7
- export declare function getAppFrontendHost(storeId: string, installedAppId: string): any;
8
- export declare function getStorefrontFrontendHost(storefrontSlug: string, branchId?: string): any;
9
- export declare function getLocalFrontendHost(storeId: string, localId: string): any;
1
+ export declare const API_BASE_URL: string;
2
+ export declare const LOCAL_PROXY_PROVIDER: string;
3
+ export declare const SCHEMAS_BASE_URL: string;
4
+ export declare function getAdminApiBaseUrl(storeId: string): string;
5
+ export declare function getFrontendApiBaseUrl(storeId: string): string;
6
+ export declare function getLoginHost(storeId?: string): string;
7
+ export declare function getAppFrontendHost(storeId: string, installedAppId: string): string;
8
+ export declare function getStorefrontFrontendHost(storefrontSlug: string, branchId?: string): string;
9
+ export declare function getLocalFrontendHost(storeId: string, localId: string): string;
@@ -1,4 +1,4 @@
1
- interface CreateContentFileBody {
1
+ export interface CreateContentFileBody {
2
2
  $schema: string;
3
3
  collection: string;
4
4
  description?: string;
@@ -19,9 +19,9 @@ interface ContentFieldProps {
19
19
  label: string;
20
20
  type?: ContentType;
21
21
  }
22
- declare const validateViews: (values: string[], onError: (msg: string, options: {
22
+ export declare function validateViews(values: string[], onError: (msg: string, options: {
23
23
  exit: number;
24
- }) => never) => void;
25
- declare const parseViews: (views: string[]) => ContentViewProps[];
26
- declare const parseFields: (fields: string[]) => ContentFieldProps[];
27
- export { CreateContentFileBody, parseFields, parseViews, validateViews };
24
+ }) => never): void;
25
+ export declare function parseViews(views: string[]): ContentViewProps[];
26
+ export declare function parseFields(fields: string[]): ContentFieldProps[];
27
+ export {};
@@ -1,12 +1,12 @@
1
1
  import { titleize } from 'inflection';
2
2
  const validContentViewValues = ['list', 'edit', 'new'];
3
- const validateViews = (values, onError) => {
3
+ export function validateViews(values, onError) {
4
4
  const invalid = values.filter((v) => !validContentViewValues.includes(v));
5
5
  if (invalid.length > 0) {
6
6
  onError(`Invalid view(s): ${invalid.join(', ')}\n\nValid views: ${validContentViewValues.join(', ')}\n\nExample: swell create content visitors -v list,edit,new -y`, { exit: 1 });
7
7
  }
8
- };
9
- const parseViews = (views) => {
8
+ }
9
+ export function parseViews(views) {
10
10
  if (views.length === 0) {
11
11
  return [];
12
12
  }
@@ -14,14 +14,14 @@ const parseViews = (views) => {
14
14
  for (const viewId of views) {
15
15
  viewResponse.push({
16
16
  id: viewId,
17
- ...(viewId === 'list' ? { nav: {} } : {}),
17
+ ...(viewId === 'list' ? { nav: {} } : undefined),
18
18
  fields: [],
19
19
  tabs: [],
20
20
  });
21
21
  }
22
22
  return viewResponse;
23
- };
24
- const parseFields = (fields) => {
23
+ }
24
+ export function parseFields(fields) {
25
25
  if (fields.length === 0) {
26
26
  return [];
27
27
  }
@@ -43,5 +43,4 @@ const parseFields = (fields) => {
43
43
  }
44
44
  }
45
45
  return fieldResponse;
46
- };
47
- export { parseFields, parseViews, validateViews };
46
+ }
@@ -1,10 +1,10 @@
1
- type FunctionType = 'cron' | 'model' | 'route' | 'workflow';
2
- type FunctionLanguage = 'js' | 'ts';
3
- interface CreateFunctionArgs {
1
+ export type FunctionType = 'cron' | 'model' | 'route' | 'workflow';
2
+ export type FunctionLanguage = 'js' | 'ts';
3
+ export interface CreateFunctionArgs {
4
4
  functionName: string;
5
5
  trigger: FunctionType;
6
6
  }
7
- interface WriteFunctionFileParams {
7
+ export interface WriteFunctionFileParams {
8
8
  description: string;
9
9
  events: string;
10
10
  extension?: string;
@@ -14,5 +14,4 @@ interface WriteFunctionFileParams {
14
14
  schedule: string;
15
15
  trigger: FunctionType;
16
16
  }
17
- declare const getFunctionTemplate: ({ description, events, extension, functionName, language, route, schedule, trigger, }: WriteFunctionFileParams) => string;
18
- export { CreateFunctionArgs, FunctionLanguage, FunctionType, WriteFunctionFileParams, getFunctionTemplate, };
17
+ export declare function getFunctionTemplate({ description, events, extension, functionName, language, route, schedule, trigger, }: WriteFunctionFileParams): string;
@@ -1,4 +1,4 @@
1
- const getFunctionTemplate = ({ description, events, extension, functionName, language, route, schedule, trigger, }) => {
1
+ export function getFunctionTemplate({ description, events, extension, functionName, language, route, schedule, trigger, }) {
2
2
  if (trigger === 'workflow') {
3
3
  return getWorkflowTemplate({
4
4
  description,
@@ -6,7 +6,7 @@ const getFunctionTemplate = ({ description, events, extension, functionName, lan
6
6
  language,
7
7
  });
8
8
  }
9
- let typeAppend = ``;
9
+ let typeAppend = '';
10
10
  if (trigger === 'model') {
11
11
  const eventsList = events
12
12
  .split(/\s*,\s*/g)
@@ -43,8 +43,8 @@ export default async function (req${language === 'ts' ? ': SwellRequest' : ''})
43
43
  const { swell, store, data } = req;
44
44
  }
45
45
  `;
46
- };
47
- const getWorkflowTemplate = ({ description, functionName, language, }) => {
46
+ }
47
+ function getWorkflowTemplate({ description, functionName, language, }) {
48
48
  const className = toWorkflowClassName(functionName);
49
49
  const reqParam = language === 'ts' ? 'req: SwellWorkflowRequest' : 'req';
50
50
  const stepParam = language === 'ts' ? 'step: SwellWorkflowStep' : 'step';
@@ -65,8 +65,8 @@ export default class ${className} {
65
65
  }
66
66
  }
67
67
  `;
68
- };
69
- const toWorkflowClassName = (functionName) => {
68
+ }
69
+ function toWorkflowClassName(functionName) {
70
70
  const baseName = functionName
71
71
  .split(/[/\\]/)
72
72
  .pop()
@@ -80,5 +80,4 @@ const toWorkflowClassName = (functionName) => {
80
80
  return 'Workflow';
81
81
  }
82
82
  return /^[$A-Z_a-z]/.test(className) ? className : `Workflow${className}`;
83
- };
84
- export { getFunctionTemplate, };
83
+ }
@@ -1,13 +1,12 @@
1
- interface CreateFileParams {
1
+ export interface CreateFileParams {
2
2
  extension?: string;
3
3
  fileBody: Record<any, any> | string;
4
4
  fileName: string;
5
5
  }
6
- declare const toFileName: (value: string) => string;
7
- declare const toAppName: (value: string) => string;
8
- declare const toAppId: (value: string | undefined) => string;
9
- declare const toFunctionFileName: (value: string) => string;
10
- declare const toCollectionName: (value: string) => string;
11
- declare const toCollectionLabel: (value: string) => string;
12
- declare const toNotificationLabel: (value: string) => string;
13
- export { CreateFileParams, toAppId, toAppName, toCollectionLabel, toCollectionName, toFileName, toFunctionFileName, toNotificationLabel, };
6
+ export declare const toFileName: (value: string) => string;
7
+ export declare const toAppName: (value: string) => string;
8
+ export declare const toAppId: (value: string | undefined) => string;
9
+ export declare const toFunctionFileName: (value: string) => string;
10
+ export declare const toCollectionName: (value: string) => string;
11
+ export declare const toCollectionLabel: (value: string) => string;
12
+ export declare const toNotificationLabel: (value: string) => string;
@@ -1,14 +1,14 @@
1
1
  import { dasherize, pluralize, titleize, underscore } from 'inflection';
2
2
  // Example: 'My Thing' => 'my-thing'
3
- const toFileName = (value) => dasherize(underscore(value.split('.')[0].replace(' ', '_'))).toLowerCase();
3
+ export const toFileName = (value) => dasherize(underscore(value.split('.')[0].replace(' ', '_'))).toLowerCase();
4
4
  // Example: 'my-things' => 'My Things'
5
- const toAppName = (value) => titleize(value)
5
+ export const toAppName = (value) => titleize(value)
6
6
  .replaceAll(/[_\s-:./-]+/g, ' ')
7
7
  .replaceAll(/([a-z])([A-Z])/g, '$1 $2')
8
8
  .replaceAll(/(\d)([a-z])/gi, '$1 $2')
9
9
  .replaceAll(/([a-z])(\d)/gi, '$1 $2');
10
10
  // Example: 'My App' => 'my_app'
11
- const toAppId = (value) => String(value || '')
11
+ export const toAppId = (value) => String(value || '')
12
12
  .replaceAll(/[^\s\w./:-]/g, '')
13
13
  .replaceAll(/[_\s-:./]+/g, '_')
14
14
  .replaceAll(/^_+|_+$/g, '')
@@ -16,11 +16,10 @@ const toAppId = (value) => String(value || '')
16
16
  .toLowerCase();
17
17
  // Example: 'My Thing' => 'my-thing'
18
18
  // And: 'myThing' => 'myThing'
19
- const toFunctionFileName = (value) => value.split('.')[0].replace(' ', '-');
19
+ export const toFunctionFileName = (value) => value.split('.')[0].replace(' ', '-');
20
20
  // Example: 'My Thing' => 'my-things'
21
- const toCollectionName = (value) => pluralize(value.replaceAll(/[^A-Za-z]/g, '-').replace(' ', '')).toLowerCase();
21
+ export const toCollectionName = (value) => pluralize(value.replaceAll(/[^A-Za-z]/g, '-').replace(' ', '')).toLowerCase();
22
22
  // Example: 'my-things' => 'My Things'
23
- const toCollectionLabel = (value) => pluralize(titleize(value).replace('-', ' '));
23
+ export const toCollectionLabel = (value) => pluralize(titleize(value).replace('-', ' '));
24
24
  // Example: 'order-receipt' => 'Order Receipt'
25
- const toNotificationLabel = (value) => titleize(value).replace('-', ' ');
26
- export { toAppId, toAppName, toCollectionLabel, toCollectionName, toFileName, toFunctionFileName, toNotificationLabel, };
25
+ export const toNotificationLabel = (value) => titleize(value).replace('-', ' ');
@@ -1,4 +1,4 @@
1
- interface CreateModelFileBody {
1
+ export interface CreateModelFileBody {
2
2
  $schema: string;
3
3
  collection?: string;
4
4
  description?: string;
@@ -18,6 +18,6 @@ type FieldType = 'collection' | 'currency' | 'image' | 'int' | 'link' | 'string'
18
18
  interface ModelFieldTypeObject {
19
19
  type: FieldType;
20
20
  }
21
- declare const parseFields: (fields: string[]) => ModelFieldResponse;
22
- declare const parseEvents: (events: string[]) => ModelEventObject;
23
- export { CreateModelFileBody, parseEvents, parseFields };
21
+ export declare function parseFields(fields: string[]): ModelFieldResponse;
22
+ export declare function parseEvents(events: string[]): ModelEventObject;
23
+ export {};
@@ -1,4 +1,4 @@
1
- const parseFields = (fields) => {
1
+ export function parseFields(fields) {
2
2
  if (fields.length === 0) {
3
3
  return {};
4
4
  }
@@ -12,8 +12,8 @@ const parseFields = (fields) => {
12
12
  }
13
13
  }
14
14
  return fieldResponse;
15
- };
16
- const parseEvents = (events) => {
15
+ }
16
+ export function parseEvents(events) {
17
17
  if (events.length === 0) {
18
18
  return {};
19
19
  }
@@ -26,5 +26,4 @@ const parseEvents = (events) => {
26
26
  return {
27
27
  types: eventTypes,
28
28
  };
29
- };
30
- export { parseEvents, parseFields };
29
+ }
@@ -1,4 +1,4 @@
1
- interface WriteNotificationsFileParams {
1
+ export interface WriteNotificationsFileParams {
2
2
  admin?: boolean;
3
3
  description: string;
4
4
  event: string;
@@ -7,7 +7,7 @@ interface WriteNotificationsFileParams {
7
7
  once?: boolean;
8
8
  subject: string;
9
9
  }
10
- interface CreateNotificationFileBody {
10
+ export interface CreateNotificationFileBody {
11
11
  $schema: string;
12
12
  admin?: boolean;
13
13
  collection: string;
@@ -23,4 +23,3 @@ interface CreateNotificationFileBody {
23
23
  sample?: Record<any, any>;
24
24
  subject: string;
25
25
  }
26
- export { CreateNotificationFileBody, WriteNotificationsFileParams };
@@ -1,4 +1,4 @@
1
- interface CreateSettingFileBody {
1
+ export interface CreateSettingFileBody {
2
2
  $schema: string;
3
3
  description?: string;
4
4
  fields: SettingFieldProps[];
@@ -10,6 +10,6 @@ interface SettingFieldProps {
10
10
  type?: SettingFieldType;
11
11
  }
12
12
  type SettingFieldType = 'asset' | 'basic_html' | 'boolean' | 'category_lookup' | 'checkbox' | 'checkboxes' | 'collection' | 'color' | 'color_scheme' | 'color_scheme_group' | 'currency' | 'customer_lookup' | 'date' | 'datetime' | 'document' | 'dropdown' | 'email' | 'field_group' | 'font_family' | 'generic_lookup' | 'html' | 'icon' | 'image' | 'long_text' | 'lookup' | 'markdown' | 'number' | 'percent' | 'phone' | 'product_lookup' | 'radio' | 'rich_html' | 'rich_text' | 'select' | 'short_text' | 'slider' | 'slug' | 'tags' | 'text' | 'textarea' | 'time' | 'toggle' | 'url' | 'variant_lookup' | 'video';
13
- declare const parseFields: (fields: string[]) => SettingFieldProps[];
14
- declare const toSettingLabel: (value: string) => string;
15
- export { CreateSettingFileBody, parseFields, toSettingLabel };
13
+ export declare function parseFields(fields: string[]): SettingFieldProps[];
14
+ export declare const toSettingLabel: (value: string) => string;
15
+ export {};
@@ -1,5 +1,5 @@
1
1
  import { titleize } from 'inflection';
2
- const parseFields = (fields) => {
2
+ export function parseFields(fields) {
3
3
  if (fields.length === 0) {
4
4
  return [];
5
5
  }
@@ -21,7 +21,6 @@ const parseFields = (fields) => {
21
21
  }
22
22
  }
23
23
  return fieldResponse;
24
- };
24
+ }
25
25
  // Example: 'api-config' => 'Api Config'
26
- const toSettingLabel = (value) => titleize(value).replaceAll('-', ' ');
27
- export { parseFields, toSettingLabel };
26
+ export const toSettingLabel = (value) => titleize(value).replaceAll('-', ' ');
@@ -1,14 +1,14 @@
1
- interface TestTemplateOptions {
1
+ export interface TestTemplateOptions {
2
2
  /** App id from swell.json, used for SWELL_APP_ID and settings() */
3
3
  appId: string;
4
4
  }
5
- interface WriteTestsOptions extends TestTemplateOptions {
5
+ export interface WriteTestsOptions extends TestTemplateOptions {
6
6
  /** Absolute path to the app root */
7
7
  appPath: string;
8
8
  /** Overwrite existing files if present */
9
9
  overwrite: boolean;
10
10
  }
11
- interface ScaffoldResult {
11
+ export interface ScaffoldResult {
12
12
  /** Files that were created or overwritten */
13
13
  createdFiles: string[];
14
14
  /** Files that were skipped because they already exist */
@@ -18,4 +18,3 @@ interface ScaffoldResult {
18
18
  /** Warning messages to display to user */
19
19
  warnings: string[];
20
20
  }
21
- export type { ScaffoldResult, TestTemplateOptions, WriteTestsOptions };
@@ -1,4 +1,3 @@
1
1
  import type { ScaffoldResult, WriteTestsOptions } from './tests/types.js';
2
- declare function createTestsScaffold(options: WriteTestsOptions): Promise<ScaffoldResult>;
3
- export { createTestsScaffold };
2
+ export declare function createTestsScaffold(options: WriteTestsOptions): Promise<ScaffoldResult>;
4
3
  export type { ScaffoldResult } from './tests/types.js';
@@ -1,6 +1,6 @@
1
- import * as fs from 'node:fs';
1
+ import * as fs from 'node:fs/promises';
2
2
  import * as path from 'node:path';
3
- import { filePathExists, writeFile } from '../apps/index.js';
3
+ import { filePathExistsAsync, writeFile } from '../apps/index.js';
4
4
  import { envDtsTemplate, integrationTestTemplate, mockRequestTemplate, setupGlobalsTemplate, swellClientTemplate, tsconfigTemplate, unitTestTemplate, vitestConfigTemplate, } from './tests/templates/index.js';
5
5
  const TEST_DEV_DEPENDENCIES = {
6
6
  '@cloudflare/vitest-pool-workers': 'latest',
@@ -8,15 +8,15 @@ const TEST_DEV_DEPENDENCIES = {
8
8
  '@swell/app-types': 'latest',
9
9
  };
10
10
  async function writeTextFile(filePath, contents, overwrite) {
11
- if (!overwrite && filePathExists(filePath)) {
11
+ if (!overwrite && (await filePathExistsAsync(filePath))) {
12
12
  return { created: false, skipped: true };
13
13
  }
14
14
  await writeFile(filePath, contents);
15
15
  return { created: true, skipped: false };
16
16
  }
17
- function updatePackageJson(appPath) {
17
+ async function updatePackageJson(appPath) {
18
18
  const pkgPath = path.join(appPath, 'package.json');
19
- if (!filePathExists(pkgPath)) {
19
+ if (!(await filePathExistsAsync(pkgPath))) {
20
20
  return {
21
21
  updated: false,
22
22
  warning: 'package.json not found. Run `npm init` first.',
@@ -24,7 +24,7 @@ function updatePackageJson(appPath) {
24
24
  }
25
25
  let pkgRaw;
26
26
  try {
27
- pkgRaw = fs.readFileSync(pkgPath, 'utf8');
27
+ pkgRaw = await fs.readFile(pkgPath, 'utf8');
28
28
  }
29
29
  catch (error) {
30
30
  return {
@@ -57,7 +57,7 @@ function updatePackageJson(appPath) {
57
57
  pkg.scripts = scripts;
58
58
  try {
59
59
  const next = `${JSON.stringify(pkg, null, 2)}\n`;
60
- fs.writeFileSync(pkgPath, next, 'utf8');
60
+ await fs.writeFile(pkgPath, next, 'utf8');
61
61
  return { updated: true };
62
62
  }
63
63
  catch (error) {
@@ -67,15 +67,15 @@ function updatePackageJson(appPath) {
67
67
  };
68
68
  }
69
69
  }
70
- function validatePrerequisites(appPath) {
70
+ async function validatePrerequisites(appPath) {
71
71
  const warnings = [];
72
72
  const tsconfigPath = path.join(appPath, 'tsconfig.json');
73
- if (!filePathExists(tsconfigPath)) {
73
+ if (!(await filePathExistsAsync(tsconfigPath))) {
74
74
  warnings.push('tsconfig.json not found. test/tsconfig.json extends it; create one or tests may not compile.');
75
75
  }
76
76
  return warnings;
77
77
  }
78
- async function createTestsScaffold(options) {
78
+ export async function createTestsScaffold(options) {
79
79
  const { appPath, appId, overwrite } = options;
80
80
  const result = {
81
81
  createdFiles: [],
@@ -83,7 +83,7 @@ async function createTestsScaffold(options) {
83
83
  packageJsonUpdated: false,
84
84
  warnings: [],
85
85
  };
86
- const prereqWarnings = validatePrerequisites(appPath);
86
+ const prereqWarnings = await validatePrerequisites(appPath);
87
87
  result.warnings.push(...prereqWarnings);
88
88
  const trackFile = async (relativePath, contents) => {
89
89
  const fullPath = path.join(appPath, relativePath);
@@ -103,11 +103,10 @@ async function createTestsScaffold(options) {
103
103
  await trackFile('test/helpers/mock-request.ts', mockRequestTemplate({ appId }));
104
104
  await trackFile('test/unit/example.test.ts', unitTestTemplate());
105
105
  await trackFile('test/integration/example.test.ts', integrationTestTemplate());
106
- const pkgResult = updatePackageJson(appPath);
106
+ const pkgResult = await updatePackageJson(appPath);
107
107
  result.packageJsonUpdated = pkgResult.updated;
108
108
  if (pkgResult.warning) {
109
109
  result.warnings.push(pkgResult.warning);
110
110
  }
111
111
  return result;
112
112
  }
113
- export { createTestsScaffold };
@@ -1,4 +1,4 @@
1
- interface CreateWebhookFileBody {
1
+ export interface CreateWebhookFileBody {
2
2
  $schema: string;
3
3
  description?: string;
4
4
  enabled?: boolean;
@@ -13,20 +13,20 @@ type ErrorHandler = (msg: string, options: {
13
13
  * Input: "payment.succeeded,payment.failed"
14
14
  * Output: ["payment.succeeded", "payment.failed"]
15
15
  */
16
- declare const parseEvents: (eventsInput: string) => string[];
16
+ export declare function parseEvents(eventsInput: string): string[];
17
17
  /**
18
18
  * Validate event format (model.action pattern)
19
19
  * Valid: "product.created", "payment.succeeded"
20
20
  * Invalid: "product", "created", "", ".created", "product."
21
21
  */
22
- declare const validateEventFormat: (events: string[], onError: ErrorHandler) => void;
22
+ export declare function validateEventFormat(events: string[], onError: ErrorHandler): void;
23
23
  /**
24
24
  * Validate URL format (basic check for protocol)
25
25
  */
26
- declare const validateUrl: (url: string, onError: ErrorHandler) => void;
26
+ export declare function validateUrl(url: string, onError: ErrorHandler): void;
27
27
  /**
28
28
  * Convert name to webhook label
29
29
  * "payment-handler" => "Payment Handler"
30
30
  */
31
- declare const toWebhookLabel: (value: string) => string;
32
- export { CreateWebhookFileBody, parseEvents, toWebhookLabel, validateEventFormat, validateUrl, };
31
+ export declare const toWebhookLabel: (value: string) => string;
32
+ export {};