vyriy 0.3.5 → 0.3.9

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 (38) hide show
  1. package/README.md +48 -21
  2. package/cli/args/args.js +6 -0
  3. package/cli/args/types.d.ts +5 -1
  4. package/cli/cli.js +18 -2
  5. package/commands/new/new.js +77 -6
  6. package/commands/new/types.d.ts +2 -0
  7. package/commands/publish/index.d.ts +2 -0
  8. package/commands/publish/index.js +1 -0
  9. package/commands/publish/publish.d.ts +2 -0
  10. package/commands/publish/publish.js +274 -0
  11. package/commands/publish/types.d.ts +31 -0
  12. package/index.d.ts +1 -0
  13. package/index.js +1 -0
  14. package/package.json +159 -1
  15. package/presets/base/createBaseFiles.d.ts +3 -0
  16. package/presets/base/createBaseFiles.js +307 -0
  17. package/presets/config.d.ts +28 -0
  18. package/presets/config.js +7 -0
  19. package/presets/createProjectFiles.js +4 -175
  20. package/presets/library/createLibraryUiFiles.d.ts +3 -0
  21. package/presets/library/createLibraryUiFiles.js +127 -0
  22. package/presets/packages/createPackageFiles.d.ts +3 -0
  23. package/presets/packages/createPackageFiles.js +39 -0
  24. package/presets/packages/createPackageManifest.d.ts +7 -0
  25. package/presets/packages/createPackageManifest.js +13 -0
  26. package/presets/workspaces/createWorkspaceFiles.d.ts +3 -0
  27. package/presets/workspaces/createWorkspaceFiles.js +98 -0
  28. package/project-plan/api/api.js +5 -17
  29. package/project-plan/api/types.d.ts +1 -0
  30. package/project-plan/create/create.js +68 -77
  31. package/project-plan/kind/kind.js +1 -16
  32. package/project-plan/types.d.ts +7 -7
  33. package/prompts/project-plan/project-plan.js +62 -24
  34. package/shared/index.d.ts +1 -0
  35. package/shared/index.js +1 -0
  36. package/shared/runCommand.d.ts +9 -0
  37. package/shared/runCommand.js +34 -0
  38. package/shared/types.d.ts +7 -0
