vyriy 0.5.2 → 0.5.3
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.
- package/README.md +23 -12
- package/args.js +40 -0
- package/bin/vyriy.js +1 -1
- package/cli.js +67 -0
- package/package.json +51 -6
- package/{cli/types.d.ts → types.d.ts} +7 -1
- package/cli/args.js +0 -29
- package/cli/cli.js +0 -28
- package/commands/check-env.d.ts +0 -2
- package/commands/check-env.js +0 -120
- package/commands/create/index.d.ts +0 -2
- package/commands/create/index.js +0 -130
- package/commands/create/plan/index.d.ts +0 -4
- package/commands/create/plan/index.js +0 -3
- package/commands/create/plan/plan.d.ts +0 -7
- package/commands/create/plan/plan.js +0 -35
- package/commands/create/plan/question.d.ts +0 -2
- package/commands/create/plan/question.js +0 -25
- package/commands/create/plan/types.d.ts +0 -12
- package/commands/create/preset/api.d.ts +0 -2
- package/commands/create/preset/api.js +0 -63
- package/commands/create/preset/base.d.ts +0 -2
- package/commands/create/preset/base.js +0 -159
- package/commands/create/preset/fullstack.d.ts +0 -2
- package/commands/create/preset/fullstack.js +0 -158
- package/commands/create/preset/gql.d.ts +0 -2
- package/commands/create/preset/gql.js +0 -744
- package/commands/create/preset/index.d.ts +0 -52
- package/commands/create/preset/index.js +0 -62
- package/commands/create/preset/library.d.ts +0 -2
- package/commands/create/preset/library.js +0 -247
- package/commands/create/preset/mfe.d.ts +0 -2
- package/commands/create/preset/mfe.js +0 -326
- package/commands/create/preset/rest.d.ts +0 -2
- package/commands/create/preset/rest.js +0 -242
- package/commands/create/preset/shared.d.ts +0 -116
- package/commands/create/preset/shared.js +0 -245
- package/commands/create/preset/spa.d.ts +0 -2
- package/commands/create/preset/spa.js +0 -132
- package/commands/create/preset/ssg.d.ts +0 -2
- package/commands/create/preset/ssg.js +0 -171
- package/commands/create/preset/ssr.d.ts +0 -2
- package/commands/create/preset/ssr.js +0 -179
- package/commands/create/preset/types.d.ts +0 -9
- package/commands/create/prompt/conflict-strategy.d.ts +0 -5
- package/commands/create/prompt/conflict-strategy.js +0 -22
- package/commands/create/prompt/index.d.ts +0 -6
- package/commands/create/prompt/index.js +0 -5
- package/commands/create/prompt/preset.d.ts +0 -4
- package/commands/create/prompt/preset.js +0 -11
- package/commands/create/prompt/prompt.d.ts +0 -2
- package/commands/create/prompt/prompt.js +0 -4
- package/commands/create/prompt/resolve-option.d.ts +0 -6
- package/commands/create/prompt/resolve-option.js +0 -8
- package/commands/create/prompt/scope.d.ts +0 -2
- package/commands/create/prompt/scope.js +0 -2
- package/commands/create/prompt/types.d.ts +0 -4
- package/commands/dist.d.ts +0 -2
- package/commands/dist.js +0 -287
- package/commands/help.d.ts +0 -3
- package/commands/help.js +0 -24
- package/commands/index.d.ts +0 -5
- package/commands/index.js +0 -5
- package/commands/types.d.ts +0 -44
- package/commands/version.d.ts +0 -2
- package/commands/version.js +0 -6
- /package/{cli/args.d.ts → args.d.ts} +0 -0
- /package/{cli/cli.d.ts → cli.d.ts} +0 -0
- /package/{cli/index.d.ts → index.d.ts} +0 -0
- /package/{cli/index.js → index.js} +0 -0
|
@@ -1,132 +0,0 @@
|
|
|
1
|
-
import packageJson from '../../../package.json' with { type: 'json' };
|
|
2
|
-
import { base } from './base.js';
|
|
3
|
-
import { assetsDeclarationFile, baseToolingDeps, buildPackageJson, reactComponentFiles, reactDeps, reactWorkspaceScripts, stylelintConfigFile, stylelintDeps, webpackDeps, } from './shared.js';
|
|
4
|
-
export const spa = (options) => ({
|
|
5
|
-
...base(options),
|
|
6
|
-
...stylelintConfigFile(),
|
|
7
|
-
...assetsDeclarationFile(),
|
|
8
|
-
...reactComponentFiles(),
|
|
9
|
-
'package.json': buildPackageJson(options, [
|
|
10
|
-
'packages/*',
|
|
11
|
-
'workspaces/*',
|
|
12
|
-
], reactWorkspaceScripts('spa'), {
|
|
13
|
-
...baseToolingDeps(),
|
|
14
|
-
...webpackDeps(),
|
|
15
|
-
...reactDeps(),
|
|
16
|
-
...stylelintDeps(),
|
|
17
|
-
'@vyriy/cn': `^${packageJson.version}`,
|
|
18
|
-
'@vyriy/html': `^${packageJson.version}`,
|
|
19
|
-
'@vyriy/browserslist-config': `^${packageJson.version}`,
|
|
20
|
-
}),
|
|
21
|
-
'.browserslistrc': `[development]
|
|
22
|
-
extends @vyriy/browserslist-config
|
|
23
|
-
|
|
24
|
-
[ssr]
|
|
25
|
-
extends @vyriy/browserslist-config
|
|
26
|
-
|
|
27
|
-
[production]
|
|
28
|
-
extends @vyriy/browserslist-config
|
|
29
|
-
|
|
30
|
-
[modern]
|
|
31
|
-
extends @vyriy/browserslist-config
|
|
32
|
-
`,
|
|
33
|
-
'workspaces/spa/bin/build.sh': `#!/usr/bin/env sh
|
|
34
|
-
|
|
35
|
-
set -e
|
|
36
|
-
|
|
37
|
-
scriptdir="$PWD/workspaces/spa";
|
|
38
|
-
|
|
39
|
-
NODE_ENV=production npx webpack --config $scriptdir/webpack.config.ts
|
|
40
|
-
`,
|
|
41
|
-
'workspaces/spa/bin/start.sh': `#!/usr/bin/env sh
|
|
42
|
-
|
|
43
|
-
set -e
|
|
44
|
-
|
|
45
|
-
scriptdir="$PWD/workspaces/spa";
|
|
46
|
-
|
|
47
|
-
npx webpack serve --open --config $scriptdir/webpack.config.ts
|
|
48
|
-
`,
|
|
49
|
-
'workspaces/spa/doc.mdx': `import { Meta, Markdown } from '@storybook/addon-docs/blocks';
|
|
50
|
-
import ReadMe from './README.md?raw';
|
|
51
|
-
|
|
52
|
-
<Meta title="Workspaces/SPA" />
|
|
53
|
-
|
|
54
|
-
<Markdown>{ReadMe}</Markdown>
|
|
55
|
-
`,
|
|
56
|
-
'workspaces/spa/README.md': `# ${options.name} SPA\n\n${options.description}\n`,
|
|
57
|
-
'workspaces/spa/webpack.config.ts': `import { csr, html } from '@vyriy/webpack-config';
|
|
58
|
-
import { path } from '@vyriy/path';
|
|
59
|
-
|
|
60
|
-
export default csr(
|
|
61
|
-
'@w/spa',
|
|
62
|
-
{
|
|
63
|
-
path: path('dist', 'spa'),
|
|
64
|
-
filename: 'index.js',
|
|
65
|
-
},
|
|
66
|
-
(config) => {
|
|
67
|
-
return {
|
|
68
|
-
...config,
|
|
69
|
-
plugins: [
|
|
70
|
-
...(config.plugins ?? []),
|
|
71
|
-
html({
|
|
72
|
-
title: '<title>SPA</title>',
|
|
73
|
-
body: '<div id="root"></div>',
|
|
74
|
-
}),
|
|
75
|
-
],
|
|
76
|
-
};
|
|
77
|
-
},
|
|
78
|
-
);
|
|
79
|
-
`,
|
|
80
|
-
'workspaces/spa/package.json': JSON.stringify({
|
|
81
|
-
name: '@w/spa',
|
|
82
|
-
type: 'module',
|
|
83
|
-
private: true,
|
|
84
|
-
}, null, 2) + '\n',
|
|
85
|
-
'workspaces/spa/index.tsx': `import { createRoot } from 'react-dom/client';
|
|
86
|
-
|
|
87
|
-
import { Page } from '@p/components';
|
|
88
|
-
|
|
89
|
-
import '@p/components/page/styles.scss';
|
|
90
|
-
|
|
91
|
-
createRoot(document.getElementById('root')!).render(<Page content="Test content" />);
|
|
92
|
-
`,
|
|
93
|
-
'workspaces/spa/index.test.tsx': `import type { ReactElement, ReactNode } from 'react';
|
|
94
|
-
import { describe, expect, it, jest } from '@jest/globals';
|
|
95
|
-
|
|
96
|
-
const renderMock = jest.fn<(children: ReactNode) => void>();
|
|
97
|
-
const createRootMock = jest.fn<(container: Element | DocumentFragment) => { render: typeof renderMock }>(() => ({
|
|
98
|
-
render: renderMock,
|
|
99
|
-
}));
|
|
100
|
-
const PageMock = jest.fn(({ content }: { content: string }) => <div>{content}</div>);
|
|
101
|
-
|
|
102
|
-
jest.mock('react-dom/client', () => ({
|
|
103
|
-
createRoot: createRootMock,
|
|
104
|
-
}));
|
|
105
|
-
|
|
106
|
-
jest.mock('@p/components', () => ({
|
|
107
|
-
Page: PageMock,
|
|
108
|
-
}));
|
|
109
|
-
|
|
110
|
-
describe('workspaces/spa/index.tsx', () => {
|
|
111
|
-
it('mounts the page component into the root element', async () => {
|
|
112
|
-
document.body.innerHTML = '<div id="root"></div>';
|
|
113
|
-
const rootElement = document.getElementById('root');
|
|
114
|
-
|
|
115
|
-
if (!rootElement) {
|
|
116
|
-
throw new Error('Expected root element to exist.');
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
await import('./index.js');
|
|
120
|
-
|
|
121
|
-
expect(createRootMock).toHaveBeenCalledTimes(1);
|
|
122
|
-
expect(createRootMock.mock.calls[0]?.[0]).toBe(rootElement);
|
|
123
|
-
expect(renderMock).toHaveBeenCalledTimes(1);
|
|
124
|
-
|
|
125
|
-
const renderedElement = renderMock.mock.calls[0]?.[0] as ReactElement<{ content: string }>;
|
|
126
|
-
|
|
127
|
-
expect(renderedElement.type).toBe(PageMock);
|
|
128
|
-
expect(renderedElement.props.content).toBe('Test content');
|
|
129
|
-
});
|
|
130
|
-
});
|
|
131
|
-
`,
|
|
132
|
-
});
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import packageJson from '../../../package.json' with { type: 'json' };
|
|
2
|
-
import { base } from './base.js';
|
|
3
|
-
import { assetsDeclarationFile, baseToolingDeps, buildPackageJson, reactComponentFiles, reactDeps, reactServiceFiles, reactWorkspaceScripts, stylelintConfigFile, stylelintDeps, webpackDeps, } from './shared.js';
|
|
4
|
-
export const ssg = (options) => ({
|
|
5
|
-
...base(options),
|
|
6
|
-
...stylelintConfigFile(),
|
|
7
|
-
...assetsDeclarationFile(),
|
|
8
|
-
...reactComponentFiles(),
|
|
9
|
-
...reactServiceFiles(),
|
|
10
|
-
'package.json': buildPackageJson(options, [
|
|
11
|
-
'packages/*',
|
|
12
|
-
'workspaces/*',
|
|
13
|
-
], reactWorkspaceScripts('ssg'), {
|
|
14
|
-
...baseToolingDeps(),
|
|
15
|
-
...webpackDeps(),
|
|
16
|
-
'@vyriy/script': `^${packageJson.version}`,
|
|
17
|
-
...reactDeps(),
|
|
18
|
-
...stylelintDeps(),
|
|
19
|
-
'@vyriy/cn': `^${packageJson.version}`,
|
|
20
|
-
'@vyriy/html': `^${packageJson.version}`,
|
|
21
|
-
sass: packageJson.peerDependencies.sass,
|
|
22
|
-
}),
|
|
23
|
-
'workspaces/ssg/bin/build.sh': `#!/usr/bin/env sh
|
|
24
|
-
|
|
25
|
-
set -e
|
|
26
|
-
|
|
27
|
-
scriptdir="$PWD/workspaces/ssg";
|
|
28
|
-
distdir="$PWD/dist/ssg";
|
|
29
|
-
|
|
30
|
-
NODE_ENV=production npx webpack --config $scriptdir/webpack.config.ts
|
|
31
|
-
|
|
32
|
-
yarn exec sass packages/components/page/styles.scss "$distdir/styles.css" --no-source-map --style=compressed
|
|
33
|
-
cp $scriptdir/package.json "$distdir/package.json"
|
|
34
|
-
npm pkg delete "type" --prefix "$distdir"
|
|
35
|
-
npm pkg delete "private" --prefix "$distdir"
|
|
36
|
-
`,
|
|
37
|
-
'workspaces/ssg/bin/start.sh': `#!/usr/bin/env sh
|
|
38
|
-
|
|
39
|
-
set -e
|
|
40
|
-
|
|
41
|
-
scriptdir="$PWD/workspaces/ssg";
|
|
42
|
-
distdir="$PWD/dist/ssg";
|
|
43
|
-
|
|
44
|
-
mkdir -p "$distdir"
|
|
45
|
-
yarn exec sass packages/components/page/styles.scss "$distdir/styles.css" --no-source-map
|
|
46
|
-
|
|
47
|
-
PROJECT_CWD="$distdir" NODE_ENV=production LOG_LEVEL=info "$PWD/node_modules/.bin/tsx" $scriptdir/index.tsx
|
|
48
|
-
`,
|
|
49
|
-
'workspaces/ssg/doc.mdx': `import { Meta, Markdown } from '@storybook/addon-docs/blocks';
|
|
50
|
-
import ReadMe from './README.md?raw';
|
|
51
|
-
|
|
52
|
-
<Meta title="Workspaces/SSG" />
|
|
53
|
-
|
|
54
|
-
<Markdown>{ReadMe}</Markdown>
|
|
55
|
-
`,
|
|
56
|
-
'workspaces/ssg/README.md': `# ${options.name} SSG\n\n${options.description}\n`,
|
|
57
|
-
'workspaces/ssg/webpack.config.ts': `import { path } from '@vyriy/path';
|
|
58
|
-
import { ssr, external } from '@vyriy/webpack-config';
|
|
59
|
-
|
|
60
|
-
export default ssr(
|
|
61
|
-
'@w/ssg',
|
|
62
|
-
{
|
|
63
|
-
path: path('dist', 'ssg'),
|
|
64
|
-
filename: 'index.js',
|
|
65
|
-
library: { type: 'commonjs2' },
|
|
66
|
-
},
|
|
67
|
-
(config) => ({
|
|
68
|
-
...config,
|
|
69
|
-
externals: [external({ allowlist: [/^@p/, /^@w/, /^@vyriy/] })],
|
|
70
|
-
}),
|
|
71
|
-
);
|
|
72
|
-
`,
|
|
73
|
-
'workspaces/ssg/package.json': JSON.stringify({
|
|
74
|
-
name: '@w/ssg',
|
|
75
|
-
type: 'module',
|
|
76
|
-
private: true,
|
|
77
|
-
}, null, 2) + '\n',
|
|
78
|
-
'workspaces/ssg/index.tsx': `import { mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
79
|
-
import { renderToString } from 'react-dom/server';
|
|
80
|
-
|
|
81
|
-
import { script } from '@vyriy/script';
|
|
82
|
-
import { html, minify } from '@vyriy/html';
|
|
83
|
-
import { path } from '@vyriy/path';
|
|
84
|
-
|
|
85
|
-
import { cms } from '@p/services/cms';
|
|
86
|
-
import { Page } from '@p/components';
|
|
87
|
-
|
|
88
|
-
const dashboardStyles = readFileSync(path('styles.css'), 'utf8');
|
|
89
|
-
const staticPath = path('static');
|
|
90
|
-
|
|
91
|
-
void script(async () => {
|
|
92
|
-
const content = await cms.getContent();
|
|
93
|
-
|
|
94
|
-
mkdirSync(staticPath, { recursive: true });
|
|
95
|
-
|
|
96
|
-
writeFileSync(
|
|
97
|
-
path(staticPath, 'index.html'),
|
|
98
|
-
minify(
|
|
99
|
-
html({
|
|
100
|
-
htmlAttributes: 'lang="en"',
|
|
101
|
-
title: \`<title>\${content.title}</title>\`,
|
|
102
|
-
meta: '<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
103
|
-
style: \`<style>\${dashboardStyles.trim()}</style>\`,
|
|
104
|
-
body: renderToString(<Page content={content.body} />),
|
|
105
|
-
}),
|
|
106
|
-
),
|
|
107
|
-
);
|
|
108
|
-
});
|
|
109
|
-
`,
|
|
110
|
-
'workspaces/ssg/index.test.tsx': `import { describe, expect, it, jest } from '@jest/globals';
|
|
111
|
-
|
|
112
|
-
const getContentMock = jest.fn(() =>
|
|
113
|
-
Promise.resolve({
|
|
114
|
-
title: 'Sample Content',
|
|
115
|
-
body: 'This is a sample content fetched from the CMS.',
|
|
116
|
-
}),
|
|
117
|
-
);
|
|
118
|
-
let scriptPromise: Promise<void> | undefined;
|
|
119
|
-
const scriptMock = jest.fn((handler: () => Promise<void>) => {
|
|
120
|
-
scriptPromise = handler();
|
|
121
|
-
|
|
122
|
-
return scriptPromise;
|
|
123
|
-
});
|
|
124
|
-
const nodeFs = jest.requireActual<typeof import('node:fs')>('node:fs');
|
|
125
|
-
const mkdirSyncMock = jest.fn();
|
|
126
|
-
const readFileSyncMock = jest.fn<(path: string | URL, encoding: 'utf8') => string>(
|
|
127
|
-
() => '.content { display: block; }',
|
|
128
|
-
);
|
|
129
|
-
const writeFileSyncMock = jest.fn();
|
|
130
|
-
|
|
131
|
-
jest.mock('node:fs', () => ({
|
|
132
|
-
...nodeFs,
|
|
133
|
-
mkdirSync: mkdirSyncMock,
|
|
134
|
-
readFileSync: readFileSyncMock,
|
|
135
|
-
writeFileSync: writeFileSyncMock,
|
|
136
|
-
}));
|
|
137
|
-
|
|
138
|
-
jest.mock('@vyriy/script', () => ({
|
|
139
|
-
script: scriptMock,
|
|
140
|
-
}));
|
|
141
|
-
|
|
142
|
-
jest.mock('@p/services/cms', () => ({
|
|
143
|
-
cms: {
|
|
144
|
-
getContent: getContentMock,
|
|
145
|
-
},
|
|
146
|
-
}));
|
|
147
|
-
|
|
148
|
-
describe('workspaces/ssg/index.tsx', () => {
|
|
149
|
-
it('generates a static index HTML file', async () => {
|
|
150
|
-
await import('./index.js');
|
|
151
|
-
await scriptPromise;
|
|
152
|
-
|
|
153
|
-
expect(scriptMock).toHaveBeenCalledTimes(1);
|
|
154
|
-
expect(readFileSyncMock).toHaveBeenCalledWith(expect.stringContaining('styles.css'), 'utf8');
|
|
155
|
-
expect(getContentMock).toHaveBeenCalledTimes(1);
|
|
156
|
-
expect(mkdirSyncMock).toHaveBeenCalledWith(expect.stringContaining('static'), {
|
|
157
|
-
recursive: true,
|
|
158
|
-
});
|
|
159
|
-
expect(writeFileSyncMock).toHaveBeenCalledWith(
|
|
160
|
-
expect.stringContaining('static/index.html'),
|
|
161
|
-
expect.stringContaining('<title>Sample Content</title>'),
|
|
162
|
-
);
|
|
163
|
-
|
|
164
|
-
const generatedHtml = writeFileSyncMock.mock.calls[0]?.[1] as string;
|
|
165
|
-
|
|
166
|
-
expect(generatedHtml).toContain('<style>.content { display: block; }</style>');
|
|
167
|
-
expect(generatedHtml).toContain('This is a sample content fetched from the CMS.');
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
`,
|
|
171
|
-
});
|
|
@@ -1,179 +0,0 @@
|
|
|
1
|
-
import packageJson from '../../../package.json' with { type: 'json' };
|
|
2
|
-
import { base } from './base.js';
|
|
3
|
-
import { assetsDeclarationFile, baseToolingDeps, buildPackageJson, reactComponentFiles, reactDeps, reactServiceFiles, reactWorkspaceScripts, serverDeps, stylelintConfigFile, stylelintDeps, webpackDeps, } from './shared.js';
|
|
4
|
-
export const ssr = (options) => ({
|
|
5
|
-
...base(options),
|
|
6
|
-
...stylelintConfigFile(),
|
|
7
|
-
...assetsDeclarationFile(),
|
|
8
|
-
...reactComponentFiles(),
|
|
9
|
-
...reactServiceFiles(),
|
|
10
|
-
'package.json': buildPackageJson(options, [
|
|
11
|
-
'packages/*',
|
|
12
|
-
'workspaces/*',
|
|
13
|
-
], reactWorkspaceScripts('api'), {
|
|
14
|
-
...baseToolingDeps(),
|
|
15
|
-
...webpackDeps(),
|
|
16
|
-
...serverDeps(),
|
|
17
|
-
...reactDeps(),
|
|
18
|
-
...stylelintDeps(),
|
|
19
|
-
'@vyriy/cn': `^${packageJson.version}`,
|
|
20
|
-
'@vyriy/html': `^${packageJson.version}`,
|
|
21
|
-
sass: packageJson.peerDependencies.sass,
|
|
22
|
-
}),
|
|
23
|
-
'workspaces/api/bin/build.sh': `#!/usr/bin/env sh
|
|
24
|
-
|
|
25
|
-
set -e
|
|
26
|
-
|
|
27
|
-
scriptdir="$PWD/workspaces/api";
|
|
28
|
-
distdir="$PWD/dist/api";
|
|
29
|
-
|
|
30
|
-
NODE_ENV=production npx webpack --config $scriptdir/webpack.config.ts
|
|
31
|
-
|
|
32
|
-
yarn exec sass packages/components/page/styles.scss "$distdir/styles.css" --no-source-map --style=compressed
|
|
33
|
-
cp $scriptdir/package.json "$distdir/package.json"
|
|
34
|
-
npm pkg delete "type" --prefix "$distdir"
|
|
35
|
-
npm pkg delete "private" --prefix "$distdir"
|
|
36
|
-
`,
|
|
37
|
-
'workspaces/api/bin/start.sh': `#!/usr/bin/env sh
|
|
38
|
-
|
|
39
|
-
set -e
|
|
40
|
-
|
|
41
|
-
scriptdir="$PWD/workspaces/api";
|
|
42
|
-
distdir="$PWD/dist/api";
|
|
43
|
-
|
|
44
|
-
mkdir -p "$distdir"
|
|
45
|
-
yarn exec sass packages/components/page/styles.scss "$distdir/styles.css" --no-source-map
|
|
46
|
-
|
|
47
|
-
PROJECT_CWD="$distdir" NODE_ENV=production LOG_LEVEL=info "$PWD/node_modules/.bin/tsx" $scriptdir/index.tsx
|
|
48
|
-
`,
|
|
49
|
-
'workspaces/api/doc.mdx': `import { Meta, Markdown } from '@storybook/addon-docs/blocks';
|
|
50
|
-
import ReadMe from './README.md?raw';
|
|
51
|
-
|
|
52
|
-
<Meta title="Workspaces/API" />
|
|
53
|
-
|
|
54
|
-
<Markdown>{ReadMe}</Markdown>
|
|
55
|
-
`,
|
|
56
|
-
'workspaces/api/README.md': `# ${options.name} API\n\n${options.description}\n`,
|
|
57
|
-
'workspaces/api/webpack.config.ts': `import { path } from '@vyriy/path';
|
|
58
|
-
import { ssr, external } from '@vyriy/webpack-config';
|
|
59
|
-
|
|
60
|
-
export default ssr(
|
|
61
|
-
'@w/api',
|
|
62
|
-
{
|
|
63
|
-
path: path('dist', 'api'),
|
|
64
|
-
filename: 'index.js',
|
|
65
|
-
library: { type: 'commonjs2' },
|
|
66
|
-
},
|
|
67
|
-
(config) => ({
|
|
68
|
-
...config,
|
|
69
|
-
externals: [external({ allowlist: [/^@p/, /^@w/, /^@vyriy/] })],
|
|
70
|
-
}),
|
|
71
|
-
);
|
|
72
|
-
`,
|
|
73
|
-
'workspaces/api/package.json': JSON.stringify({
|
|
74
|
-
name: '@w/api',
|
|
75
|
-
type: 'module',
|
|
76
|
-
private: true,
|
|
77
|
-
}, null, 2) + '\n',
|
|
78
|
-
'workspaces/api/index.tsx': `import { readFileSync } from 'node:fs';
|
|
79
|
-
import { renderToString } from 'react-dom/server';
|
|
80
|
-
|
|
81
|
-
import { server } from '@vyriy/server';
|
|
82
|
-
import { api } from '@vyriy/handler';
|
|
83
|
-
import { html, minify } from '@vyriy/html';
|
|
84
|
-
import { path } from '@vyriy/path';
|
|
85
|
-
|
|
86
|
-
import { cms } from '@p/services/cms';
|
|
87
|
-
import { Page } from '@p/components';
|
|
88
|
-
|
|
89
|
-
const dashboardStyles = readFileSync(path('styles.css'), 'utf8');
|
|
90
|
-
|
|
91
|
-
server(
|
|
92
|
-
api(async () => {
|
|
93
|
-
const content = await cms.getContent();
|
|
94
|
-
|
|
95
|
-
return {
|
|
96
|
-
statusCode: 200,
|
|
97
|
-
headers: {
|
|
98
|
-
'content-type': 'text/html; charset=utf-8',
|
|
99
|
-
},
|
|
100
|
-
body: minify(
|
|
101
|
-
html({
|
|
102
|
-
htmlAttributes: 'lang="en"',
|
|
103
|
-
title: \`<title>\${content.title}</title>\`,
|
|
104
|
-
meta: '<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
105
|
-
style: \`<style>\${dashboardStyles.trim()}</style>\`,
|
|
106
|
-
body: renderToString(<Page content={content.body} />),
|
|
107
|
-
}),
|
|
108
|
-
),
|
|
109
|
-
};
|
|
110
|
-
}),
|
|
111
|
-
);
|
|
112
|
-
`,
|
|
113
|
-
'workspaces/api/index.test.tsx': `import { describe, expect, it, jest } from '@jest/globals';
|
|
114
|
-
|
|
115
|
-
const apiMock = jest.fn((handler) => ({
|
|
116
|
-
handler,
|
|
117
|
-
}));
|
|
118
|
-
const getContentMock = jest.fn(() =>
|
|
119
|
-
Promise.resolve({
|
|
120
|
-
title: 'Sample Content',
|
|
121
|
-
body: 'This is a sample content fetched from the CMS.',
|
|
122
|
-
}),
|
|
123
|
-
);
|
|
124
|
-
const nodeFs = jest.requireActual<typeof import('node:fs')>('node:fs');
|
|
125
|
-
const readFileSyncMock = jest.fn<(path: string | URL, encoding: 'utf8') => string>(
|
|
126
|
-
() => '.content { display: block; }',
|
|
127
|
-
);
|
|
128
|
-
const serverMock = jest.fn();
|
|
129
|
-
|
|
130
|
-
jest.mock('node:fs', () => ({
|
|
131
|
-
...nodeFs,
|
|
132
|
-
readFileSync: readFileSyncMock,
|
|
133
|
-
}));
|
|
134
|
-
|
|
135
|
-
jest.mock('@vyriy/handler', () => ({
|
|
136
|
-
api: apiMock,
|
|
137
|
-
}));
|
|
138
|
-
|
|
139
|
-
jest.mock('@vyriy/server', () => ({
|
|
140
|
-
server: serverMock,
|
|
141
|
-
}));
|
|
142
|
-
|
|
143
|
-
jest.mock('@p/services/cms', () => ({
|
|
144
|
-
cms: {
|
|
145
|
-
getContent: getContentMock,
|
|
146
|
-
},
|
|
147
|
-
}));
|
|
148
|
-
|
|
149
|
-
describe('workspaces/api/index.tsx', () => {
|
|
150
|
-
it('starts the server with a handler that returns rendered page HTML', async () => {
|
|
151
|
-
await import('./index.js');
|
|
152
|
-
|
|
153
|
-
expect(apiMock).toHaveBeenCalledTimes(1);
|
|
154
|
-
expect(serverMock).toHaveBeenCalledTimes(1);
|
|
155
|
-
expect(serverMock).toHaveBeenCalledWith(apiMock.mock.results[0]?.value);
|
|
156
|
-
|
|
157
|
-
const handler = apiMock.mock.calls[0]?.[0] as () => Promise<{
|
|
158
|
-
statusCode: number;
|
|
159
|
-
headers: Record<string, string>;
|
|
160
|
-
body: string;
|
|
161
|
-
}>;
|
|
162
|
-
|
|
163
|
-
const response = await handler();
|
|
164
|
-
|
|
165
|
-
expect(response).toEqual({
|
|
166
|
-
statusCode: 200,
|
|
167
|
-
headers: {
|
|
168
|
-
'content-type': 'text/html; charset=utf-8',
|
|
169
|
-
},
|
|
170
|
-
body: expect.stringContaining('<title>Sample Content</title>'),
|
|
171
|
-
});
|
|
172
|
-
expect(response.body).toContain('<style>.content { display: block; }</style>');
|
|
173
|
-
expect(response.body).toContain('This is a sample content fetched from the CMS.');
|
|
174
|
-
expect(readFileSyncMock).toHaveBeenCalledWith(expect.stringContaining('styles.css'), 'utf8');
|
|
175
|
-
expect(getContentMock).toHaveBeenCalledTimes(1);
|
|
176
|
-
});
|
|
177
|
-
});
|
|
178
|
-
`,
|
|
179
|
-
});
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { PlanResult } from '../plan/types.js';
|
|
2
|
-
export type FileMap = Record<string, string>;
|
|
3
|
-
export type Preset = (options: PlanResult) => FileMap;
|
|
4
|
-
export type PresetKey = 'base' | 'library' | 'api' | 'ssr' | 'rest' | 'gql' | 'ssg' | 'spa' | 'mfe' | 'fullstack';
|
|
5
|
-
export type Presets = Partial<Record<PresetKey, {
|
|
6
|
-
name: string;
|
|
7
|
-
description: string;
|
|
8
|
-
preset: Preset;
|
|
9
|
-
}>>;
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import { stdin, stdout } from 'node:process';
|
|
2
|
-
import { createInterface } from 'node:readline/promises';
|
|
3
|
-
export const conflictStrategy = async () => {
|
|
4
|
-
console.log('\nWhat should Vyriy do?\n');
|
|
5
|
-
console.log(' 1. overwrite existing files');
|
|
6
|
-
console.log(' 2. skip existing files');
|
|
7
|
-
console.log(' 3. abort');
|
|
8
|
-
const readline = createInterface({ input: stdin, output: stdout });
|
|
9
|
-
try {
|
|
10
|
-
const answer = (await readline.question('\nWhat should Vyriy do? (abort): ')).trim().toLowerCase();
|
|
11
|
-
if (answer === '1' || answer === 'overwrite') {
|
|
12
|
-
return { overwrite: true, skipExisting: false };
|
|
13
|
-
}
|
|
14
|
-
if (answer === '2' || answer === 'skip') {
|
|
15
|
-
return { overwrite: false, skipExisting: true };
|
|
16
|
-
}
|
|
17
|
-
return undefined;
|
|
18
|
-
}
|
|
19
|
-
finally {
|
|
20
|
-
readline.close();
|
|
21
|
-
}
|
|
22
|
-
};
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { presets as appPreset } from '../preset/index.js';
|
|
2
|
-
import type { PromptOutput, PromptQuestion } from './types.js';
|
|
3
|
-
export type PresetName = keyof typeof appPreset;
|
|
4
|
-
export declare const preset: (question: PromptQuestion, output: PromptOutput) => Promise<PresetName>;
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { presets as appPreset } from '../preset/index.js';
|
|
2
|
-
import { prompt } from './prompt.js';
|
|
3
|
-
import { resolveOption } from './resolve-option.js';
|
|
4
|
-
export const preset = async (question, output) => {
|
|
5
|
-
const defaultPreset = 'base';
|
|
6
|
-
const presetNames = Object.keys(appPreset);
|
|
7
|
-
output.write('\nProject preset:\n\n');
|
|
8
|
-
presetNames.forEach((presetName, index) => output.write(` ${index + 1}. ${appPreset[presetName].name} - ${appPreset[presetName].description}\n`));
|
|
9
|
-
const presetValue = await prompt(question, '\nPreset number or name', defaultPreset);
|
|
10
|
-
return resolveOption(presetValue, presetNames, defaultPreset);
|
|
11
|
-
};
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
type ResolveOption = {
|
|
2
|
-
<OptionName extends string>(value: string, optionNames: readonly OptionName[], fallback: OptionName): OptionName;
|
|
3
|
-
<OptionName extends string>(value: string, optionNames: readonly OptionName[]): OptionName | undefined;
|
|
4
|
-
};
|
|
5
|
-
export declare const resolveOption: ResolveOption;
|
|
6
|
-
export {};
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export const resolveOption = (value, optionNames, fallback) => {
|
|
2
|
-
const normalizedValue = value.trim();
|
|
3
|
-
const numericValue = Number.parseInt(normalizedValue, 10);
|
|
4
|
-
if (Number.isInteger(numericValue)) {
|
|
5
|
-
return optionNames[numericValue - 1] ?? fallback;
|
|
6
|
-
}
|
|
7
|
-
return optionNames.find((optionName) => optionName === normalizedValue) ?? fallback;
|
|
8
|
-
};
|
package/commands/dist.d.ts
DELETED