@quilted/create 0.1.12 → 0.1.15
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/CHANGELOG.md +18 -0
- package/build/cjs/app.cjs +303 -0
- package/build/cjs/index.cjs +5220 -5198
- package/build/cjs/index2.cjs +374 -0
- package/build/cjs/index3.cjs +7854 -0
- package/build/cjs/minimatch.cjs +1202 -0
- package/build/cjs/package-manager.cjs +300 -0
- package/build/cjs/package.cjs +410 -0
- package/build/cjs/standalone.cjs +151 -0
- package/build/esm/app.mjs +280 -0
- package/build/esm/index.mjs +5206 -5195
- package/build/esm/index2.mjs +365 -0
- package/build/esm/index3.mjs +7852 -0
- package/build/esm/minimatch.mjs +1200 -0
- package/build/esm/package-manager.mjs +270 -0
- package/build/esm/package.mjs +387 -0
- package/build/esm/standalone.mjs +149 -0
- package/build/tsconfig.tsbuildinfo +1 -1
- package/build/typescript/app.d.ts +2 -0
- package/build/typescript/app.d.ts.map +1 -0
- package/build/typescript/help.d.ts +6 -0
- package/build/typescript/help.d.ts.map +1 -0
- package/build/typescript/package.d.ts +2 -0
- package/build/typescript/package.d.ts.map +1 -0
- package/build/typescript/shared/package-manager.d.ts +3 -0
- package/build/typescript/shared/package-manager.d.ts.map +1 -0
- package/build/typescript/shared/prompts.d.ts +22 -0
- package/build/typescript/shared/prompts.d.ts.map +1 -0
- package/build/typescript/shared/tsconfig.d.ts +3 -0
- package/build/typescript/shared/tsconfig.d.ts.map +1 -0
- package/build/typescript/shared.d.ts +21 -0
- package/build/typescript/shared.d.ts.map +1 -0
- package/package.json +13 -3
- package/source/app.ts +387 -0
- package/source/create.ts +43 -383
- package/source/help.ts +132 -0
- package/source/package.ts +510 -0
- package/source/shared/package-manager.ts +74 -0
- package/source/shared/prompts.ts +133 -0
- package/source/shared/tsconfig.ts +90 -0
- package/source/shared.ts +165 -0
- package/templates/{app → app-basic}/App.tsx +4 -7
- package/templates/{app → app-basic}/features/Start/Start.module.css +0 -0
- package/templates/{app → app-basic}/features/Start/Start.tsx +1 -1
- package/templates/{app → app-basic}/features/Start/index.ts +0 -0
- package/templates/{app → app-basic}/foundation/Head.tsx +8 -8
- package/templates/{app → app-basic}/foundation/Http.tsx +10 -6
- package/templates/{app → app-basic}/package.json +10 -1
- package/templates/{app → app-basic}/quilt.project.ts +0 -0
- package/templates/{app → app-basic}/server.tsx +0 -0
- package/templates/{app → app-basic}/shared/types.ts +0 -0
- package/templates/{app → app-basic}/tsconfig.json +0 -0
- package/templates/app-single-file/App.tsx +168 -0
- package/templates/app-single-file/package.json +30 -0
- package/templates/app-single-file/quilt.project.ts +6 -0
- package/templates/app-single-file/tsconfig.json +9 -0
- package/templates/{workspace → github}/_github/workflows/actions/prepare/action.yml +0 -0
- package/templates/{workspace → github}/_github/workflows/ci.yml +0 -0
- package/templates/package/package.json +24 -9
- package/templates/package/quilt.project.ts +1 -1
- package/templates/vscode/_vscode/extensions.json +7 -0
- package/templates/vscode/_vscode/settings.json +17 -0
- package/templates/workspace/_gitignore +1 -1
- package/templates/workspace/_prettierignore +1 -0
- package/templates/workspace/package.json +1 -6
- package/templates/workspace/tsconfig.json +6 -1
- package/templates/workspace/pnpm-workspace.yaml +0 -3
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import {relative} from 'path';
|
|
2
|
+
|
|
3
|
+
import type {OutputTarget} from '../shared';
|
|
4
|
+
import {format, relativeDirectoryForDisplay} from '../shared';
|
|
5
|
+
|
|
6
|
+
interface TSConfigReference {
|
|
7
|
+
path: string;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const ENDS_WITH_TSCONFIG = /[/]?tsconfig[.a-z0-9]*[.]json/i;
|
|
11
|
+
|
|
12
|
+
export async function addToTsConfig(directory: string, output: OutputTarget) {
|
|
13
|
+
const tsconfig = JSON.parse(await output.read('tsconfig.json'));
|
|
14
|
+
|
|
15
|
+
tsconfig.references ??= [];
|
|
16
|
+
|
|
17
|
+
const relativePath = relative(output.root, directory);
|
|
18
|
+
const relativeForDisplay = relativeDirectoryForDisplay(relativePath);
|
|
19
|
+
|
|
20
|
+
if (tsconfig.references.length === 0) {
|
|
21
|
+
tsconfig.references.push({path: relativeForDisplay});
|
|
22
|
+
} else {
|
|
23
|
+
let hasExistingReference = false;
|
|
24
|
+
let referenceFormat:
|
|
25
|
+
| 'relative'
|
|
26
|
+
| 'pretty-relative'
|
|
27
|
+
| 'tsconfig'
|
|
28
|
+
| 'pretty-tsconfig' = 'pretty-relative';
|
|
29
|
+
|
|
30
|
+
for (const {path} of tsconfig.references as TSConfigReference[]) {
|
|
31
|
+
if (path.startsWith('./')) {
|
|
32
|
+
if (ENDS_WITH_TSCONFIG.test(path)) {
|
|
33
|
+
referenceFormat = 'pretty-tsconfig';
|
|
34
|
+
|
|
35
|
+
if (path === `${relativeForDisplay}/tsconfig.json`) {
|
|
36
|
+
hasExistingReference = true;
|
|
37
|
+
break;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
referenceFormat = 'pretty-relative';
|
|
42
|
+
|
|
43
|
+
if (path === relativeForDisplay) {
|
|
44
|
+
hasExistingReference = true;
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
} else if (ENDS_WITH_TSCONFIG.test(path)) {
|
|
48
|
+
referenceFormat = 'tsconfig';
|
|
49
|
+
|
|
50
|
+
if (path === `${relativePath}/tsconfig.json`) {
|
|
51
|
+
hasExistingReference = true;
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
} else {
|
|
55
|
+
referenceFormat = 'relative';
|
|
56
|
+
|
|
57
|
+
if (path === relativePath) {
|
|
58
|
+
hasExistingReference = true;
|
|
59
|
+
break;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
if (!hasExistingReference) {
|
|
65
|
+
let path: string;
|
|
66
|
+
|
|
67
|
+
if (referenceFormat === 'pretty-tsconfig') {
|
|
68
|
+
path = `${relativeForDisplay}/tsconfig.json`;
|
|
69
|
+
} else if (referenceFormat === 'pretty-relative') {
|
|
70
|
+
path = relativeForDisplay;
|
|
71
|
+
} else if (referenceFormat === 'tsconfig') {
|
|
72
|
+
path = `${relativePath}/tsconfig.json`;
|
|
73
|
+
} else {
|
|
74
|
+
path = relativePath;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
tsconfig.references.push({path});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
tsconfig.references = tsconfig.references.sort(
|
|
82
|
+
({path: pathOne}: TSConfigReference, {path: pathTwo}: TSConfigReference) =>
|
|
83
|
+
pathOne.localeCompare(pathTwo),
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
await output.write(
|
|
87
|
+
'tsconfig.json',
|
|
88
|
+
await format(JSON.stringify(tsconfig), {as: 'json'}),
|
|
89
|
+
);
|
|
90
|
+
}
|
package/source/shared.ts
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import {fileURLToPath} from 'url';
|
|
4
|
+
import type {BuiltInParserName} from 'prettier';
|
|
5
|
+
|
|
6
|
+
export {prompt} from './shared/prompts';
|
|
7
|
+
|
|
8
|
+
export function loadTemplate(
|
|
9
|
+
name:
|
|
10
|
+
| 'package'
|
|
11
|
+
| 'app-basic'
|
|
12
|
+
| 'app-single-file'
|
|
13
|
+
| 'workspace'
|
|
14
|
+
| 'github'
|
|
15
|
+
| 'vscode',
|
|
16
|
+
) {
|
|
17
|
+
let templateRootPromise: Promise<string> | undefined;
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
async copy(to: string, handleFile?: (file: string) => boolean) {
|
|
21
|
+
templateRootPromise ??= templateDirectory(name);
|
|
22
|
+
const templateRoot = await templateRootPromise;
|
|
23
|
+
const targetRoot = path.resolve(to);
|
|
24
|
+
|
|
25
|
+
const files = fs
|
|
26
|
+
.readdirSync(templateRoot)
|
|
27
|
+
.filter((file) => !path.basename(file).startsWith('.'));
|
|
28
|
+
|
|
29
|
+
for (const file of files) {
|
|
30
|
+
if (handleFile) {
|
|
31
|
+
if (!handleFile(file)) {
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const targetPath = path.join(
|
|
37
|
+
targetRoot,
|
|
38
|
+
file.startsWith('_') ? `.${file.slice(1)}` : file,
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
copy(path.join(templateRoot, file), targetPath);
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
async read(file: string) {
|
|
45
|
+
templateRootPromise ??= templateDirectory(name);
|
|
46
|
+
const templateRoot = await templateRootPromise;
|
|
47
|
+
|
|
48
|
+
return fs.readFileSync(path.join(templateRoot, file), {encoding: 'utf8'});
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface OutputTarget {
|
|
54
|
+
readonly root: string;
|
|
55
|
+
read(file: string): Promise<string>;
|
|
56
|
+
write(file: string, content: string): Promise<void>;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function createOutputTarget(target: string): OutputTarget {
|
|
60
|
+
return {
|
|
61
|
+
root: target,
|
|
62
|
+
read(file: string) {
|
|
63
|
+
return fs.promises.readFile(path.resolve(target, file), {
|
|
64
|
+
encoding: 'utf8',
|
|
65
|
+
});
|
|
66
|
+
},
|
|
67
|
+
async write(file: string, content: string) {
|
|
68
|
+
await writeFile(path.resolve(target, file), content);
|
|
69
|
+
},
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
let packageRootPromise: Promise<string> | undefined;
|
|
74
|
+
|
|
75
|
+
async function templateDirectory(
|
|
76
|
+
name:
|
|
77
|
+
| 'package'
|
|
78
|
+
| 'app-basic'
|
|
79
|
+
| 'app-single-file'
|
|
80
|
+
| 'workspace'
|
|
81
|
+
| 'github'
|
|
82
|
+
| 'vscode',
|
|
83
|
+
) {
|
|
84
|
+
return path.join(await getPackageRoot(), 'templates', name);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async function getPackageRoot(): Promise<string> {
|
|
88
|
+
if (!packageRootPromise) {
|
|
89
|
+
packageRootPromise = (async () => {
|
|
90
|
+
const {packageDirectory} = await import('pkg-dir');
|
|
91
|
+
|
|
92
|
+
return packageDirectory({
|
|
93
|
+
cwd: path.dirname(fileURLToPath(import.meta.url)),
|
|
94
|
+
});
|
|
95
|
+
})();
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return packageRootPromise;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export function toValidPackageName(projectName: string) {
|
|
102
|
+
return projectName
|
|
103
|
+
.trim()
|
|
104
|
+
.toLowerCase()
|
|
105
|
+
.replace(/\s+/g, '-')
|
|
106
|
+
.replace(/^[._]/, '')
|
|
107
|
+
.replace(/[^a-z0-9-~@/]+/g, '-');
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function copy(source: string, destination: string) {
|
|
111
|
+
const stat = fs.statSync(source);
|
|
112
|
+
if (stat.isDirectory()) {
|
|
113
|
+
copyDirectory(source, destination);
|
|
114
|
+
} else {
|
|
115
|
+
fs.copyFileSync(source, destination);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
async function copyDirectory(source: string, destination: string) {
|
|
120
|
+
fs.mkdirSync(destination, {recursive: true});
|
|
121
|
+
for (const file of fs.readdirSync(source)) {
|
|
122
|
+
const srcFile = path.resolve(source, file);
|
|
123
|
+
const destFile = path.resolve(destination, file);
|
|
124
|
+
copy(srcFile, destFile);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export async function writeFile(file: string, content: string) {
|
|
129
|
+
await fs.promises.writeFile(file, content);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
export async function isEmpty(path: string) {
|
|
133
|
+
return fs.readdirSync(path).length === 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
export async function emptyDirectory(dir: string) {
|
|
137
|
+
if (!fs.existsSync(dir)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
for (const file of fs.readdirSync(dir)) {
|
|
142
|
+
fs.rmSync(path.resolve(dir, file), {force: true, recursive: true});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export function relativeDirectoryForDisplay(relativeDirectory: string) {
|
|
147
|
+
return relativeDirectory.startsWith('.')
|
|
148
|
+
? relativeDirectory
|
|
149
|
+
: `.${path.sep}${relativeDirectory}`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export async function format(
|
|
153
|
+
content: string,
|
|
154
|
+
{as: parser}: {as: BuiltInParserName},
|
|
155
|
+
) {
|
|
156
|
+
const [{format}] = await Promise.all([import('prettier/standalone')]);
|
|
157
|
+
|
|
158
|
+
return format(content, {
|
|
159
|
+
arrowParens: 'always',
|
|
160
|
+
bracketSpacing: false,
|
|
161
|
+
singleQuote: true,
|
|
162
|
+
trailingComma: 'all',
|
|
163
|
+
parser,
|
|
164
|
+
});
|
|
165
|
+
}
|
|
@@ -5,9 +5,8 @@ import {Head} from './foundation/Head';
|
|
|
5
5
|
|
|
6
6
|
import {Start} from './features/Start';
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
*/
|
|
8
|
+
// The root component for your application. You will typically render any
|
|
9
|
+
// app-wide context in this component.
|
|
11
10
|
export default function App() {
|
|
12
11
|
return (
|
|
13
12
|
<AppContext>
|
|
@@ -20,10 +19,8 @@ export default function App() {
|
|
|
20
19
|
);
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
* of routes, you may want to split this component into its own file.
|
|
26
|
-
*/
|
|
22
|
+
// This component renders the routes for your application. If you have a lot
|
|
23
|
+
// of routes, you may want to split this component into its own file.
|
|
27
24
|
function Routes() {
|
|
28
25
|
return useRoutes([{match: '/', render: () => <Start />}]);
|
|
29
26
|
}
|
|
File without changes
|
|
File without changes
|
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
import {Title, Viewport, Favicon, SearchRobots} from '@quilted/quilt/html';
|
|
2
2
|
|
|
3
|
+
// This component sets details of the HTML page. If you need to customize
|
|
4
|
+
// any of these details based on conditions like the active route, or some
|
|
5
|
+
// state about the user, you can move these components to wherever in your
|
|
6
|
+
// application you can read that state.
|
|
3
7
|
export function Head() {
|
|
4
8
|
return (
|
|
5
9
|
<>
|
|
6
|
-
{
|
|
7
|
-
* Sets the default `<title>` for this application.
|
|
8
|
-
*/}
|
|
10
|
+
{/* Sets the default `<title>` for this application. */}
|
|
9
11
|
<Title>App</Title>
|
|
10
12
|
|
|
11
|
-
{
|
|
13
|
+
{/*
|
|
12
14
|
* Sets the default favicon used by the application. You can
|
|
13
15
|
* change this to a different emoji, make it `blank`, or pass
|
|
14
16
|
* a URL with the `source` prop.
|
|
15
17
|
*/}
|
|
16
18
|
<Favicon emoji="🧶" />
|
|
17
19
|
|
|
18
|
-
{
|
|
19
|
-
* Adds a responsive-friendly `viewport` `<meta>` tag.
|
|
20
|
-
*/}
|
|
20
|
+
{/* Adds a responsive-friendly `viewport` `<meta>` tag. */}
|
|
21
21
|
<Viewport cover />
|
|
22
22
|
|
|
23
|
-
{
|
|
23
|
+
{/*
|
|
24
24
|
* Disables all search indexing for this application. If you are
|
|
25
25
|
* building an unauthenticated app, you probably want to remove
|
|
26
26
|
* this component, or update it to control how your site is indexed
|
|
@@ -8,12 +8,16 @@ import {
|
|
|
8
8
|
StrictTransportSecurity,
|
|
9
9
|
} from '@quilted/quilt/http';
|
|
10
10
|
|
|
11
|
+
// This component sets details on the HTTP response for all HTML server-rendering
|
|
12
|
+
// requests. If you need to customize any of these details based on conditions like
|
|
13
|
+
// the active route, or some state about the user, you can move these components to
|
|
14
|
+
// wherever in your application you can read that state.
|
|
11
15
|
export function Http() {
|
|
12
16
|
const isHttps = useCurrentUrl().protocol === 'https:';
|
|
13
17
|
|
|
14
18
|
return (
|
|
15
19
|
<>
|
|
16
|
-
{
|
|
20
|
+
{/*
|
|
17
21
|
* Disables the cache for this page, which is generally the best option
|
|
18
22
|
* when dealing with authenticated content. If your site doesn’t have
|
|
19
23
|
* authentication, or you have a better cache policy that works for your
|
|
@@ -23,7 +27,7 @@ export function Http() {
|
|
|
23
27
|
*/}
|
|
24
28
|
<CacheControl cache={false} />
|
|
25
29
|
|
|
26
|
-
{
|
|
30
|
+
{/*
|
|
27
31
|
* Sets a strict content security policy for this page. If you load
|
|
28
32
|
* assets from other origins, or want to allow some more dangerous
|
|
29
33
|
* resource loading techniques like `eval`, you can change the
|
|
@@ -50,7 +54,7 @@ export function Http() {
|
|
|
50
54
|
upgradeInsecureRequests={isHttps}
|
|
51
55
|
/>
|
|
52
56
|
|
|
53
|
-
{
|
|
57
|
+
{/*
|
|
54
58
|
* Sets a strict permissions policy for this page, which limits access
|
|
55
59
|
* to some native browser features.
|
|
56
60
|
*
|
|
@@ -73,7 +77,7 @@ export function Http() {
|
|
|
73
77
|
geolocation={false}
|
|
74
78
|
/>
|
|
75
79
|
|
|
76
|
-
{
|
|
80
|
+
{/*
|
|
77
81
|
* Instructs browsers to only load this page over HTTPS using the
|
|
78
82
|
* `Strict-Transport-Security` header.
|
|
79
83
|
*
|
|
@@ -81,7 +85,7 @@ export function Http() {
|
|
|
81
85
|
*/}
|
|
82
86
|
{isHttps && <StrictTransportSecurity />}
|
|
83
87
|
|
|
84
|
-
{
|
|
88
|
+
{/*
|
|
85
89
|
* Controls how much information about the current page is included in
|
|
86
90
|
* requests (through the `Referer` header). The default value
|
|
87
91
|
* (strict-origin-when-cross-origin) means that only the origin is included
|
|
@@ -95,7 +99,7 @@ export function Http() {
|
|
|
95
99
|
value="strict-origin-when-cross-origin"
|
|
96
100
|
/>
|
|
97
101
|
|
|
98
|
-
{
|
|
102
|
+
{/*
|
|
99
103
|
* Instructs browsers to respect the MIME type in the `Content-Type` header.
|
|
100
104
|
*
|
|
101
105
|
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
{
|
|
2
|
-
"name": "template-app",
|
|
2
|
+
"name": "template-app-basic",
|
|
3
3
|
"type": "module",
|
|
4
4
|
"version": "0.0.0",
|
|
5
5
|
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node ./build/server/index.js"
|
|
8
|
+
},
|
|
6
9
|
"dependencies": {},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@quilted/quilt": "^0.5.0",
|
|
12
|
+
"@types/react": "^17.0.0",
|
|
13
|
+
"react": "npm:@quilted/react@^17.0.0",
|
|
14
|
+
"react-dom": "npm:@quilted/react-dom@^17.0.0"
|
|
15
|
+
},
|
|
7
16
|
"eslintConfig": {
|
|
8
17
|
"extends": "@quilted/eslint-config/app"
|
|
9
18
|
},
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
import {Router, useRoutes, useCurrentUrl, AppContext} from '@quilted/quilt';
|
|
2
|
+
import {Title, Viewport, Favicon, SearchRobots} from '@quilted/quilt/html';
|
|
3
|
+
import {
|
|
4
|
+
CacheControl,
|
|
5
|
+
ResponseHeader,
|
|
6
|
+
ContentSecurityPolicy,
|
|
7
|
+
PermissionsPolicy,
|
|
8
|
+
StrictTransportSecurity,
|
|
9
|
+
} from '@quilted/quilt/http';
|
|
10
|
+
import Env from '@quilted/quilt/env';
|
|
11
|
+
|
|
12
|
+
// The root component for your application. You will typically render any
|
|
13
|
+
// app-wide context in this component.
|
|
14
|
+
export default function App() {
|
|
15
|
+
return (
|
|
16
|
+
<AppContext>
|
|
17
|
+
<Router>
|
|
18
|
+
<Http />
|
|
19
|
+
<Head />
|
|
20
|
+
<Routes />
|
|
21
|
+
</Router>
|
|
22
|
+
</AppContext>
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// This component renders the routes for your application. If you have a lot
|
|
27
|
+
// of routes, you may want to split this component into its own file.
|
|
28
|
+
function Routes() {
|
|
29
|
+
return useRoutes([{match: '/', render: () => <Start />}]);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// This component will be rendered for the root URL of your application. Feel
|
|
33
|
+
// free to edit it, rename it, remove it entirely, or move it to a dedicated file.
|
|
34
|
+
function Start() {
|
|
35
|
+
return <div>Hello world!</div>;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// This component sets details of the HTML page. If you need to customize
|
|
39
|
+
// any of these details based on conditions like the active route, or some
|
|
40
|
+
// state about the user, you can move these components to wherever in your
|
|
41
|
+
// application you can read that state.
|
|
42
|
+
function Head() {
|
|
43
|
+
return (
|
|
44
|
+
<>
|
|
45
|
+
{/* Sets the default `<title>` for this application. */}
|
|
46
|
+
<Title>App</Title>
|
|
47
|
+
|
|
48
|
+
{/*
|
|
49
|
+
* Sets the default favicon used by the application. You can
|
|
50
|
+
* change this to a different emoji, make it `blank`, or pass
|
|
51
|
+
* a URL with the `source` prop.
|
|
52
|
+
*/}
|
|
53
|
+
<Favicon emoji="🧶" />
|
|
54
|
+
|
|
55
|
+
{/* Adds a responsive-friendly `viewport` `<meta>` tag. */}
|
|
56
|
+
<Viewport cover />
|
|
57
|
+
|
|
58
|
+
{/*
|
|
59
|
+
* Disables all search indexing for this application. If you are
|
|
60
|
+
* building an unauthenticated app, you probably want to remove
|
|
61
|
+
* this component, or update it to control how your site is indexed
|
|
62
|
+
* by search engines.
|
|
63
|
+
*/}
|
|
64
|
+
<SearchRobots index={false} follow={false} />
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// This component sets details on the HTTP response for all HTML server-rendering
|
|
70
|
+
// requests. If you need to customize any of these details based on conditions like
|
|
71
|
+
// the active route, or some state about the user, you can move these components to
|
|
72
|
+
// wherever in your application you can read that state.
|
|
73
|
+
export function Http() {
|
|
74
|
+
const isHttps = useCurrentUrl().protocol === 'https:';
|
|
75
|
+
|
|
76
|
+
return (
|
|
77
|
+
<>
|
|
78
|
+
{/*
|
|
79
|
+
* Disables the cache for this page, which is generally the best option
|
|
80
|
+
* when dealing with authenticated content. If your site doesn’t have
|
|
81
|
+
* authentication, or you have a better cache policy that works for your
|
|
82
|
+
* app or deployment, make sure to update this component accordingly!
|
|
83
|
+
*
|
|
84
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control
|
|
85
|
+
*/}
|
|
86
|
+
<CacheControl cache={false} />
|
|
87
|
+
|
|
88
|
+
{/*
|
|
89
|
+
* Sets a strict content security policy for this page. If you load
|
|
90
|
+
* assets from other origins, or want to allow some more dangerous
|
|
91
|
+
* resource loading techniques like `eval`, you can change the
|
|
92
|
+
* `defaultSources` to be less restrictive, or add additional items
|
|
93
|
+
* to the allowlist for more specific directives.
|
|
94
|
+
*
|
|
95
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy
|
|
96
|
+
*/}
|
|
97
|
+
<ContentSecurityPolicy
|
|
98
|
+
reportOnly={Env.MODE === 'development'}
|
|
99
|
+
// By default, only allow sources from the page’s origin.
|
|
100
|
+
defaultSources={["'self'"]}
|
|
101
|
+
// Includes `'unsafe-inline'` because CSS is often necessary in development,
|
|
102
|
+
// and can be difficult to avoid in production.
|
|
103
|
+
styleSources={["'self'", "'unsafe-inline'"]}
|
|
104
|
+
// Includes `data:` so that an inline image can be used for the favicon.
|
|
105
|
+
// If you do not use the `emoji` or `blank` favicons in your app, and you
|
|
106
|
+
// do not load any other images as data URIs, you can remove this directive.
|
|
107
|
+
imageSources={["'self'", 'data:']}
|
|
108
|
+
// Don’t allow this page to be rendered as a frame from a different origin.
|
|
109
|
+
frameAncestors={false}
|
|
110
|
+
// Ensure that all requests made by this page are made over https, unless
|
|
111
|
+
// it is being served over http (typically, during local development)
|
|
112
|
+
upgradeInsecureRequests={isHttps}
|
|
113
|
+
/>
|
|
114
|
+
|
|
115
|
+
{/*
|
|
116
|
+
* Sets a strict permissions policy for this page, which limits access
|
|
117
|
+
* to some native browser features.
|
|
118
|
+
*
|
|
119
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Feature-Policy
|
|
120
|
+
*/}
|
|
121
|
+
<PermissionsPolicy
|
|
122
|
+
// Disables Google’s Federated Learning of Cohorts (“FLoC”) tracking initiative.
|
|
123
|
+
// @see https://www.eff.org/deeplinks/2021/03/googles-floc-terrible-idea
|
|
124
|
+
interestCohort={false}
|
|
125
|
+
// Don’t use synchronous XHRs!
|
|
126
|
+
// @see https://featurepolicy.info/policies/sync-xhr
|
|
127
|
+
syncXhr={false}
|
|
128
|
+
// Disables access to a few device APIs that are infrequently used
|
|
129
|
+
// and prone to abuse. If your application uses these APIs intentionally,
|
|
130
|
+
// feel free to remove the prop, or pass an array containing the origins
|
|
131
|
+
// that should be allowed to use this feature (e.g., `['self']` to allow
|
|
132
|
+
// only the main page’s origin).
|
|
133
|
+
camera={false}
|
|
134
|
+
microphone={false}
|
|
135
|
+
geolocation={false}
|
|
136
|
+
/>
|
|
137
|
+
|
|
138
|
+
{/*
|
|
139
|
+
* Instructs browsers to only load this page over HTTPS using the
|
|
140
|
+
* `Strict-Transport-Security` header.
|
|
141
|
+
*
|
|
142
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Strict-Transport-Security
|
|
143
|
+
*/}
|
|
144
|
+
{isHttps && <StrictTransportSecurity />}
|
|
145
|
+
|
|
146
|
+
{/*
|
|
147
|
+
* Controls how much information about the current page is included in
|
|
148
|
+
* requests (through the `Referer` header). The default value
|
|
149
|
+
* (strict-origin-when-cross-origin) means that only the origin is included
|
|
150
|
+
* for cross-origin requests, while the origin, path, and querystring
|
|
151
|
+
* are included for same-origin requests.
|
|
152
|
+
*
|
|
153
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Referrer-Policy
|
|
154
|
+
*/}
|
|
155
|
+
<ResponseHeader
|
|
156
|
+
name="Referrer-Policy"
|
|
157
|
+
value="strict-origin-when-cross-origin"
|
|
158
|
+
/>
|
|
159
|
+
|
|
160
|
+
{/*
|
|
161
|
+
* Instructs browsers to respect the MIME type in the `Content-Type` header.
|
|
162
|
+
*
|
|
163
|
+
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Content-Type-Options
|
|
164
|
+
*/}
|
|
165
|
+
<ResponseHeader name="X-Content-Type-Options" value="nosniff" />
|
|
166
|
+
</>
|
|
167
|
+
);
|
|
168
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "template-app-single-file",
|
|
3
|
+
"type": "module",
|
|
4
|
+
"version": "0.0.0",
|
|
5
|
+
"private": true,
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node ./build/server/index.js"
|
|
8
|
+
},
|
|
9
|
+
"dependencies": {},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@quilted/quilt": "^0.5.0",
|
|
12
|
+
"@types/react": "^17.0.0",
|
|
13
|
+
"react": "npm:@quilted/react@^17.0.0",
|
|
14
|
+
"react-dom": "npm:@quilted/react-dom@^17.0.0"
|
|
15
|
+
},
|
|
16
|
+
"eslintConfig": {
|
|
17
|
+
"extends": "@quilted/eslint-config/app"
|
|
18
|
+
},
|
|
19
|
+
"browserslist": {
|
|
20
|
+
"defaults": [
|
|
21
|
+
"extends @quilted/browserslist-config/defaults"
|
|
22
|
+
],
|
|
23
|
+
"modules": [
|
|
24
|
+
"extends @quilted/browserslist-config/modules"
|
|
25
|
+
],
|
|
26
|
+
"evergreen": [
|
|
27
|
+
"extends @quilted/browserslist-config/evergreen"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
File without changes
|
|
File without changes
|