@@ -1,179 +1,8 @@
1
- import { agentsTemplate } from './agentsTemplate.js';
2
- const json = (value) => `${JSON.stringify(value, null, 2)}\n`;
3
- const createRootPackageJson = ({ description, packageScope, projectName, }) => ({
4
- path: 'package.json',
5
- content: json({
6
- name: `${packageScope}/${projectName}`,
7
- version: '0.1.0',
8
- description,
9
- private: true,
10
- type: 'module',
11
- packageManager: 'yarn@4.14.1',
12
- engines: {
13
- node: '>=24.0.0',
14
- },
15
- scripts: {
16
- lint: 'eslint .',
17
- test: 'jest --coverage=false',
18
- build: 'tsc --pretty false',
19
- deploy: 'echo "Deploy is not configured yet."',
20
- smoke: 'echo "Smoke checks are not configured yet."',
21
- e2e: 'echo "E2E checks are not configured yet."',
22
- },
23
- devDependencies: {},
24
- workspaces: [
25
- 'packages/*',
26
- 'workspaces/*',
27
- ],
28
- }),
29
- });
30
- const createPackageManifest = ({ packageScope, workspaceName, }) => ({
31
- path: `packages/${workspaceName}/package.json`,
32
- content: json({
33
- name: `${packageScope}/${workspaceName}`,
34
- version: '0.1.0',
35
- private: true,
36
- type: 'module',
37
- main: 'index.js',
38
- }),
39
- });
40
- const createPackageFiles = (plan, packagePlan) => [
41
- createPackageManifest({
42
- packageScope: plan.packageScope,
43
- workspaceName: packagePlan.name,
44
- }),
45
- {
46
- path: `packages/${packagePlan.name}/README.md`,
47
- content: `# ${plan.packageScope}/${packagePlan.name}\n\n${plan.description}\n`,
48
- },
49
- {
50
- path: `packages/${packagePlan.name}/index.ts`,
51
- content: packagePlan.kind === 'stack' ? "export * from './stack.js';\n" : "export type * from './types.js';\n",
52
- },
53
- ...(packagePlan.kind === 'stack'
54
- ? [
55
- {
56
- path: `packages/${packagePlan.name}/stack.ts`,
57
- content: 'export type StackName = string;\n',
58
- },
59
- {
60
- path: `packages/${packagePlan.name}/stack.test.ts`,
61
- content: "import { describe, expect, it } from '@jest/globals';\n\ndescribe('stack', () => {\n it('has a test harness', () => {\n expect(true).toBe(true);\n });\n});\n",
62
- },
63
- ]
64
- : [
65
- {
66
- path: `packages/${packagePlan.name}/types.ts`,
67
- content: 'export type PackageName = string;\n',
68
- },
69
- {
70
- path: `packages/${packagePlan.name}/${packagePlan.name}.test.ts`,
71
- content: "import { describe, expect, it } from '@jest/globals';\n\ndescribe('package', () => {\n it('has a test harness', () => {\n expect(true).toBe(true);\n });\n});\n",
72
- },
73
- ]),
74
- ];
75
- const createWorkspaceFiles = (plan, workspacePlan) => [
76
- {
77
- path: `workspaces/${workspacePlan.name}/package.json`,
78
- content: json({
79
- name: `${plan.packageScope}/${workspacePlan.name}-workspace`,
80
- version: '0.1.0',
81
- private: true,
82
- type: 'module',
83
- main: 'index.js',
84
- }),
85
- },
86
- {
87
- path: `workspaces/${workspacePlan.name}/index.ts`,
88
- content: 'export type WorkspaceName = string;\n',
89
- },
90
- {
91
- path: `workspaces/${workspacePlan.name}/${workspacePlan.name}.test.ts`,
92
- content: "import { describe, expect, it } from '@jest/globals';\n\ndescribe('workspace', () => {\n it('has a test harness', () => {\n expect(true).toBe(true);\n });\n});\n",
93
- },
94
- ];
95
- const shouldCreateStylelintConfig = (plan) => plan.features.some((feature) => [
96
- 'react',
97
- 'webpack',
98
- ].includes(feature));
1
+ import { createBaseFiles } from './base/createBaseFiles.js';
2
+ import { createPackageFiles } from './packages/createPackageFiles.js';
3
+ import { createWorkspaceFiles } from './workspaces/createWorkspaceFiles.js';
99
4
  export const createProjectFiles = (plan) => [
100
- createRootPackageJson(plan),
101
- {
102
- path: 'README.md',
103
- content: `# ${plan.projectName}\n\n${plan.description}\n`,
104
- },
105
- {
106
- path: 'doc.mdx',
107
- content: "import { Meta, Markdown } from '@storybook/addon-docs/blocks';\nimport ReadMe from './README.md?raw';\n\n<Meta title=\"Project/README\" />\n\n<Markdown>{ReadMe}</Markdown>\n",
108
- },
109
- {
110
- path: 'AGENTS.md',
111
- content: agentsTemplate,
112
- },
113
- {
114
- path: '.editorconfig',
115
- content: 'root = true\n\n[*]\ncharset = utf-8\nend_of_line = lf\ninsert_final_newline = true\nindent_style = space\nindent_size = 2\n',
116
- },
117
- {
118
- path: '.gitignore',
119
- content: 'node_modules/\ndist/\ncoverage/\n.yarn/cache/\n.env\n',
120
- },
121
- {
122
- path: '.npmrc',
123
- content: 'engine-strict=true\n',
124
- },
125
- {
126
- path: '.nvmrc',
127
- content: '24\n',
128
- },
129
- {
130
- path: '.yarnrc.yml',
131
- content: 'nodeLinker: node-modules\n',
132
- },
133
- {
134
- path: 'yarn.lock',
135
- content: '',
136
- },
137
- {
138
- path: 'tsconfig.json',
139
- content: json({
140
- extends: '@vyriy/typescript-config/index.json',
141
- compilerOptions: {
142
- noEmit: false,
143
- },
144
- include: [
145
- 'packages/**/*.ts',
146
- 'packages/**/*.tsx',
147
- 'workspaces/**/*.ts',
148
- 'workspaces/**/*.tsx',
149
- '*.ts',
150
- ],
151
- }),
152
- },
153
- {
154
- path: 'prettier.config.ts',
155
- content: "export { default } from '@vyriy/prettier-config';\n",
156
- },
157
- {
158
- path: '.prettierignore',
159
- content: 'node_modules\ndist\ncoverage\nstorybook-static\n',
160
- },
161
- {
162
- path: 'eslint.config.ts',
163
- content: "export { default } from '@vyriy/eslint-config';\n",
164
- },
165
- {
166
- path: 'jest.config.ts',
167
- content: "export { default } from '@vyriy/jest-config';\n",
168
- },
169
- ...(shouldCreateStylelintConfig(plan)
170
- ? [
171
- {
172
- path: 'stylelint.config.ts',
173
- content: "export { default } from '@vyriy/stylelint-config';\n",
174
- },
175
- ]
176
- : []),
5
+ ...createBaseFiles(plan),
177
6
  ...plan.packages.flatMap((packagePlan) => createPackageFiles(plan, packagePlan)),
178
7
  ...plan.workspaces.flatMap((workspacePlan) => createWorkspaceFiles(plan, workspacePlan)),
179
8
  ];
