create-absolutejs 0.10.3 → 0.11.0
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/dist/constants.d.ts +2 -2
- package/dist/constants.js +2 -2
- package/dist/data.d.ts +10 -10
- package/dist/data.js +88 -95
- package/dist/generators/angular/generateAngularPage.d.ts +7 -0
- package/dist/generators/angular/generateAngularPage.js +175 -0
- package/dist/generators/angular/scaffoldAngular.d.ts +2 -0
- package/dist/generators/angular/scaffoldAngular.js +34 -0
- package/dist/generators/configurations/generatePackageJson.js +26 -3
- package/dist/generators/configurations/scaffoldConfigurationFiles.js +26 -2
- package/dist/generators/db/dockerInitTemplates.d.ts +9 -9
- package/dist/generators/db/dockerInitTemplates.js +9 -9
- package/dist/generators/db/generateDatabaseTypes.js +5 -0
- package/dist/generators/db/generateDockerContainer.js +4 -2
- package/dist/generators/db/generateDrizzleSchema.js +16 -6
- package/dist/generators/db/handlerTemplates.d.ts +5 -0
- package/dist/generators/db/handlerTemplates.js +6 -0
- package/dist/generators/db/scaffoldDocker.js +42 -30
- package/dist/generators/html/generateHTMLPage.d.ts +1 -1
- package/dist/generators/html/generateHTMLPage.js +2 -2
- package/dist/generators/html/scaffoldHTML.d.ts +1 -1
- package/dist/generators/html/scaffoldHTML.js +2 -2
- package/dist/generators/htmx/generateHTMXPage.d.ts +1 -1
- package/dist/generators/htmx/generateHTMXPage.js +2 -2
- package/dist/generators/htmx/scaffoldHTMX.d.ts +1 -1
- package/dist/generators/htmx/scaffoldHTMX.js +2 -2
- package/dist/generators/project/computeFlags.d.ts +1 -0
- package/dist/generators/project/computeFlags.js +1 -0
- package/dist/generators/project/generateBuildBlock.d.ts +2 -1
- package/dist/generators/project/generateBuildBlock.js +11 -7
- package/dist/generators/project/generateDBBlock.js +6 -0
- package/dist/generators/project/generateImportsBlock.js +39 -27
- package/dist/generators/project/generateMarkupCSS.js +4 -0
- package/dist/generators/project/generateRoutesBlock.d.ts +1 -2
- package/dist/generators/project/generateRoutesBlock.js +28 -17
- package/dist/generators/project/generateServer.js +5 -10
- package/dist/generators/project/scaffoldFrontends.js +20 -1
- package/dist/generators/react/generateReactComponents.d.ts +2 -2
- package/dist/generators/react/generateReactComponents.js +33 -33
- package/dist/generators/react/scaffoldReact.d.ts +1 -1
- package/dist/generators/react/scaffoldReact.js +2 -2
- package/dist/generators/svelte/generateSveltePage.d.ts +1 -1
- package/dist/generators/svelte/generateSveltePage.js +20 -2
- package/dist/generators/svelte/scaffoldSvelte.d.ts +1 -1
- package/dist/generators/svelte/scaffoldSvelte.js +2 -2
- package/dist/generators/vue/generateVuePage.d.ts +1 -1
- package/dist/generators/vue/generateVuePage.js +20 -2
- package/dist/generators/vue/scaffoldVue.d.ts +1 -1
- package/dist/generators/vue/scaffoldVue.js +2 -2
- package/dist/questions/databaseEngine.d.ts +1 -1
- package/dist/questions/frontendDirectoryConfigurations.d.ts +1 -1
- package/dist/questions/frontends.d.ts +1 -1
- package/dist/questions/frontends.js +3 -3
- package/dist/scaffold.js +14 -2
- package/dist/templates/assets/svg/angular.svg +18 -0
- package/dist/templates/configurations/tsconfig.example.json +12 -12
- package/dist/templates/react/components/App.tsx +2 -2
- package/dist/templates/react/components/Head.tsx +7 -7
- package/dist/templates/react/components/OAuthLink.tsx +2 -2
- package/dist/templates/styles/colors.ts +6 -8
- package/dist/templates/styles/reset.css +15 -0
- package/dist/templates/svelte/components/Counter.svelte +4 -0
- package/dist/templates/vue/components/CountButton.vue +1 -1
- package/dist/typeGuards.d.ts +6 -6
- package/dist/typeGuards.js +6 -6
- package/dist/types.d.ts +1 -0
- package/dist/utils/checkDockerInstalled.d.ts +4 -4
- package/dist/utils/checkDockerInstalled.js +78 -71
- package/dist/utils/parseCommandLineOptions.js +13 -16
- package/dist/versions.d.ts +37 -29
- package/dist/versions.js +48 -39
- package/package.json +10 -9
- /package/dist/templates/configurations/{eslint.config.mjs → eslint.config.example.mjs} +0 -0
package/dist/constants.d.ts
CHANGED
package/dist/constants.js
CHANGED
package/dist/data.d.ts
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import type { FrontendLabels, AvailableDependency } from './types';
|
|
2
|
-
export declare const
|
|
2
|
+
export declare const absoluteAuthPlugin: AvailableDependency;
|
|
3
3
|
export declare const availableAuthProviders: readonly ["abs", "none"];
|
|
4
|
-
export declare const
|
|
5
|
-
export declare const availablePrismaDialects: readonly ["mysql", "postgresql", "sqlite", "mongodb", "mariadb", "cockroachdb", "mssql"];
|
|
4
|
+
export declare const availableCodeQualityTools: readonly ["eslint+prettier", "biome"];
|
|
6
5
|
export declare const availableDatabaseEngines: readonly ["postgresql", "mysql", "sqlite", "mongodb", "mariadb", "gel", "singlestore", "cockroachdb", "mssql", "none"];
|
|
6
|
+
export declare const availableDatabaseHosts: readonly ["neon", "planetscale", "turso", "none"];
|
|
7
7
|
export declare const availableDirectoryConfigurations: readonly ["default", "custom"];
|
|
8
|
+
export declare const availableDrizzleDialects: readonly ["gel", "mariadb", "mssql", "mysql", "postgresql", "singlestore", "sqlite"];
|
|
9
|
+
export declare const availableFrontends: readonly ["react", "html", "svelte", "vue", "htmx", "angular"];
|
|
8
10
|
export declare const availableORMs: readonly ["drizzle", "prisma", "none"];
|
|
9
|
-
export declare const availableDatabaseHosts: readonly ["neon", "planetscale", "turso", "none"];
|
|
10
|
-
export declare const availableCodeQualityTools: readonly ["eslint+prettier", "biome"];
|
|
11
|
-
export declare const frontendLabels: FrontendLabels;
|
|
12
11
|
export declare const availablePlugins: AvailableDependency[];
|
|
13
|
-
export declare const
|
|
14
|
-
export declare const scopedStatePlugin: AvailableDependency;
|
|
15
|
-
export declare const eslintAndPrettierDependencies: AvailableDependency[];
|
|
16
|
-
export declare const eslintReactDependencies: AvailableDependency[];
|
|
12
|
+
export declare const availablePrismaDialects: readonly ["mysql", "postgresql", "sqlite", "mongodb", "mariadb", "cockroachdb", "mssql"];
|
|
17
13
|
export declare const defaultDependencies: AvailableDependency[];
|
|
18
14
|
export declare const defaultPlugins: AvailableDependency[];
|
|
15
|
+
export declare const eslintAndPrettierDependencies: AvailableDependency[];
|
|
16
|
+
export declare const eslintReactDependencies: AvailableDependency[];
|
|
17
|
+
export declare const frontendLabels: FrontendLabels;
|
|
18
|
+
export declare const scopedStatePlugin: AvailableDependency;
|
package/dist/data.js
CHANGED
|
@@ -1,31 +1,20 @@
|
|
|
1
|
-
import { cyan, green, magenta } from 'picocolors';
|
|
1
|
+
import { cyan, green, magenta, red } from 'picocolors';
|
|
2
2
|
import { versions } from './versions';
|
|
3
|
-
export const
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
3
|
+
export const absoluteAuthPlugin = {
|
|
4
|
+
imports: [
|
|
5
|
+
{
|
|
6
|
+
config: {
|
|
7
|
+
providersConfiguration: {}
|
|
8
|
+
},
|
|
9
|
+
isPlugin: true,
|
|
10
|
+
packageName: 'absoluteAuth'
|
|
11
|
+
}
|
|
12
|
+
],
|
|
13
|
+
latestVersion: versions['@absolutejs/auth'],
|
|
14
|
+
value: '@absolutejs/auth'
|
|
15
|
+
};
|
|
11
16
|
export const availableAuthProviders = ['abs', 'none'];
|
|
12
|
-
export const
|
|
13
|
-
'gel',
|
|
14
|
-
'mysql',
|
|
15
|
-
'postgresql',
|
|
16
|
-
'sqlite',
|
|
17
|
-
'singlestore',
|
|
18
|
-
'mariadb'
|
|
19
|
-
];
|
|
20
|
-
export const availablePrismaDialects = [
|
|
21
|
-
'mysql',
|
|
22
|
-
'postgresql',
|
|
23
|
-
'sqlite',
|
|
24
|
-
'mongodb',
|
|
25
|
-
'mariadb',
|
|
26
|
-
'cockroachdb',
|
|
27
|
-
'mssql'
|
|
28
|
-
];
|
|
17
|
+
export const availableCodeQualityTools = ['eslint+prettier', 'biome'];
|
|
29
18
|
export const availableDatabaseEngines = [
|
|
30
19
|
'postgresql',
|
|
31
20
|
'mysql',
|
|
@@ -38,25 +27,31 @@ export const availableDatabaseEngines = [
|
|
|
38
27
|
'mssql',
|
|
39
28
|
'none'
|
|
40
29
|
];
|
|
41
|
-
export const availableDirectoryConfigurations = ['default', 'custom'];
|
|
42
|
-
export const availableORMs = ['drizzle', 'prisma', 'none'];
|
|
43
30
|
export const availableDatabaseHosts = [
|
|
44
31
|
'neon',
|
|
45
32
|
'planetscale',
|
|
46
33
|
'turso',
|
|
47
34
|
'none'
|
|
48
35
|
];
|
|
49
|
-
export const
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
36
|
+
export const availableDirectoryConfigurations = ['default', 'custom'];
|
|
37
|
+
export const availableDrizzleDialects = [
|
|
38
|
+
'gel',
|
|
39
|
+
'mariadb',
|
|
40
|
+
'mssql',
|
|
41
|
+
'mysql',
|
|
42
|
+
'postgresql',
|
|
43
|
+
'singlestore',
|
|
44
|
+
'sqlite'
|
|
45
|
+
];
|
|
46
|
+
export const availableFrontends = [
|
|
47
|
+
'react',
|
|
48
|
+
'html',
|
|
49
|
+
'svelte',
|
|
50
|
+
'vue',
|
|
51
|
+
'htmx',
|
|
52
|
+
'angular'
|
|
53
|
+
];
|
|
54
|
+
export const availableORMs = ['drizzle', 'prisma', 'none'];
|
|
60
55
|
export const availablePlugins = [
|
|
61
56
|
{
|
|
62
57
|
imports: [{ config: null, isPlugin: true, packageName: 'cors' }],
|
|
@@ -77,30 +72,41 @@ export const availablePlugins = [
|
|
|
77
72
|
value: 'elysia-rate-limit'
|
|
78
73
|
}
|
|
79
74
|
];
|
|
80
|
-
export const
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
75
|
+
export const availablePrismaDialects = [
|
|
76
|
+
'mysql',
|
|
77
|
+
'postgresql',
|
|
78
|
+
'sqlite',
|
|
79
|
+
'mongodb',
|
|
80
|
+
'mariadb',
|
|
81
|
+
'cockroachdb',
|
|
82
|
+
'mssql'
|
|
83
|
+
];
|
|
84
|
+
export const defaultDependencies = [
|
|
85
|
+
{
|
|
86
|
+
imports: [{ isPlugin: false, packageName: 'Elysia' }],
|
|
87
|
+
latestVersion: versions['elysia'],
|
|
88
|
+
value: 'elysia'
|
|
89
|
+
}
|
|
90
|
+
];
|
|
91
|
+
export const defaultPlugins = [
|
|
92
|
+
{
|
|
93
|
+
imports: [
|
|
94
|
+
{ isPlugin: false, packageName: 'asset' },
|
|
95
|
+
{ isPlugin: true, packageName: 'networking' },
|
|
96
|
+
{ isPlugin: false, packageName: 'prepare' }
|
|
97
|
+
],
|
|
98
|
+
latestVersion: versions['@absolutejs/absolute'],
|
|
99
|
+
value: '@absolutejs/absolute'
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
latestVersion: versions['@elysiajs/eden'],
|
|
103
|
+
value: '@elysiajs/eden'
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
latestVersion: versions['@elysiajs/static'],
|
|
107
|
+
value: '@elysiajs/static'
|
|
108
|
+
}
|
|
109
|
+
];
|
|
104
110
|
export const eslintAndPrettierDependencies = [
|
|
105
111
|
{
|
|
106
112
|
latestVersion: versions['@eslint/compat'],
|
|
@@ -173,35 +179,22 @@ export const eslintReactDependencies = [
|
|
|
173
179
|
value: 'zod-validation-error'
|
|
174
180
|
}
|
|
175
181
|
];
|
|
176
|
-
export const
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
},
|
|
196
|
-
{
|
|
197
|
-
imports: [
|
|
198
|
-
{
|
|
199
|
-
config: { assets: './build', prefix: '' },
|
|
200
|
-
isPlugin: true,
|
|
201
|
-
packageName: 'staticPlugin'
|
|
202
|
-
}
|
|
203
|
-
],
|
|
204
|
-
latestVersion: versions['@elysiajs/static'],
|
|
205
|
-
value: '@elysiajs/static'
|
|
206
|
-
}
|
|
207
|
-
];
|
|
182
|
+
export const frontendLabels = {
|
|
183
|
+
angular: red('Angular'),
|
|
184
|
+
html: 'HTML',
|
|
185
|
+
htmx: 'HTMX',
|
|
186
|
+
react: cyan('React'),
|
|
187
|
+
svelte: magenta('Svelte'),
|
|
188
|
+
vue: green('Vue')
|
|
189
|
+
};
|
|
190
|
+
export const scopedStatePlugin = {
|
|
191
|
+
imports: [
|
|
192
|
+
{
|
|
193
|
+
config: { count: { value: 0 } },
|
|
194
|
+
isPlugin: true,
|
|
195
|
+
packageName: 'scopedState'
|
|
196
|
+
}
|
|
197
|
+
],
|
|
198
|
+
latestVersion: versions['elysia-scoped-state'],
|
|
199
|
+
value: 'elysia-scoped-state'
|
|
200
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Frontend } from '../../types';
|
|
2
|
+
export declare const generateAngularPage: (_frontends: Frontend[]) => string;
|
|
3
|
+
export declare const generateAppComponent: () => string;
|
|
4
|
+
export declare const generateAppComponentCss: () => string;
|
|
5
|
+
export declare const generateAppComponentHtml: (frontends: Frontend[], editBasePath: string) => string;
|
|
6
|
+
export declare const generateCounterComponent: () => string;
|
|
7
|
+
export declare const generateDropdownComponent: (frontends: Frontend[]) => string;
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { formatNavLink } from '../../utils/formatNavLink';
|
|
2
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
3
|
+
export const generateAngularPage = (_frontends) => `import { Component, inject, InjectionToken } from '@angular/core';
|
|
4
|
+
import { CommonModule } from '@angular/common';
|
|
5
|
+
import { DropdownComponent } from '../components/dropdown.component';
|
|
6
|
+
import { AppComponent } from '../components/app.component';
|
|
7
|
+
|
|
8
|
+
export const INITIAL_COUNT = new InjectionToken<number>('INITIAL_COUNT');
|
|
9
|
+
|
|
10
|
+
type AngularPageProps = {
|
|
11
|
+
initialCount: number;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
@Component({
|
|
15
|
+
selector: 'angular-page',
|
|
16
|
+
standalone: true,
|
|
17
|
+
imports: [CommonModule, DropdownComponent, AppComponent],
|
|
18
|
+
template: \`
|
|
19
|
+
<header>
|
|
20
|
+
<a href="/">AbsoluteJS</a>
|
|
21
|
+
<app-dropdown></app-dropdown>
|
|
22
|
+
</header>
|
|
23
|
+
<app-root [initialCount]="initialCount"></app-root>
|
|
24
|
+
\`
|
|
25
|
+
})
|
|
26
|
+
export class AngularExampleComponent {
|
|
27
|
+
initialCount: number = 0;
|
|
28
|
+
|
|
29
|
+
constructor() {
|
|
30
|
+
const initialCountToken = inject(INITIAL_COUNT, { optional: true });
|
|
31
|
+
this.initialCount = initialCountToken ?? 0;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export const factory = (props: AngularPageProps) => {
|
|
36
|
+
const component = new AngularExampleComponent();
|
|
37
|
+
component.initialCount = props.initialCount;
|
|
38
|
+
return component;
|
|
39
|
+
};
|
|
40
|
+
`;
|
|
41
|
+
export const generateAppComponent = () => `import { Component, Input, ViewEncapsulation } from '@angular/core';
|
|
42
|
+
import { CommonModule } from '@angular/common';
|
|
43
|
+
import { CounterComponent } from './counter.component';
|
|
44
|
+
|
|
45
|
+
@Component({
|
|
46
|
+
selector: 'app-root',
|
|
47
|
+
standalone: true,
|
|
48
|
+
imports: [CommonModule, CounterComponent],
|
|
49
|
+
templateUrl: './app.component.html',
|
|
50
|
+
styleUrls: ['./app.component.css'],
|
|
51
|
+
encapsulation: ViewEncapsulation.None
|
|
52
|
+
})
|
|
53
|
+
export class AppComponent {
|
|
54
|
+
@Input() initialCount: number = 0;
|
|
55
|
+
}
|
|
56
|
+
`;
|
|
57
|
+
export const generateAppComponentCss = () => ``;
|
|
58
|
+
export const generateAppComponentHtml = (frontends, editBasePath) => {
|
|
59
|
+
const exploreBlock = frontends.length > 1
|
|
60
|
+
? `\n\t<p style="margin-top: 2rem">\n\t\tExplore the other pages to see multiple frameworks running\n\t\ttogether.\n\t</p>`
|
|
61
|
+
: '';
|
|
62
|
+
return `<main>
|
|
63
|
+
<nav>
|
|
64
|
+
<a href="https://absolutejs.com" target="_blank">
|
|
65
|
+
<img
|
|
66
|
+
class="logo"
|
|
67
|
+
src="/assets/png/absolutejs-temp.png"
|
|
68
|
+
alt="AbsoluteJS Logo"
|
|
69
|
+
/>
|
|
70
|
+
</a>
|
|
71
|
+
<a href="https://angular.dev/">
|
|
72
|
+
<img
|
|
73
|
+
class="logo angular"
|
|
74
|
+
src="/assets/svg/angular.svg"
|
|
75
|
+
alt="Angular Logo"
|
|
76
|
+
/>
|
|
77
|
+
</a>
|
|
78
|
+
</nav>
|
|
79
|
+
<h1>AbsoluteJS + Angular</h1>
|
|
80
|
+
<app-counter [initialCount]="initialCount"></app-counter>
|
|
81
|
+
<p>
|
|
82
|
+
Edit <code>${editBasePath}/pages/angular-example.ts</code> and save to
|
|
83
|
+
test HMR.
|
|
84
|
+
</p>${exploreBlock}
|
|
85
|
+
<p style="color: #777; font-size: 1rem; margin-top: 2rem">
|
|
86
|
+
Click on the AbsoluteJS and Angular logos to learn more.
|
|
87
|
+
</p>
|
|
88
|
+
</main>
|
|
89
|
+
`;
|
|
90
|
+
};
|
|
91
|
+
export const generateCounterComponent = () => `import { Component, Input } from '@angular/core';
|
|
92
|
+
import { CommonModule } from '@angular/common';
|
|
93
|
+
|
|
94
|
+
@Component({
|
|
95
|
+
selector: 'app-counter',
|
|
96
|
+
standalone: true,
|
|
97
|
+
imports: [CommonModule],
|
|
98
|
+
template: \`
|
|
99
|
+
<button (click)="increment()">
|
|
100
|
+
count is <span class="counter-value">{{ count }}</span>
|
|
101
|
+
</button>
|
|
102
|
+
\`,
|
|
103
|
+
styles: [
|
|
104
|
+
\`
|
|
105
|
+
button {
|
|
106
|
+
background-color: #1a1a1a;
|
|
107
|
+
border: 1px solid transparent;
|
|
108
|
+
border-radius: 0.5rem;
|
|
109
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
110
|
+
cursor: pointer;
|
|
111
|
+
font-family: inherit;
|
|
112
|
+
font-size: 1.1rem;
|
|
113
|
+
font-weight: 500;
|
|
114
|
+
margin: 2rem 0;
|
|
115
|
+
padding: 0.6rem 1.2rem;
|
|
116
|
+
transition: border-color 0.25s;
|
|
117
|
+
}
|
|
118
|
+
button:hover {
|
|
119
|
+
border-color: #dd0031;
|
|
120
|
+
}
|
|
121
|
+
button:focus,
|
|
122
|
+
button:focus-visible {
|
|
123
|
+
outline: 4px auto -webkit-focus-ring-color;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
@media (prefers-color-scheme: light) {
|
|
127
|
+
button {
|
|
128
|
+
background-color: #ffffff;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
\`
|
|
132
|
+
]
|
|
133
|
+
})
|
|
134
|
+
export class CounterComponent {
|
|
135
|
+
@Input() initialCount: number = 0;
|
|
136
|
+
count: number = 0;
|
|
137
|
+
|
|
138
|
+
ngOnInit() {
|
|
139
|
+
this.count = this.initialCount;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
increment() {
|
|
143
|
+
this.count++;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
`;
|
|
147
|
+
export const generateDropdownComponent = (frontends) => {
|
|
148
|
+
const navLinks = frontends.map(formatNavLink).join('\n\t\t\t\t');
|
|
149
|
+
return `import { Component } from '@angular/core';
|
|
150
|
+
import { CommonModule } from '@angular/common';
|
|
151
|
+
|
|
152
|
+
@Component({
|
|
153
|
+
selector: 'app-dropdown',
|
|
154
|
+
standalone: true,
|
|
155
|
+
imports: [CommonModule],
|
|
156
|
+
template: \`
|
|
157
|
+
<details
|
|
158
|
+
class="dropdown"
|
|
159
|
+
[attr.open]="isOpen ? '' : null"
|
|
160
|
+
(mouseenter)="isOpen = true"
|
|
161
|
+
(mouseleave)="isOpen = false"
|
|
162
|
+
>
|
|
163
|
+
<summary>Pages</summary>
|
|
164
|
+
<nav class="menu">
|
|
165
|
+
${navLinks}
|
|
166
|
+
</nav>
|
|
167
|
+
</details>
|
|
168
|
+
\`,
|
|
169
|
+
styles: []
|
|
170
|
+
})
|
|
171
|
+
export class DropdownComponent {
|
|
172
|
+
isOpen = false;
|
|
173
|
+
}
|
|
174
|
+
`;
|
|
175
|
+
};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { copyFileSync, mkdirSync, writeFileSync } from 'fs';
|
|
2
|
+
import { join } from 'path';
|
|
3
|
+
import { generateMarkupCSS } from '../project/generateMarkupCSS';
|
|
4
|
+
import { generateAngularPage, generateAppComponent, generateAppComponentCss, generateAppComponentHtml, generateCounterComponent, generateDropdownComponent } from './generateAngularPage';
|
|
5
|
+
export const scaffoldAngular = ({ editBasePath, isSingleFrontend, targetDirectory, frontends, templatesDirectory, projectAssetsDirectory }) => {
|
|
6
|
+
copyFileSync(join(templatesDirectory, 'assets', 'svg', 'angular.svg'), join(projectAssetsDirectory, 'svg', 'angular.svg'));
|
|
7
|
+
const componentsDirectory = join(targetDirectory, 'components');
|
|
8
|
+
mkdirSync(componentsDirectory, { recursive: true });
|
|
9
|
+
const pagesDirectory = join(targetDirectory, 'pages');
|
|
10
|
+
mkdirSync(pagesDirectory, { recursive: true });
|
|
11
|
+
const stylesDirectory = join(targetDirectory, 'styles');
|
|
12
|
+
mkdirSync(stylesDirectory, { recursive: true });
|
|
13
|
+
writeFileSync(join(pagesDirectory, 'angular-example.ts'), generateAngularPage(frontends), 'utf-8');
|
|
14
|
+
writeFileSync(join(componentsDirectory, 'dropdown.component.ts'), generateDropdownComponent(frontends), 'utf-8');
|
|
15
|
+
writeFileSync(join(componentsDirectory, 'app.component.ts'), generateAppComponent(), 'utf-8');
|
|
16
|
+
writeFileSync(join(componentsDirectory, 'app.component.html'), generateAppComponentHtml(frontends, editBasePath), 'utf-8');
|
|
17
|
+
writeFileSync(join(componentsDirectory, 'app.component.css'), generateAppComponentCss(), 'utf-8');
|
|
18
|
+
writeFileSync(join(componentsDirectory, 'counter.component.ts'), generateCounterComponent(), 'utf-8');
|
|
19
|
+
const angularCSS = generateMarkupCSS('angular', '#dd0031', isSingleFrontend);
|
|
20
|
+
const customElementCSS = `
|
|
21
|
+
/* Flex wrappers for Angular custom elements */
|
|
22
|
+
angular-page {
|
|
23
|
+
display: flex;
|
|
24
|
+
flex: 1;
|
|
25
|
+
flex-direction: column;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
app-root {
|
|
29
|
+
display: flex;
|
|
30
|
+
flex: 1;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
}`;
|
|
33
|
+
writeFileSync(join(stylesDirectory, 'angular-example.css'), angularCSS + customElementCSS, 'utf-8');
|
|
34
|
+
};
|
|
@@ -52,6 +52,15 @@ export const createPackageJson = async ({ projectName, authOption, plugins, data
|
|
|
52
52
|
for (const dep of eslintReactDependencies)
|
|
53
53
|
packageNames.add(dep.value);
|
|
54
54
|
}
|
|
55
|
+
if (flags.requiresAngular) {
|
|
56
|
+
packageNames.add('@angular/common');
|
|
57
|
+
packageNames.add('@angular/compiler');
|
|
58
|
+
packageNames.add('@angular/compiler-cli');
|
|
59
|
+
packageNames.add('@angular/core');
|
|
60
|
+
packageNames.add('@angular/platform-browser');
|
|
61
|
+
packageNames.add('@angular/platform-server');
|
|
62
|
+
packageNames.add('@angular/ssr');
|
|
63
|
+
}
|
|
55
64
|
if (flags.requiresSvelte)
|
|
56
65
|
packageNames.add('svelte');
|
|
57
66
|
if (flags.requiresSvelte && codeQualityTool === 'eslint+prettier')
|
|
@@ -139,6 +148,20 @@ export const createPackageJson = async ({ projectName, authOption, plugins, data
|
|
|
139
148
|
devDependencies[dep.value] = resolveVersion(dep.value, dep.latestVersion);
|
|
140
149
|
});
|
|
141
150
|
}
|
|
151
|
+
if (flags.requiresAngular) {
|
|
152
|
+
const angularPackages = [
|
|
153
|
+
'@angular/common',
|
|
154
|
+
'@angular/compiler',
|
|
155
|
+
'@angular/compiler-cli',
|
|
156
|
+
'@angular/core',
|
|
157
|
+
'@angular/platform-browser',
|
|
158
|
+
'@angular/platform-server',
|
|
159
|
+
'@angular/ssr'
|
|
160
|
+
];
|
|
161
|
+
angularPackages.forEach((pkg) => {
|
|
162
|
+
dependencies[pkg] = resolveVersion(pkg, versions[pkg]);
|
|
163
|
+
});
|
|
164
|
+
}
|
|
142
165
|
if (flags.requiresSvelte) {
|
|
143
166
|
dependencies['svelte'] = resolveVersion('svelte', versions['svelte']);
|
|
144
167
|
}
|
|
@@ -168,9 +191,9 @@ export const createPackageJson = async ({ projectName, authOption, plugins, data
|
|
|
168
191
|
if (latest)
|
|
169
192
|
s.stop(green('Package versions resolved'));
|
|
170
193
|
const scripts = {
|
|
171
|
-
dev: '
|
|
172
|
-
format: `
|
|
173
|
-
lint: '
|
|
194
|
+
dev: 'absolute dev',
|
|
195
|
+
format: `absolute prettier --write "./**/*.{js,ts,css,json,mjs,md${flags.requiresReact ? ',jsx,tsx' : ''}${flags.requiresSvelte ? ',svelte' : ''}${flags.requiresVue ? ',vue' : ''}${flags.requiresHtml || flags.requiresHtmx ? ',html' : ''}}"`,
|
|
196
|
+
lint: 'absolute eslint',
|
|
174
197
|
test: 'echo "Error: no test specified" && exit 1',
|
|
175
198
|
typecheck: 'bun run tsc --noEmit'
|
|
176
199
|
};
|
|
@@ -1,11 +1,35 @@
|
|
|
1
|
-
import { copyFileSync, writeFileSync } from 'fs';
|
|
1
|
+
import { copyFileSync, readFileSync, writeFileSync } from 'fs';
|
|
2
2
|
import { join } from 'path';
|
|
3
3
|
import { dim, yellow } from 'picocolors';
|
|
4
4
|
import { generateEnv } from './generateEnv';
|
|
5
5
|
import { generateEslintConfig } from './generateEslintConfig';
|
|
6
6
|
import { generatePrettierrc } from './generatePrettierrc';
|
|
7
7
|
export const scaffoldConfigurationFiles = ({ tailwind, templatesDirectory, databaseEngine, envVariables, databaseHost, codeQualityTool, frontends, initializeGitNow, projectName }) => {
|
|
8
|
-
|
|
8
|
+
const hasAngular = frontends.includes('angular');
|
|
9
|
+
if (hasAngular) {
|
|
10
|
+
const templatePath = join(templatesDirectory, 'configurations', 'tsconfig.example.json');
|
|
11
|
+
const raw = readFileSync(templatePath, 'utf-8');
|
|
12
|
+
const stripped = raw
|
|
13
|
+
.replace(/\/\*[\s\S]*?\*\//g, '')
|
|
14
|
+
.replace(/\/\/[^\n]*/g, '')
|
|
15
|
+
.replace(/,\s*([}\]])/g, '$1');
|
|
16
|
+
const tsconfig = JSON.parse(stripped);
|
|
17
|
+
tsconfig.compilerOptions['emitDecoratorMetadata'] = true;
|
|
18
|
+
tsconfig.compilerOptions['experimentalDecorators'] = true;
|
|
19
|
+
tsconfig.compilerOptions['useDefineForClassFields'] = false;
|
|
20
|
+
const withAngular = {
|
|
21
|
+
angularCompilerOptions: {
|
|
22
|
+
enableI18nLegacyMessageIdFormat: false,
|
|
23
|
+
strictInjectionParameters: true,
|
|
24
|
+
strictTemplates: true
|
|
25
|
+
},
|
|
26
|
+
...tsconfig
|
|
27
|
+
};
|
|
28
|
+
writeFileSync(join(projectName, 'tsconfig.json'), JSON.stringify(withAngular, null, '\t'));
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
copyFileSync(join(templatesDirectory, 'configurations', 'tsconfig.example.json'), join(projectName, 'tsconfig.json'));
|
|
32
|
+
}
|
|
9
33
|
if (tailwind) {
|
|
10
34
|
copyFileSync(join(templatesDirectory, 'tailwind', 'postcss.config.ts'), join(projectName, 'postcss.config.ts'));
|
|
11
35
|
copyFileSync(join(templatesDirectory, 'tailwind', 'tailwind.config.ts'), join(projectName, 'tailwind.config.ts'));
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
export declare const userTables: {
|
|
2
|
-
readonly cockroachdb: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n metadata JSONB DEFAULT '{}'::jsonb\n);";
|
|
3
|
-
readonly gel: "create type users {\n create required property auth_sub: str {\n create constraint exclusive;\n };\n\n create required property created_at: datetime {\n set default := datetime_current();\n };\n\n create required property metadata: json {\n set default := to_json('{}');\n };\n};";
|
|
4
|
-
readonly mariadb: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSON DEFAULT ('{}')\n);";
|
|
5
|
-
readonly mssql: "IF OBJECT_ID('users','U') IS NULL\nBEGIN\n CREATE TABLE users (\n auth_sub NVARCHAR(255) PRIMARY KEY,\n created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),\n metadata NVARCHAR(MAX) NULL\n );\nEND;";
|
|
6
|
-
readonly mysql: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSON DEFAULT (JSON_OBJECT())\n);";
|
|
7
|
-
readonly postgresql: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n metadata JSONB DEFAULT '{}'::jsonb\n);";
|
|
8
|
-
readonly singlestore: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSON DEFAULT ('{}')\n);";
|
|
9
|
-
};
|
|
10
1
|
export declare const countHistoryTables: {
|
|
11
2
|
readonly cockroachdb: "CREATE SEQUENCE IF NOT EXISTS count_history_uid_seq START WITH 1 INCREMENT BY 1;\nCREATE TABLE IF NOT EXISTS count_history (\n uid BIGINT PRIMARY KEY DEFAULT nextval('count_history_uid_seq'),\n count INT NOT NULL,\n created_at TIMESTAMP NOT NULL DEFAULT NOW()\n);";
|
|
12
3
|
readonly gel: "create scalar type CountHistoryUid extending sequence;\ncreate type count_history {\n create required property uid: CountHistoryUid {\n create constraint exclusive;\n set default := sequence_next(introspect CountHistoryUid);\n };\n\n create required property count: int16;\n\n create required property created_at: datetime {\n set default := datetime_current();\n };\n};";
|
|
@@ -50,3 +41,12 @@ export declare const initTemplates: {
|
|
|
50
41
|
readonly wait: "until singlestore -u root -ppassword -e \"SELECT 1\" >/dev/null 2>&1; do sleep 1; done";
|
|
51
42
|
};
|
|
52
43
|
};
|
|
44
|
+
export declare const userTables: {
|
|
45
|
+
readonly cockroachdb: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n metadata JSONB DEFAULT '{}'::jsonb\n);";
|
|
46
|
+
readonly gel: "create type users {\n create required property auth_sub: str {\n create constraint exclusive;\n };\n\n create required property created_at: datetime {\n set default := datetime_current();\n };\n\n create required property metadata: json {\n set default := to_json('{}');\n };\n};";
|
|
47
|
+
readonly mariadb: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSON DEFAULT ('{}')\n);";
|
|
48
|
+
readonly mssql: "IF OBJECT_ID('users','U') IS NULL\nBEGIN\n CREATE TABLE users (\n auth_sub NVARCHAR(255) PRIMARY KEY,\n created_at DATETIME2 NOT NULL DEFAULT SYSUTCDATETIME(),\n metadata NVARCHAR(MAX) NULL\n );\nEND;";
|
|
49
|
+
readonly mysql: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSON DEFAULT (JSON_OBJECT())\n);";
|
|
50
|
+
readonly postgresql: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT NOW(),\n metadata JSONB DEFAULT '{}'::jsonb\n);";
|
|
51
|
+
readonly singlestore: "CREATE TABLE IF NOT EXISTS users (\n auth_sub VARCHAR(255) PRIMARY KEY,\n created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,\n metadata JSON DEFAULT ('{}')\n);";
|
|
52
|
+
};
|
|
@@ -91,15 +91,6 @@ create type count_history {
|
|
|
91
91
|
set default := datetime_current();
|
|
92
92
|
};
|
|
93
93
|
};`;
|
|
94
|
-
export const userTables = {
|
|
95
|
-
cockroachdb: cockroachdbUsers,
|
|
96
|
-
gel: gelUsers,
|
|
97
|
-
mariadb: mariadbUsers,
|
|
98
|
-
mssql: mssqlUsers,
|
|
99
|
-
mysql: mysqlUsers,
|
|
100
|
-
postgresql: postgresqlUsers,
|
|
101
|
-
singlestore: singlestoreUsers
|
|
102
|
-
};
|
|
103
94
|
export const countHistoryTables = {
|
|
104
95
|
cockroachdb: cockroachdbCountHistory,
|
|
105
96
|
gel: gelCountHistory,
|
|
@@ -143,3 +134,12 @@ export const initTemplates = {
|
|
|
143
134
|
wait: 'until singlestore -u root -ppassword -e "SELECT 1" >/dev/null 2>&1; do sleep 1; done'
|
|
144
135
|
}
|
|
145
136
|
};
|
|
137
|
+
export const userTables = {
|
|
138
|
+
cockroachdb: cockroachdbUsers,
|
|
139
|
+
gel: gelUsers,
|
|
140
|
+
mariadb: mariadbUsers,
|
|
141
|
+
mssql: mssqlUsers,
|
|
142
|
+
mysql: mysqlUsers,
|
|
143
|
+
postgresql: postgresqlUsers,
|
|
144
|
+
singlestore: singlestoreUsers
|
|
145
|
+
};
|
|
@@ -34,6 +34,11 @@ export const generateDatabaseTypes = ({ databaseEngine, databaseHost, authOption
|
|
|
34
34
|
dbTypeLine =
|
|
35
35
|
'export type DatabaseType = Mysql2Database<SchemaType>;';
|
|
36
36
|
break;
|
|
37
|
+
case 'mssql':
|
|
38
|
+
dbImport = `import { NodeMssqlDatabase } from 'drizzle-orm/node-mssql';`;
|
|
39
|
+
dbTypeLine =
|
|
40
|
+
'export type DatabaseType = NodeMssqlDatabase<SchemaType>;';
|
|
41
|
+
break;
|
|
37
42
|
case 'postgresql':
|
|
38
43
|
dbImport = `import { BunSQLDatabase } from 'drizzle-orm/bun-sql';`;
|
|
39
44
|
dbTypeLine =
|