vyriy 0.4.4 → 0.4.7
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 +11 -16
- package/commands/check-env.js +58 -3
- package/commands/create/plan/plan.d.ts +1 -1
- package/commands/create/preset/api.js +0 -2
- package/commands/create/preset/gql.js +740 -6
- package/commands/create/preset/index.d.ts +10 -0
- package/commands/create/preset/index.js +12 -0
- package/commands/create/preset/rest.js +335 -7
- package/commands/create/preset/spa.js +40 -42
- package/commands/create/preset/ssg.js +69 -71
- package/commands/create/preset/ssr.js +0 -2
- package/commands/types.d.ts +4 -5
- package/package.json +5 -8
|
@@ -29,4 +29,14 @@ export declare const presets: {
|
|
|
29
29
|
description: string;
|
|
30
30
|
preset: import("./types.js").Preset;
|
|
31
31
|
};
|
|
32
|
+
rest: {
|
|
33
|
+
name: string;
|
|
34
|
+
description: string;
|
|
35
|
+
preset: import("./types.js").Preset;
|
|
36
|
+
};
|
|
37
|
+
gql: {
|
|
38
|
+
name: string;
|
|
39
|
+
description: string;
|
|
40
|
+
preset: import("./types.js").Preset;
|
|
41
|
+
};
|
|
32
42
|
};
|
|
@@ -4,6 +4,8 @@ import { api } from './api.js';
|
|
|
4
4
|
import { ssr } from './ssr.js';
|
|
5
5
|
import { ssg } from './ssg.js';
|
|
6
6
|
import { spa } from './spa.js';
|
|
7
|
+
import { rest } from './rest.js';
|
|
8
|
+
import { gql } from './gql.js';
|
|
7
9
|
export const presets = {
|
|
8
10
|
base: {
|
|
9
11
|
name: 'Base',
|
|
@@ -35,4 +37,14 @@ export const presets = {
|
|
|
35
37
|
description: 'Preset for Single Page Application (SPA)',
|
|
36
38
|
preset: spa,
|
|
37
39
|
},
|
|
40
|
+
rest: {
|
|
41
|
+
name: 'REST',
|
|
42
|
+
description: 'Preset for simple REST API',
|
|
43
|
+
preset: rest,
|
|
44
|
+
},
|
|
45
|
+
gql: {
|
|
46
|
+
name: 'GraphQL',
|
|
47
|
+
description: 'Preset for GraphQL API',
|
|
48
|
+
preset: gql,
|
|
49
|
+
},
|
|
38
50
|
};
|
|
@@ -1,16 +1,344 @@
|
|
|
1
|
+
import packageJson from '../../../package.json' with { type: 'json' };
|
|
1
2
|
import { base } from './base.js';
|
|
2
3
|
export const rest = {
|
|
3
4
|
files: (options) => ({
|
|
4
5
|
...base.files(options),
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
'package.json': JSON.stringify({
|
|
7
|
+
name: options.name,
|
|
8
|
+
version: '0.0.0',
|
|
9
|
+
description: options.description,
|
|
10
|
+
private: true,
|
|
11
|
+
type: 'module',
|
|
12
|
+
agents: './AGENTS.md',
|
|
13
|
+
packageManager: packageJson.packageManager,
|
|
14
|
+
engines: {
|
|
15
|
+
node: packageJson.engines.node,
|
|
16
|
+
},
|
|
17
|
+
workspaces: [
|
|
18
|
+
'workspaces/*',
|
|
19
|
+
],
|
|
20
|
+
scripts: {
|
|
21
|
+
storybook: 'cross-env STORYBOOK_DISABLE_TELEMETRY=1 storybook dev -p 6006 --disable-telemetry',
|
|
22
|
+
check: 'run-s lint build test',
|
|
23
|
+
fix: "run-s 'fix:*'",
|
|
24
|
+
start: "run-p 'start:*'",
|
|
25
|
+
lint: "run-s 'lint:*'",
|
|
26
|
+
build: "run-s 'build:*'",
|
|
27
|
+
test: "run-s 'test:*'",
|
|
28
|
+
'fix:prettier': 'prettier . --write',
|
|
29
|
+
'fix:eslint': 'eslint . --fix',
|
|
30
|
+
'start:api': 'sh workspaces/api/bin/start.sh',
|
|
31
|
+
'lint:ts': 'tsc',
|
|
32
|
+
'lint:prettier': 'prettier . --check',
|
|
33
|
+
'lint:eslint': 'eslint .',
|
|
34
|
+
'build:api': 'rimraf dist && sh workspaces/api/bin/build.sh',
|
|
35
|
+
'build:storybook': 'cross-env STORYBOOK_DISABLE_TELEMETRY=1 storybook build --quiet --disable-telemetry',
|
|
36
|
+
'test:jest': 'jest',
|
|
37
|
+
postinstall: 'husky',
|
|
38
|
+
},
|
|
39
|
+
dependencies: {
|
|
40
|
+
'@vyriy/typescript-config': `^${packageJson.version}`,
|
|
41
|
+
typescript: packageJson.peerDependencies.typescript,
|
|
42
|
+
'@vyriy/prettier-config': `^${packageJson.version}`,
|
|
43
|
+
prettier: packageJson.peerDependencies.prettier,
|
|
44
|
+
'@vyriy/eslint-config': `^${packageJson.version}`,
|
|
45
|
+
eslint: packageJson.peerDependencies.eslint,
|
|
46
|
+
'@vyriy/jest-config': `^${packageJson.version}`,
|
|
47
|
+
jest: packageJson.peerDependencies.jest,
|
|
48
|
+
'@vyriy/storybook-config': `^${packageJson.version}`,
|
|
49
|
+
storybook: packageJson.peerDependencies.storybook,
|
|
50
|
+
'@vyriy/path': `^${packageJson.version}`,
|
|
51
|
+
husky: packageJson.peerDependencies.husky,
|
|
52
|
+
'npm-run-all2': packageJson.peerDependencies['npm-run-all2'],
|
|
53
|
+
'cross-env': packageJson.peerDependencies['cross-env'],
|
|
54
|
+
rimraf: packageJson.peerDependencies.rimraf,
|
|
55
|
+
'@vyriy/webpack-config': `^${packageJson.version}`,
|
|
56
|
+
'@vyriy/handler': `^${packageJson.version}`,
|
|
57
|
+
'@vyriy/server': `^${packageJson.version}`,
|
|
58
|
+
tsx: packageJson.peerDependencies.tsx,
|
|
59
|
+
'webpack-cli': packageJson.peerDependencies['webpack-cli'],
|
|
60
|
+
'@vyriy/router': `^${packageJson.version}`,
|
|
61
|
+
'@vyriy/html': `^${packageJson.version}`,
|
|
62
|
+
},
|
|
63
|
+
}, null, 2) + '\n',
|
|
64
|
+
'workspaces/api/bin/build.sh': `#!/usr/bin/env sh
|
|
65
|
+
|
|
66
|
+
set -e
|
|
67
|
+
|
|
68
|
+
scriptdir="$PWD/workspaces/api";
|
|
69
|
+
|
|
70
|
+
NODE_ENV=production npx webpack --config $scriptdir/webpack.config.ts
|
|
71
|
+
|
|
72
|
+
cp $scriptdir/package.json dist/api/package.json
|
|
73
|
+
npm pkg delete "type" --prefix dist/api
|
|
74
|
+
npm pkg delete "private" --prefix dist/api
|
|
75
|
+
`,
|
|
76
|
+
'workspaces/api/bin/start.sh': `#!/usr/bin/env sh
|
|
77
|
+
|
|
78
|
+
set -e
|
|
79
|
+
|
|
80
|
+
scriptdir="$PWD/workspaces/api";
|
|
81
|
+
|
|
82
|
+
NODE_ENV=production LOG_LEVEL=info tsx $scriptdir/index.ts
|
|
83
|
+
`,
|
|
84
|
+
'workspaces/api/doc.mdx': `import { Meta, Markdown } from '@storybook/addon-docs/blocks';
|
|
85
|
+
import ReadMe from './README.md?raw';
|
|
86
|
+
|
|
87
|
+
<Meta title="Workspaces/API" />
|
|
88
|
+
|
|
89
|
+
<Markdown>{ReadMe}</Markdown>
|
|
90
|
+
`,
|
|
91
|
+
'workspaces/api/README.md': `# ${options.name} API\n\n${options.description}\n`,
|
|
92
|
+
'workspaces/api/webpack.config.ts': `import { path } from '@vyriy/path';
|
|
93
|
+
import { ssr, external } from '@vyriy/webpack-config';
|
|
94
|
+
|
|
95
|
+
export default ssr(
|
|
96
|
+
'@w/api',
|
|
97
|
+
{
|
|
98
|
+
path: path('dist', 'api'),
|
|
99
|
+
filename: 'index.js',
|
|
100
|
+
library: { type: 'commonjs2' },
|
|
101
|
+
},
|
|
102
|
+
(config) => ({
|
|
103
|
+
...config,
|
|
104
|
+
externals: [external({ allowlist: [/^@p/, /^@w/, /^@vyriy/] })],
|
|
105
|
+
}),
|
|
106
|
+
);
|
|
107
|
+
`,
|
|
108
|
+
'workspaces/api/package.json': JSON.stringify({
|
|
109
|
+
name: '@w/api',
|
|
110
|
+
type: 'module',
|
|
111
|
+
private: true,
|
|
112
|
+
}, null, 2) + '\n',
|
|
113
|
+
'workspaces/api/index.ts': `import { server } from '@vyriy/server';
|
|
114
|
+
import { api } from '@vyriy/handler';
|
|
115
|
+
import { createRouter } from '@vyriy/router';
|
|
116
|
+
import { html, minify } from '@vyriy/html';
|
|
117
|
+
|
|
118
|
+
const router = createRouter();
|
|
119
|
+
|
|
120
|
+
router.get('/api/test', async () => {
|
|
121
|
+
return Promise.resolve({
|
|
122
|
+
headers: {
|
|
123
|
+
'content-type': 'application/json',
|
|
124
|
+
},
|
|
125
|
+
body: JSON.stringify({ test: 'ok' }),
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
router.get('/openapi.json', async () => {
|
|
130
|
+
return Promise.resolve({
|
|
131
|
+
headers: {
|
|
132
|
+
'content-type': 'application/json',
|
|
133
|
+
},
|
|
134
|
+
body: JSON.stringify({
|
|
135
|
+
openapi: '3.0.0',
|
|
136
|
+
info: {
|
|
137
|
+
title: 'REST API',
|
|
138
|
+
description: 'A minimal example of an OpenAPI definition in JSON format.',
|
|
139
|
+
version: '1.0.0',
|
|
140
|
+
},
|
|
141
|
+
servers: [
|
|
142
|
+
{
|
|
143
|
+
url: 'http://localhost:3000',
|
|
144
|
+
description: 'Local server',
|
|
145
|
+
},
|
|
146
|
+
],
|
|
147
|
+
paths: {
|
|
148
|
+
'/api/test': {
|
|
149
|
+
get: {
|
|
150
|
+
summary: 'Test endpoint',
|
|
151
|
+
operationId: 'getTest',
|
|
152
|
+
responses: {
|
|
153
|
+
'200': {
|
|
154
|
+
description: 'A successful test response',
|
|
155
|
+
content: {
|
|
156
|
+
'application/json': {
|
|
157
|
+
schema: {
|
|
158
|
+
$ref: '#/components/schemas/TestResponse',
|
|
159
|
+
},
|
|
160
|
+
example: {
|
|
161
|
+
test: 'ok',
|
|
162
|
+
},
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
},
|
|
168
|
+
},
|
|
169
|
+
},
|
|
170
|
+
components: {
|
|
171
|
+
schemas: {
|
|
172
|
+
TestResponse: {
|
|
173
|
+
type: 'object',
|
|
174
|
+
required: ['test'],
|
|
175
|
+
properties: {
|
|
176
|
+
test: {
|
|
177
|
+
type: 'string',
|
|
178
|
+
example: 'ok',
|
|
179
|
+
},
|
|
180
|
+
},
|
|
181
|
+
},
|
|
9
182
|
},
|
|
183
|
+
},
|
|
184
|
+
}),
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
router.get('/', async () => {
|
|
189
|
+
return Promise.resolve({
|
|
190
|
+
headers: {
|
|
191
|
+
'content-type': 'text/html; charset=utf-8',
|
|
10
192
|
},
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
193
|
+
body: minify(
|
|
194
|
+
html({
|
|
195
|
+
title: '<title>REST API</title>',
|
|
196
|
+
meta: '<meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" />',
|
|
197
|
+
body: [
|
|
198
|
+
'<div id="app"></div>',
|
|
199
|
+
'<script src="https://cdn.jsdelivr.net/npm/@scalar/api-reference"></script>',
|
|
200
|
+
"<script>Scalar.createApiReference('#app', { url: '/openapi.json' })</script>",
|
|
201
|
+
].join(''),
|
|
202
|
+
}),
|
|
203
|
+
),
|
|
204
|
+
});
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
server(api(async (event) => router.route(event)));
|
|
208
|
+
`,
|
|
209
|
+
'workspaces/api/index.test.ts': `import { describe, expect, it, jest } from '@jest/globals';
|
|
210
|
+
import type { APIGatewayProxyEvent } from '@vyriy/router';
|
|
211
|
+
|
|
212
|
+
const apiMock = jest.fn((handler) => ({
|
|
213
|
+
handler,
|
|
214
|
+
}));
|
|
215
|
+
const serverMock = jest.fn();
|
|
216
|
+
|
|
217
|
+
jest.mock('@vyriy/handler', () => ({
|
|
218
|
+
api: apiMock,
|
|
219
|
+
}));
|
|
220
|
+
|
|
221
|
+
jest.mock('@vyriy/server', () => ({
|
|
222
|
+
server: serverMock,
|
|
223
|
+
}));
|
|
224
|
+
|
|
225
|
+
describe('workspaces/api/index.ts', () => {
|
|
226
|
+
const getEvent = (path: string): APIGatewayProxyEvent =>
|
|
227
|
+
({
|
|
228
|
+
body: null,
|
|
229
|
+
headers: {},
|
|
230
|
+
httpMethod: 'GET',
|
|
231
|
+
path,
|
|
232
|
+
pathParameters: null,
|
|
233
|
+
queryStringParameters: null,
|
|
234
|
+
}) as APIGatewayProxyEvent;
|
|
235
|
+
|
|
236
|
+
it('starts the server with the API router handler', async () => {
|
|
237
|
+
await import('./index.js');
|
|
238
|
+
|
|
239
|
+
expect(apiMock).toHaveBeenCalledTimes(1);
|
|
240
|
+
expect(serverMock).toHaveBeenCalledTimes(1);
|
|
241
|
+
expect(serverMock).toHaveBeenCalledWith(apiMock.mock.results[0]?.value);
|
|
242
|
+
|
|
243
|
+
const handler = apiMock.mock.calls[0]?.[0] as (event: APIGatewayProxyEvent) => Promise<{
|
|
244
|
+
body: string;
|
|
245
|
+
headers?: Record<string, string>;
|
|
246
|
+
statusCode: number;
|
|
247
|
+
}>;
|
|
248
|
+
|
|
249
|
+
await expect(handler(getEvent('/api/test'))).resolves.toEqual({
|
|
250
|
+
body: JSON.stringify({
|
|
251
|
+
test: 'ok',
|
|
252
|
+
}),
|
|
253
|
+
headers: {
|
|
254
|
+
'content-type': 'application/json',
|
|
255
|
+
},
|
|
256
|
+
statusCode: 200,
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
const openApiResponse = await handler(getEvent('/openapi.json'));
|
|
260
|
+
|
|
261
|
+
expect(openApiResponse).toEqual({
|
|
262
|
+
body: expect.any(String),
|
|
263
|
+
headers: {
|
|
264
|
+
'content-type': 'application/json',
|
|
265
|
+
},
|
|
266
|
+
statusCode: 200,
|
|
267
|
+
});
|
|
268
|
+
expect(JSON.parse(openApiResponse.body)).toEqual({
|
|
269
|
+
components: {
|
|
270
|
+
schemas: {
|
|
271
|
+
TestResponse: {
|
|
272
|
+
properties: {
|
|
273
|
+
test: {
|
|
274
|
+
example: 'ok',
|
|
275
|
+
type: 'string',
|
|
276
|
+
},
|
|
277
|
+
},
|
|
278
|
+
required: ['test'],
|
|
279
|
+
type: 'object',
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
},
|
|
283
|
+
info: {
|
|
284
|
+
description: 'A minimal example of an OpenAPI definition in JSON format.',
|
|
285
|
+
title: 'REST API',
|
|
286
|
+
version: '1.0.0',
|
|
287
|
+
},
|
|
288
|
+
openapi: '3.0.0',
|
|
289
|
+
paths: {
|
|
290
|
+
'/api/test': {
|
|
291
|
+
get: {
|
|
292
|
+
operationId: 'getTest',
|
|
293
|
+
responses: {
|
|
294
|
+
'200': {
|
|
295
|
+
content: {
|
|
296
|
+
'application/json': {
|
|
297
|
+
example: {
|
|
298
|
+
test: 'ok',
|
|
299
|
+
},
|
|
300
|
+
schema: {
|
|
301
|
+
$ref: '#/components/schemas/TestResponse',
|
|
302
|
+
},
|
|
303
|
+
},
|
|
304
|
+
},
|
|
305
|
+
description: 'A successful test response',
|
|
306
|
+
},
|
|
307
|
+
},
|
|
308
|
+
summary: 'Test endpoint',
|
|
309
|
+
},
|
|
310
|
+
},
|
|
311
|
+
},
|
|
312
|
+
servers: [
|
|
313
|
+
{
|
|
314
|
+
description: 'Local server',
|
|
315
|
+
url: 'http://localhost:3000',
|
|
14
316
|
},
|
|
317
|
+
],
|
|
318
|
+
});
|
|
319
|
+
|
|
320
|
+
const docsResponse = await handler(getEvent('/'));
|
|
321
|
+
|
|
322
|
+
expect(docsResponse).toEqual({
|
|
323
|
+
body: expect.stringContaining("Scalar.createApiReference('#app', { url: '/openapi.json' })"),
|
|
324
|
+
headers: {
|
|
325
|
+
'content-type': 'text/html; charset=utf-8',
|
|
326
|
+
},
|
|
327
|
+
statusCode: 200,
|
|
328
|
+
});
|
|
329
|
+
|
|
330
|
+
await expect(handler(getEvent('/healthcheck'))).resolves.toEqual({
|
|
331
|
+
body: JSON.stringify({
|
|
332
|
+
message: 'Not Found',
|
|
333
|
+
}),
|
|
334
|
+
statusCode: 404,
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
`,
|
|
339
|
+
}),
|
|
340
|
+
ci: {
|
|
341
|
+
...base.ci,
|
|
15
342
|
},
|
|
343
|
+
deploy: {},
|
|
16
344
|
};
|
|
@@ -51,14 +51,12 @@ export const spa = {
|
|
|
51
51
|
'@vyriy/storybook-config': `^${packageJson.version}`,
|
|
52
52
|
storybook: packageJson.peerDependencies.storybook,
|
|
53
53
|
'@vyriy/path': `^${packageJson.version}`,
|
|
54
|
-
vyriy: `^${packageJson.version}`,
|
|
55
54
|
husky: packageJson.peerDependencies.husky,
|
|
56
55
|
'npm-run-all2': packageJson.peerDependencies['npm-run-all2'],
|
|
57
56
|
'cross-env': packageJson.peerDependencies['cross-env'],
|
|
58
57
|
rimraf: packageJson.peerDependencies.rimraf,
|
|
59
58
|
'@vyriy/webpack-config': `^${packageJson.version}`,
|
|
60
59
|
tsx: packageJson.peerDependencies.tsx,
|
|
61
|
-
webpack: packageJson.peerDependencies.webpack,
|
|
62
60
|
'webpack-cli': packageJson.peerDependencies['webpack-cli'],
|
|
63
61
|
react: packageJson.peerDependencies.react,
|
|
64
62
|
'react-dom': packageJson.peerDependencies['react-dom'],
|
|
@@ -93,56 +91,56 @@ extends @vyriy/browserslist-config
|
|
|
93
91
|
'packages/components/index.ts': "export * from './page/index.js';\n",
|
|
94
92
|
'packages/components/index.test.tsx': `import { describe, expect, it } from '@jest/globals';
|
|
95
93
|
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
import { Page } from './index.js';
|
|
95
|
+
import { Page as PageImplementation } from './page/index.js';
|
|
98
96
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
97
|
+
describe('packages/components/page', () => {
|
|
98
|
+
it('re-exports the page component', () => {
|
|
99
|
+
expect(Page).toBe(PageImplementation);
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
`,
|
|
105
103
|
'packages/components/page/index.ts': `export * from './page.js';
|
|
106
|
-
|
|
107
|
-
|
|
104
|
+
export type * from './types.js';
|
|
105
|
+
`,
|
|
108
106
|
'packages/components/page/index.test.ts': `import { describe, expect, it } from '@jest/globals';
|
|
109
107
|
|
|
110
|
-
|
|
111
|
-
|
|
108
|
+
import { Page } from './index.js';
|
|
109
|
+
import { Page as PageImplementation } from './page.js';
|
|
112
110
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
describe('packages/components/page', () => {
|
|
112
|
+
it('re-exports the page component', () => {
|
|
113
|
+
expect(Page).toBe(PageImplementation);
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
`,
|
|
119
117
|
'packages/components/page/types.ts': `import { FC } from 'react';
|
|
120
118
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
119
|
+
export type PageProps = {
|
|
120
|
+
content: string;
|
|
121
|
+
};
|
|
124
122
|
|
|
125
|
-
|
|
126
|
-
|
|
123
|
+
export type PageType = FC<PageProps>;
|
|
124
|
+
`,
|
|
127
125
|
'packages/components/page/page.tsx': `import type { PageType } from './types.js';
|
|
128
126
|
|
|
129
|
-
|
|
130
|
-
|
|
127
|
+
export const Page: PageType = ({ content }) => <div className="content">{content}</div>;
|
|
128
|
+
`,
|
|
131
129
|
'packages/components/page/styles.scss': `.content {
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
display: block;
|
|
131
|
+
}
|
|
132
|
+
`,
|
|
135
133
|
'packages/components/page/page.test.tsx': `import { renderToStaticMarkup } from 'react-dom/server';
|
|
136
|
-
|
|
134
|
+
import { describe, expect, it } from '@jest/globals';
|
|
137
135
|
|
|
138
|
-
|
|
136
|
+
import { Page } from './page.js';
|
|
139
137
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
138
|
+
describe('packages/components/page/page', () => {
|
|
139
|
+
it('renders content inside the page content container', () => {
|
|
140
|
+
expect(renderToStaticMarkup(<Page content="Page body" />)).toBe('<div class="content">Page body</div>');
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
`,
|
|
146
144
|
'workspaces/spa/bin/build.sh': `#!/usr/bin/env sh
|
|
147
145
|
|
|
148
146
|
set -e
|
|
@@ -160,12 +158,12 @@ scriptdir="$PWD/workspaces/spa";
|
|
|
160
158
|
npx webpack serve --open --config $scriptdir/webpack.config.ts
|
|
161
159
|
`,
|
|
162
160
|
'workspaces/spa/doc.mdx': `import { Meta, Markdown } from '@storybook/addon-docs/blocks';
|
|
163
|
-
|
|
161
|
+
import ReadMe from './README.md?raw';
|
|
164
162
|
|
|
165
|
-
|
|
163
|
+
<Meta title="Workspaces/SPA" />
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
165
|
+
<Markdown>{ReadMe}</Markdown>
|
|
166
|
+
`,
|
|
169
167
|
'workspaces/spa/README.md': `# ${options.name} SPA\n\n${options.description}\n`,
|
|
170
168
|
'workspaces/spa/webpack.config.ts': `import { csr, html } from '@vyriy/webpack-config';
|
|
171
169
|
import { path } from '@vyriy/path';
|