@@ -0,0 +1,3 @@
1
+ import { ProjectFile } from '../../file-plan/index.js';
2
+ import type { VyriyPackagePlan, VyriyProjectPlan } from '../../project-plan/index.js';
3
+ export declare const createLibraryUiFiles: (plan: VyriyProjectPlan, packagePlan: VyriyPackagePlan) => ProjectFile[];
@@ -0,0 +1,127 @@
1
+ import { packageVersion, peerDependencies, publishedPackageJson } from '../config.js';
2
+ import { createPackageManifest } from '../packages/createPackageManifest.js';
3
+ export const createLibraryUiFiles = (plan, packagePlan) => [
4
+ createPackageManifest({
5
+ dependencies: {
6
+ '@vyriy/cn': packageVersion(publishedPackageJson.version),
7
+ },
8
+ packageScope: plan.packageScope,
9
+ peerDependencies: {
10
+ react: peerDependencies.react,
11
+ },
12
+ workspaceName: packagePlan.name,
13
+ }),
14
+ {
15
+ path: `packages/${packagePlan.name}/README.md`,
16
+ content: `# ${plan.packageScope}/${packagePlan.name}\n\n${plan.description}\n`,
17
+ },
18
+ {
19
+ path: `packages/${packagePlan.name}/index.ts`,
20
+ content: "export * from './button.js';\n",
21
+ },
22
+ {
23
+ path: `packages/${packagePlan.name}/button.tsx`,
24
+ content: `import type { ComponentProps, FC } from 'react';
25
+ import { cn } from '@vyriy/cn';
26
+
27
+ import './button.scss';
28
+
29
+ export type ButtonProps = ComponentProps<'button'> & {
30
+ readonly variant?: 'primary' | 'secondary';
31
+ };
32
+
33
+ export type ButtonType = FC<ButtonProps>;
34
+
35
+ export const Button: ButtonType = ({ className, type = 'button', variant = 'primary', ...props }) => (
36
+ <button className={cn('button', \`button--\${variant}\`, className)} type={type} {...props} />
37
+ );
38
+ `,
39
+ },
40
+ {
41
+ path: `packages/${packagePlan.name}/button.scss`,
42
+ content: `.button {
43
+ border: 1px solid transparent;
44
+ border-radius: 6px;
45
+ cursor: pointer;
46
+ font: inherit;
47
+ padding: 0.5rem 0.875rem;
48
+ }
49
+
50
+ .button--primary {
51
+ background: #1f6feb;
52
+ color: #fff;
53
+ }
54
+
55
+ .button--secondary {
56
+ background: #fff;
57
+ border-color: #d0d7de;
58
+ color: #24292f;
59
+ }
60
+ `,
61
+ },
62
+ {
63
+ path: `packages/${packagePlan.name}/styles.d.ts`,
64
+ content: "declare module '*.scss';\n",
65
+ },
66
+ {
67
+ path: `packages/${packagePlan.name}/button.stories.tsx`,
68
+ content: `import type { Meta, StoryObj } from '@storybook/react-webpack5';
69
+
70
+ import { Button } from './button.js';
71
+
72
+ const meta = {
73
+ title: 'UI/Button',
74
+ component: Button,
75
+ args: {
76
+ children: 'Button',
77
+ },
78
+ } satisfies Meta<typeof Button>;
79
+
80
+ export default meta;
81
+
82
+ type Story = StoryObj<typeof meta>;
83
+
84
+ export const Primary: Story = {};
85
+
86
+ export const Secondary: Story = {
87
+ args: {
88
+ variant: 'secondary',
89
+ },
90
+ };
91
+ `,
92
+ },
93
+ {
94
+ path: `packages/${packagePlan.name}/button.test.tsx`,
95
+ content: `import type { ReactElement } from 'react';
96
+ import { describe, expect, it } from '@jest/globals';
97
+
98
+ import { Button } from './button.js';
99
+
100
+ type ButtonElement = ReactElement<{
101
+ readonly className: string;
102
+ readonly type: string;
103
+ }>;
104
+
105
+ describe('Button', () => {
106
+ it('creates a primary button by default', () => {
107
+ const element = Button({ children: 'Save' }) as ButtonElement;
108
+
109
+ expect(element.props.className).toBe('button button--primary');
110
+ expect(element.props.type).toBe('button');
111
+ });
112
+
113
+ it('composes secondary and custom classes', () => {
114
+ const element = Button({
115
+ children: 'Cancel',
116
+ className: 'wide',
117
+ type: 'submit',
118
+ variant: 'secondary',
119
+ }) as ButtonElement;
120
+
121
+ expect(element.props.className).toBe('button button--secondary wide');
122
+ expect(element.props.type).toBe('submit');
123
+ });
124
+ });
125
+ `,
126
+ },
127
+ ];
@@ -0,0 +1,3 @@
1
+ import { ProjectFile } from '../../file-plan/index.js';
2
+ import type { VyriyPackagePlan, VyriyProjectPlan } from '../../project-plan/index.js';
3
+ export declare const createPackageFiles: (plan: VyriyProjectPlan, packagePlan: VyriyPackagePlan) => ProjectFile[];
@@ -0,0 +1,39 @@
1
+ import { createLibraryUiFiles } from '../library/createLibraryUiFiles.js';
2
+ import { createPackageManifest } from './createPackageManifest.js';
3
+ const createGenericPackageFiles = (plan, packagePlan) => [
4
+ createPackageManifest({
5
+ packageScope: plan.packageScope,
6
+ workspaceName: packagePlan.name,
7
+ }),
8
+ {
9
+ path: `packages/${packagePlan.name}/README.md`,
10
+ content: `# ${plan.packageScope}/${packagePlan.name}\n\n${plan.description}\n`,
11
+ },
12
+ {
13
+ path: `packages/${packagePlan.name}/index.ts`,
14
+ content: packagePlan.kind === 'stack' ? "export * from './stack.js';\n" : "export type * from './types.js';\n",
15
+ },
16
+ ...(packagePlan.kind === 'stack'
17
+ ? [
18
+ {
19
+ path: `packages/${packagePlan.name}/stack.ts`,
20
+ content: 'export type StackName = string;\n',
21
+ },
22
+ {
23
+ path: `packages/${packagePlan.name}/stack.test.ts`,
24
+ content: "import { describe, expect, it } from '@jest/globals';\n\ndescribe('stack', () => {\n it('has a test harness', () => {\n expect(true).toBe(true);\n });\n});\n",
25
+ },
26
+ ]
27
+ : [
28
+ {
29
+ path: `packages/${packagePlan.name}/types.ts`,
30
+ content: 'export type PackageName = string;\n',
31
+ },
32
+ {
33
+ path: `packages/${packagePlan.name}/${packagePlan.name}.test.ts`,
34
+ content: "import { describe, expect, it } from '@jest/globals';\n\ndescribe('package', () => {\n it('has a test harness', () => {\n expect(true).toBe(true);\n });\n});\n",
35
+ },
36
+ ]),
37
+ ];
38
+ const createPresetPackageFiles = (plan, packagePlan) => plan.preset === 'library' && packagePlan.kind === 'ui' ? createLibraryUiFiles(plan, packagePlan) : undefined;
39
+ export const createPackageFiles = (plan, packagePlan) => createPresetPackageFiles(plan, packagePlan) ?? createGenericPackageFiles(plan, packagePlan);
@@ -0,0 +1,7 @@
1
+ import { ProjectFile } from '../../file-plan/index.js';
2
+ export declare const createPackageManifest: ({ dependencies, packageScope, peerDependencies, workspaceName, }: {
3
+ readonly dependencies?: Record<string, string>;
4
+ readonly packageScope: string;
5
+ readonly peerDependencies?: Record<string, string>;
6
+ readonly workspaceName: string;
7
+ }) => ProjectFile;
@@ -0,0 +1,13 @@
1
+ import { json } from '../config.js';
2
+ export const createPackageManifest = ({ dependencies = {}, packageScope, peerDependencies = {}, workspaceName, }) => ({
3
+ path: `packages/${workspaceName}/package.json`,
4
+ content: json({
5
+ name: `${packageScope}/${workspaceName}`,
6
+ version: '0.0.0',
7
+ private: true,
8
+ type: 'module',
9
+ main: 'index.js',
10
+ ...(Object.keys(dependencies).length > 0 ? { dependencies } : {}),
11
+ ...(Object.keys(peerDependencies).length > 0 ? { peerDependencies } : {}),
12
+ }),
13
+ });
@@ -0,0 +1,3 @@
1
+ import { ProjectFile } from '../../file-plan/index.js';
2
+ import type { VyriyProjectPlan, VyriyWorkspacePlan } from '../../project-plan/index.js';
3
+ export declare const createWorkspaceFiles: (plan: VyriyProjectPlan, workspacePlan: VyriyWorkspacePlan) => ProjectFile[];
@@ -0,0 +1,98 @@
1
+ import { json, packageVersion, publishedPackageJson } from '../config.js';
2
+ const getWorkspacePath = (workspacePlan) => workspacePlan.kind === 'lambda' && workspacePlan.name === 'api'
3
+ ? `workspaces/lambda/${workspacePlan.name}`
4
+ : `workspaces/${workspacePlan.name}`;
5
+ const getWorkspacePackageName = ({ packageScope, workspacePlan, }) => workspacePlan.kind === 'lambda' && workspacePlan.name === 'api'
6
+ ? `${packageScope}/lambda-api-workspace`
7
+ : `${packageScope}/${workspacePlan.name}-workspace`;
8
+ const isApiWorkspace = (workspacePlan) => [
9
+ 'api',
10
+ 'lambda',
11
+ 'fargate',
12
+ ].includes(workspacePlan.kind);
13
+ const createApiWorkspaceDependencies = (workspacePlan) => isApiWorkspace(workspacePlan)
14
+ ? {
15
+ '@vyriy/handler': packageVersion(publishedPackageJson.version),
16
+ '@vyriy/server': packageVersion(publishedPackageJson.version),
17
+ }
18
+ : {};
19
+ const createApiHandlerFile = (workspacePath) => ({
20
+ path: `${workspacePath}/handler.ts`,
21
+ content: `import { api } from '@vyriy/handler';
22
+
23
+ export const handler = api(async (event) => ({
24
+ statusCode: 200,
25
+ body: JSON.stringify({
26
+ path: event.path,
27
+ }),
28
+ }));
29
+ `,
30
+ });
31
+ const createApiServerFile = ({ entrypoint, workspacePath, }) => ({
32
+ path: `${workspacePath}/${entrypoint}`,
33
+ content: `import { server } from '@vyriy/server';
34
+
35
+ import { handler } from './handler.js';
36
+
37
+ server(handler);
38
+ `,
39
+ });
40
+ const createDockerfile = (workspacePath) => ({
41
+ path: `${workspacePath}/Dockerfile`,
42
+ content: `FROM node:24-alpine
43
+
44
+ WORKDIR /app
45
+
46
+ COPY package.json yarn.lock .yarnrc.yml ./
47
+ COPY .yarn ./.yarn
48
+ COPY packages ./packages
49
+ COPY workspaces ./workspaces
50
+
51
+ RUN corepack enable && yarn install --immutable
52
+ RUN yarn build
53
+
54
+ CMD ["node", "workspaces/api/index.js"]
55
+ `,
56
+ });
57
+ const createApiWorkspaceFiles = (plan, workspacePlan) => {
58
+ const workspacePath = getWorkspacePath(workspacePlan);
59
+ const isLambda = workspacePlan.kind === 'lambda';
60
+ return [
61
+ createApiHandlerFile(workspacePath),
62
+ createApiServerFile({ entrypoint: isLambda ? 'server.ts' : 'index.ts', workspacePath }),
63
+ {
64
+ path: `${workspacePath}/${workspacePlan.name}.test.ts`,
65
+ content: "import { describe, expect, it } from '@jest/globals';\n\nimport { handler } from './handler.js';\n\ndescribe('api workspace', () => {\n it('exports a handler', () => {\n expect(handler).toEqual(expect.any(Function));\n });\n});\n",
66
+ },
67
+ ...(plan.features.includes('docker') && !isLambda ? [createDockerfile(workspacePath)] : []),
68
+ ];
69
+ };
70
+ export const createWorkspaceFiles = (plan, workspacePlan) => {
71
+ const workspacePath = getWorkspacePath(workspacePlan);
72
+ const dependencies = createApiWorkspaceDependencies(workspacePlan);
73
+ return [
74
+ {
75
+ path: `${workspacePath}/package.json`,
76
+ content: json({
77
+ name: getWorkspacePackageName({ packageScope: plan.packageScope, workspacePlan }),
78
+ version: '0.0.0',
79
+ private: true,
80
+ type: 'module',
81
+ main: workspacePlan.kind === 'lambda' ? 'server.js' : 'index.js',
82
+ ...(Object.keys(dependencies).length > 0 ? { dependencies } : {}),
83
+ }),
84
+ },
85
+ ...(isApiWorkspace(workspacePlan)
86
+ ? createApiWorkspaceFiles(plan, workspacePlan)
87
+ : [
88
+ {
89
+ path: `${workspacePath}/index.ts`,
90
+ content: 'export type WorkspaceName = string;\n',
91
+ },
92
+ {
93
+ path: `${workspacePath}/${workspacePlan.name}.test.ts`,
94
+ content: "import { describe, expect, it } from '@jest/globals';\n\ndescribe('workspace', () => {\n it('has a test harness', () => {\n expect(true).toBe(true);\n });\n});\n",
95
+ },
96
+ ]),
97
+ ];
98
+ };
@@ -1,30 +1,25 @@
1
1
  const apiPresets = [
2
2
  'api',
3
3
  'fullstack',
4
- 'mfe-bff',
5
- 'openmfe-bff',
6
- 'aws-serverless',
4
+ 'mfe',
7
5
  ];
8
6
  export const isApiPreset = (preset) => apiPresets.includes(preset);
9
- export const getApiRuntimeFromPreset = (preset) => preset === 'aws-serverless' ? 'lambda' : 'node';
10
- export const getDefaultApiStyleFromPreset = (preset) => preset === 'openmfe-bff' ? 'mixed' : 'rest';
7
+ export const getApiRuntimeFromPreset = () => 'docker';
8
+ export const getDefaultApiStyleFromPreset = () => 'rest';
11
9
  export const getFeaturesFromApiPlan = (api) => {
12
10
  if (!api) {
13
11
  return [];
14
12
  }
15
- if (api.style === 'mixed') {
16
- return ['rest-api', 'graphql-api'];
17
- }
18
13
  return api.style === 'rest' ? ['rest-api'] : ['graphql-api'];
19
14
  };
20
- export const createApiPlan = ({ preset, style = getDefaultApiStyleFromPreset(preset) }) => {
15
+ export const createApiPlan = ({ preset, runtime = getApiRuntimeFromPreset(preset), style = getDefaultApiStyleFromPreset(preset), }) => {
21
16
  if (!isApiPreset(preset)) {
22
17
  return undefined;
23
18
  }
24
19
  const basePlan = {
25
20
  enabled: true,
26
21
  style,
27
- runtime: getApiRuntimeFromPreset(preset),
22
+ runtime,
28
23
  };
29
24
  const restPlan = {
30
25
  rest: {
@@ -37,13 +32,6 @@ export const createApiPlan = ({ preset, style = getDefaultApiStyleFromPreset(pre
37
32
  packageName: 'graphql',
38
33
  },
39
34
  };
40
- if (style === 'mixed') {
41
- return {
42
- ...basePlan,
43
- ...restPlan,
44
- ...graphqlPlan,
45
- };
46
- }
47
35
  return style === 'rest'
48
36
  ? {
49
37
  ...basePlan,
@@ -1,6 +1,7 @@
1
1
  import { VyriyApiPlan, VyriyApiRuntime, VyriyApiStyle, VyriyFeature, VyriyPreset } from '../types.js';
2
2
  export type CreateApiPlanOptions = {
3
3
  readonly preset: VyriyPreset;
4
+ readonly runtime?: VyriyApiRuntime;
4
5
  readonly style?: VyriyApiStyle;
5
6
  };
6
7
  export type CreateApiPlan = (options: CreateApiPlanOptions) => VyriyApiPlan | undefined;