@tdk-landscape/tdk-cli-core 1.3.87 ā 1.3.88
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 +4 -4
- package/cli/dist/backend-frameworks/express.js +50 -0
- package/cli/dist/backend-frameworks/registry.js +41 -0
- package/cli/dist/backend-frameworks/types.js +2 -0
- package/cli/dist/commands/resource.js +27 -5
- package/cli/dist/frontend-frameworks/lit.js +65 -0
- package/cli/dist/frontend-frameworks/preact.js +63 -0
- package/cli/dist/frontend-frameworks/qwik.js +62 -0
- package/cli/dist/frontend-frameworks/registry.js +14 -3
- package/cli/dist/frontend-frameworks/solid.js +63 -0
- package/cli/dist/frontend-frameworks/svelte.js +68 -0
- package/cli/dist/utils/service-manifest.js +1 -0
- package/cli/package.json +2 -2
- package/engine/schemas/service-schema.json +25 -6
- package/engine/topologies/platform/docker/compose/compose.star +9 -1
- package/engine/topologies/tilt/generators/typescript/frontend_tsconfig.star +10 -1
- package/engine/topologies/tilt/generators/validators.star +1 -1
- package/engine/topologies/tilt/generators/vite/frameworks/lit.star +90 -0
- package/engine/topologies/tilt/generators/vite/frameworks/preact.star +92 -0
- package/engine/topologies/tilt/generators/vite/frameworks/qwik.star +92 -0
- package/engine/topologies/tilt/generators/vite/frameworks/solid.star +92 -0
- package/engine/topologies/tilt/generators/vite/frameworks/svelte.star +92 -0
- package/engine/topologies/tilt/generators/vite/frontend.star +25 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -18,11 +18,11 @@ tdk up shop
|
|
|
18
18
|
curl http://api.shop.localhost/api/orders-api/health
|
|
19
19
|
```
|
|
20
20
|
|
|
21
|
-

|
|
21
|
+

|
|
22
22
|
|
|
23
23
|
*Scaffolding a backend and frontend, then listing the stack.*
|
|
24
24
|
|
|
25
|
-

|
|
25
|
+

|
|
26
26
|
|
|
27
27
|
If Helm, Compose, or your existing Tilt setup already gives you a working local environment, keep using it. TDK CLI is for engineers managing several services who want a clear local service contract and one command to start the stack.
|
|
28
28
|
|
|
@@ -66,9 +66,9 @@ curl -fsSL https://tdk-landscape.github.io/install.sh | sh
|
|
|
66
66
|
- [Features and license limits](docs/FEATURES.md)
|
|
67
67
|
- [Honest comparison and known limits](docs/compare-honest.md)
|
|
68
68
|
- [Public claims registry](docs/claims.md)
|
|
69
|
-
- [Show HN draft](docs/show-hn.md)
|
|
69
|
+
- [Show HN draft](docs/drafts/show-hn.md)
|
|
70
70
|
- [Architecture and repository map](docs/project-overview.md)
|
|
71
|
-
- [Scale fixture measurements and caveats](docs/scale-bench.md)
|
|
71
|
+
- [Scale fixture measurements and caveats](docs/benchmarks/scale-bench.md)
|
|
72
72
|
|
|
73
73
|
## Requirements and support
|
|
74
74
|
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
export function getExpressIndexTemplate(name) {
|
|
2
|
+
return `import express from 'express';
|
|
3
|
+
|
|
4
|
+
const app = express();
|
|
5
|
+
|
|
6
|
+
// Health check endpoint (required by TILT_RESOURCE_DEFAULTS.star)
|
|
7
|
+
app.get('/health', (_req, res) => {
|
|
8
|
+
res.json({ status: 'ok', service: '${name}' });
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
app.get('/health/live', (_req, res) => {
|
|
12
|
+
res.json({ status: 'alive', timestamp: Date.now() });
|
|
13
|
+
});
|
|
14
|
+
|
|
15
|
+
app.get('/health/ready', async (_req, res) => {
|
|
16
|
+
const dependencies: Record<string, string> = {};
|
|
17
|
+
let allReady = true;
|
|
18
|
+
|
|
19
|
+
// Add dependency checks here (database, cache, etc.)
|
|
20
|
+
// Mark allReady = false if any dependency is unhealthy
|
|
21
|
+
|
|
22
|
+
const status = allReady ? 'ready' : 'not_ready';
|
|
23
|
+
res.status(allReady ? 200 : 503).json({ status, dependencies });
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
app.get('/', (_req, res) => {
|
|
27
|
+
res.json({
|
|
28
|
+
service: '${name}',
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
endpoints: ['/health', '/health/live', '/health/ready']
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
const port = Number(process.env.PORT || 3000);
|
|
35
|
+
|
|
36
|
+
// Bind beyond loopback: Traefik reaches the container over the Docker network.
|
|
37
|
+
app.listen(port, '0.0.0.0', () => {
|
|
38
|
+
console.log('\\nš ${name} running on http://localhost:' + port);
|
|
39
|
+
console.log('š Health check: http://localhost:' + port + '/health\\n');
|
|
40
|
+
});
|
|
41
|
+
`;
|
|
42
|
+
}
|
|
43
|
+
export const expressBackendProvider = {
|
|
44
|
+
id: "express",
|
|
45
|
+
label: "Bun + Express",
|
|
46
|
+
dependencies: { express: "^5.1.0" },
|
|
47
|
+
devDependencies: { "@types/express": "^5.0.0" },
|
|
48
|
+
createIndex: getExpressIndexTemplate,
|
|
49
|
+
};
|
|
50
|
+
//# sourceMappingURL=express.js.map
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { getBackendIndexTemplate } from "../backend-languages/bun.js";
|
|
2
|
+
import { TdkError } from "../utils/errors.js";
|
|
3
|
+
import { expressBackendProvider } from "./express.js";
|
|
4
|
+
/** Hono is the historical default; omitting --framework keeps the exact historical output. */
|
|
5
|
+
export const DEFAULT_BACKEND_FRAMEWORK = "hono";
|
|
6
|
+
export const honoBackendProvider = {
|
|
7
|
+
id: "hono",
|
|
8
|
+
label: "Bun + Hono",
|
|
9
|
+
dependencies: { hono: "^4.0.0" },
|
|
10
|
+
devDependencies: {},
|
|
11
|
+
createIndex: getBackendIndexTemplate,
|
|
12
|
+
};
|
|
13
|
+
export const BACKEND_FRAMEWORKS = {
|
|
14
|
+
hono: honoBackendProvider,
|
|
15
|
+
express: expressBackendProvider,
|
|
16
|
+
};
|
|
17
|
+
export function getBackendFramework(frameworkId) {
|
|
18
|
+
const id = (frameworkId ?? DEFAULT_BACKEND_FRAMEWORK).trim().toLowerCase();
|
|
19
|
+
const provider = Object.hasOwn(BACKEND_FRAMEWORKS, id) ? BACKEND_FRAMEWORKS[id] : undefined;
|
|
20
|
+
if (!provider) {
|
|
21
|
+
const supportedIds = Object.keys(BACKEND_FRAMEWORKS).join(", ");
|
|
22
|
+
throw new TdkError(`Unknown backend framework "${frameworkId}". Supported frameworks: ${supportedIds}.`, [`Use one of: ${supportedIds}`, `Omit --framework to use ${DEFAULT_BACKEND_FRAMEWORK}`]);
|
|
23
|
+
}
|
|
24
|
+
return provider;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Returns the provider for an explicit `--framework` on a backend, or undefined when none was given
|
|
28
|
+
* (the historical Hono scaffold). Python owns its runtime, so a framework cannot be combined with it.
|
|
29
|
+
*/
|
|
30
|
+
export function resolveBackendFramework(resourceType, frameworkId, language) {
|
|
31
|
+
if (resourceType !== "backend" || frameworkId === undefined)
|
|
32
|
+
return undefined;
|
|
33
|
+
if (language?.createFiles) {
|
|
34
|
+
throw new TdkError(`--framework cannot be combined with --language ${language.id}.`, [
|
|
35
|
+
`The ${language.id} provider owns its runtime and framework`,
|
|
36
|
+
"Drop --framework, or use --language bun",
|
|
37
|
+
]);
|
|
38
|
+
}
|
|
39
|
+
return getBackendFramework(frameworkId);
|
|
40
|
+
}
|
|
41
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -2,6 +2,7 @@ import { existsSync, mkdirSync } from "node:fs";
|
|
|
2
2
|
import { isAbsolute, relative, resolve } from "node:path";
|
|
3
3
|
import chalk from "chalk";
|
|
4
4
|
import { Command } from "commander";
|
|
5
|
+
import { resolveBackendFramework } from "../backend-frameworks/registry.js";
|
|
5
6
|
import { getBackendIndexTemplate } from "../backend-languages/bun.js";
|
|
6
7
|
import { resolveBackendLanguage } from "../backend-languages/registry.js";
|
|
7
8
|
import { resolveFrontendFramework } from "../frontend-frameworks/registry.js";
|
|
@@ -50,6 +51,7 @@ export const TYPE_SPECIFIC = {
|
|
|
50
51
|
healthCheck: "/health",
|
|
51
52
|
},
|
|
52
53
|
};
|
|
54
|
+
const BYO_RESTART_POLICIES = ["no", "on-failure", "unless-stopped", "always"];
|
|
53
55
|
export function resolveByoPort(value, assignedPort, resources) {
|
|
54
56
|
if (!value)
|
|
55
57
|
return assignedPort;
|
|
@@ -69,6 +71,8 @@ export function createServiceJson(name, type, stack, port, extraFeatures = [], f
|
|
|
69
71
|
const framework = resolveFrontendFramework(type, frameworkId);
|
|
70
72
|
// Only an explicit selection is persisted: a missing `language` has always meant Bun.
|
|
71
73
|
const language = languageId === undefined ? undefined : resolveBackendLanguage(type, languageId);
|
|
74
|
+
// Likewise a missing backend `framework` has always meant Hono.
|
|
75
|
+
const backendFramework = resolveBackendFramework(type, frameworkId, language);
|
|
72
76
|
const typeSpecific = TYPE_SPECIFIC[type];
|
|
73
77
|
const base = JSON.parse(JSON.stringify(BASE_TEMPLATE));
|
|
74
78
|
for (const [key, value] of Object.entries(typeSpecific)) {
|
|
@@ -105,12 +109,14 @@ export function createServiceJson(name, type, stack, port, extraFeatures = [], f
|
|
|
105
109
|
stack,
|
|
106
110
|
port,
|
|
107
111
|
...(framework ? { framework: framework.id } : {}),
|
|
112
|
+
...(backendFramework ? { framework: backendFramework.id } : {}),
|
|
108
113
|
...(language ? { language: language.id } : {}),
|
|
109
114
|
};
|
|
110
115
|
}
|
|
111
116
|
export function createPackageJson(name, type, frameworkId) {
|
|
112
117
|
const isFrontend = type === "frontend";
|
|
113
118
|
const framework = resolveFrontendFramework(type, frameworkId);
|
|
119
|
+
const backendFramework = resolveBackendFramework(type, frameworkId);
|
|
114
120
|
return {
|
|
115
121
|
name: `@project/${name}`,
|
|
116
122
|
version: "0.0.1",
|
|
@@ -129,7 +135,7 @@ export function createPackageJson(name, type, frameworkId) {
|
|
|
129
135
|
"lint:fix": "biome check . --write",
|
|
130
136
|
},
|
|
131
137
|
dependencies: {
|
|
132
|
-
...(isFrontend ? {} : { hono: "^4.0.0" }),
|
|
138
|
+
...(isFrontend ? {} : (backendFramework?.dependencies ?? { hono: "^4.0.0" })),
|
|
133
139
|
...(framework?.dependencies ?? {}),
|
|
134
140
|
},
|
|
135
141
|
devDependencies: {
|
|
@@ -142,6 +148,7 @@ export function createPackageJson(name, type, frameworkId) {
|
|
|
142
148
|
"@biomejs/biome": "^2.5.13",
|
|
143
149
|
...(isFrontend ? { vite: "^5.0.0" } : {}),
|
|
144
150
|
...(framework?.devDependencies ?? {}),
|
|
151
|
+
...(backendFramework?.devDependencies ?? {}),
|
|
145
152
|
},
|
|
146
153
|
};
|
|
147
154
|
}
|
|
@@ -288,7 +295,7 @@ export const resourceCommand = new Command("resource")
|
|
|
288
295
|
.description("Create a new resource (service) from scratch, or register an existing one")
|
|
289
296
|
.argument("[name]", "Resource name (kebab-case)")
|
|
290
297
|
.option("-t, --type <type>", "Resource type: backend, frontend, worker, bring-your-own, sdk", "backend")
|
|
291
|
-
.option("--framework <id>", "
|
|
298
|
+
.option("--framework <id>", "Framework: frontend react (default), vue, svelte, preact, lit, solid, qwik; backend hono (default), express")
|
|
292
299
|
.option("--language <id>", "Backend language: bun (default), python")
|
|
293
300
|
.option("-s, --stack <stack>", "Stack to assign resource to", "default")
|
|
294
301
|
.option("-p, --path <path>", "Custom path for resource directory")
|
|
@@ -299,6 +306,7 @@ export const resourceCommand = new Command("resource")
|
|
|
299
306
|
.option("--dockerfile <path>", "Path to Dockerfile relative to resource dir (for bring-your-own)")
|
|
300
307
|
.option("--health-path <path>", "HTTP health check path (for bring-your-own)", "/health")
|
|
301
308
|
.option("--no-proxy", "Disable the Traefik route (bring-your-own only)")
|
|
309
|
+
.option("--restart <policy>", "Compose restart policy: no, on-failure, unless-stopped, always (bring-your-own only; use no for one-shot jobs)")
|
|
302
310
|
.option("--image <name>", "Docker image name instead of building from Dockerfile (for bring-your-own)")
|
|
303
311
|
.option("--port <port>", "Port number (default: next free in 4000-5999)")
|
|
304
312
|
.action(async (name, options) => {
|
|
@@ -350,6 +358,7 @@ export const resourceCommand = new Command("resource")
|
|
|
350
358
|
}
|
|
351
359
|
const frontendFramework = resolveFrontendFramework(resourceType, options.framework);
|
|
352
360
|
const backendLanguage = resolveBackendLanguage(resourceType, options.language);
|
|
361
|
+
const backendFramework = resolveBackendFramework(resourceType, options.framework, backendLanguage);
|
|
353
362
|
let dddEnabled = false;
|
|
354
363
|
if (options.ddd) {
|
|
355
364
|
if (resourceType !== "backend" && resourceType !== "worker") {
|
|
@@ -446,6 +455,18 @@ export const resourceCommand = new Command("resource")
|
|
|
446
455
|
const nextPort = resourceType === "sdk"
|
|
447
456
|
? 0
|
|
448
457
|
: assignPort(resourceType, allResources);
|
|
458
|
+
if (options.restart !== undefined) {
|
|
459
|
+
if (resourceType !== "bring-your-own") {
|
|
460
|
+
throw new TdkError("--restart can only be used with --type bring-your-own.", [
|
|
461
|
+
"Add --type bring-your-own, or drop --restart",
|
|
462
|
+
]);
|
|
463
|
+
}
|
|
464
|
+
if (!BYO_RESTART_POLICIES.includes(options.restart)) {
|
|
465
|
+
throw new TdkError(`Unknown --restart policy "${options.restart}".`, [
|
|
466
|
+
`Use one of: ${BYO_RESTART_POLICIES.join(", ")}`,
|
|
467
|
+
]);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
449
470
|
const assignedPort = resourceType === "bring-your-own"
|
|
450
471
|
? resolveByoPort(options.port, nextPort, allResources)
|
|
451
472
|
: nextPort;
|
|
@@ -515,6 +536,7 @@ export const resourceCommand = new Command("resource")
|
|
|
515
536
|
healthCheckPath: options.healthPath || "/health",
|
|
516
537
|
...(options.image ? { image: options.image } : { dockerfile }),
|
|
517
538
|
...(options.proxy === false ? { exposeViaProxy: false } : {}),
|
|
539
|
+
...(options.restart ? { restart: options.restart } : {}),
|
|
518
540
|
};
|
|
519
541
|
const { writeFileSync } = await import("node:fs");
|
|
520
542
|
writeFileSync(resolve(fullPath, "service.json"), JSON.stringify(byoServiceJson, null, 2));
|
|
@@ -573,8 +595,8 @@ This file contains the resource configuration for TDK.
|
|
|
573
595
|
}
|
|
574
596
|
}
|
|
575
597
|
// Prepare file generation tasks
|
|
576
|
-
const serviceJson = createServiceJson(resourceName, resourceType, stackName, assignedPort, dddEnabled ? ["ddd"] : [], frontendFramework?.id, options.language === undefined ? undefined : backendLanguage?.id);
|
|
577
|
-
const packageJson = createPackageJson(resourceName, resourceType, frontendFramework?.id);
|
|
598
|
+
const serviceJson = createServiceJson(resourceName, resourceType, stackName, assignedPort, dddEnabled ? ["ddd"] : [], frontendFramework?.id ?? backendFramework?.id, options.language === undefined ? undefined : backendLanguage?.id);
|
|
599
|
+
const packageJson = createPackageJson(resourceName, resourceType, frontendFramework?.id ?? backendFramework?.id);
|
|
578
600
|
const tasks = [
|
|
579
601
|
{
|
|
580
602
|
type: "json",
|
|
@@ -610,7 +632,7 @@ This file contains the resource configuration for TDK.
|
|
|
610
632
|
tasks.push({
|
|
611
633
|
type: "text",
|
|
612
634
|
filename: "src/index.ts",
|
|
613
|
-
content: getBackendIndexTemplate(resourceName),
|
|
635
|
+
content: (backendFramework?.createIndex ?? getBackendIndexTemplate)(resourceName),
|
|
614
636
|
description: "Generating backend source",
|
|
615
637
|
emoji: "š»",
|
|
616
638
|
});
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
export const litFrontendProvider = {
|
|
2
|
+
id: "lit",
|
|
3
|
+
label: "Lit + Vite",
|
|
4
|
+
dependencies: {
|
|
5
|
+
lit: "^3.2.0",
|
|
6
|
+
},
|
|
7
|
+
devDependencies: {},
|
|
8
|
+
compilerOptions: {},
|
|
9
|
+
createFiles(name) {
|
|
10
|
+
return [
|
|
11
|
+
{
|
|
12
|
+
filename: "index.html",
|
|
13
|
+
content: `<!DOCTYPE html>
|
|
14
|
+
<html lang="en">
|
|
15
|
+
<head>
|
|
16
|
+
<meta charset="UTF-8" />
|
|
17
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
18
|
+
<title>${name}</title>
|
|
19
|
+
</head>
|
|
20
|
+
<body>
|
|
21
|
+
<app-root></app-root>
|
|
22
|
+
<script type="module" src="/src/main.ts"></script>
|
|
23
|
+
</body>
|
|
24
|
+
</html>
|
|
25
|
+
`,
|
|
26
|
+
description: "Generating HTML template",
|
|
27
|
+
emoji: "š»",
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
filename: "src/main.ts",
|
|
31
|
+
content: `import './app-root';
|
|
32
|
+
`,
|
|
33
|
+
description: "Generating Lit entry",
|
|
34
|
+
emoji: "š»",
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
filename: "src/app-root.ts",
|
|
38
|
+
content: `import { LitElement, css, html } from 'lit';
|
|
39
|
+
|
|
40
|
+
export class AppRoot extends LitElement {
|
|
41
|
+
static styles = css\`
|
|
42
|
+
:host {
|
|
43
|
+
display: block;
|
|
44
|
+
padding: 2rem;
|
|
45
|
+
font-family: system-ui;
|
|
46
|
+
}
|
|
47
|
+
\`;
|
|
48
|
+
|
|
49
|
+
render() {
|
|
50
|
+
return html\`
|
|
51
|
+
<h1>${name}</h1>
|
|
52
|
+
<p>Frontend resource created with TDK</p>
|
|
53
|
+
\`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
customElements.define('app-root', AppRoot);
|
|
58
|
+
`,
|
|
59
|
+
description: "Generating Lit app",
|
|
60
|
+
emoji: "š»",
|
|
61
|
+
},
|
|
62
|
+
];
|
|
63
|
+
},
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=lit.js.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const preactFrontendProvider = {
|
|
2
|
+
id: "preact",
|
|
3
|
+
label: "Preact + Vite",
|
|
4
|
+
dependencies: {
|
|
5
|
+
preact: "^10.26.0",
|
|
6
|
+
},
|
|
7
|
+
devDependencies: {
|
|
8
|
+
"@preact/preset-vite": "^2.10.0",
|
|
9
|
+
},
|
|
10
|
+
compilerOptions: {
|
|
11
|
+
jsx: "react-jsx",
|
|
12
|
+
jsxImportSource: "preact",
|
|
13
|
+
},
|
|
14
|
+
createFiles(name) {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
filename: "index.html",
|
|
18
|
+
content: `<!DOCTYPE html>
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<meta charset="UTF-8" />
|
|
22
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
23
|
+
<title>${name}</title>
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<div id="app"></div>
|
|
27
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
30
|
+
`,
|
|
31
|
+
description: "Generating HTML template",
|
|
32
|
+
emoji: "š»",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
filename: "src/main.tsx",
|
|
36
|
+
content: `import { render } from 'preact';
|
|
37
|
+
import App from './App';
|
|
38
|
+
|
|
39
|
+
render(<App />, document.getElementById('app')!);
|
|
40
|
+
`,
|
|
41
|
+
description: "Generating Preact entry",
|
|
42
|
+
emoji: "š»",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
filename: "src/App.tsx",
|
|
46
|
+
content: `function App() {
|
|
47
|
+
return (
|
|
48
|
+
<div style={{ padding: '2rem', fontFamily: 'system-ui' }}>
|
|
49
|
+
<h1>${name}</h1>
|
|
50
|
+
<p>Frontend resource created with TDK</p>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default App;
|
|
56
|
+
`,
|
|
57
|
+
description: "Generating Preact app",
|
|
58
|
+
emoji: "š»",
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=preact.js.map
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
export const qwikFrontendProvider = {
|
|
2
|
+
id: "qwik",
|
|
3
|
+
label: "Qwik + Vite",
|
|
4
|
+
dependencies: {
|
|
5
|
+
"@builder.io/qwik": "^1.12.0",
|
|
6
|
+
},
|
|
7
|
+
devDependencies: {},
|
|
8
|
+
compilerOptions: {
|
|
9
|
+
jsx: "react-jsx",
|
|
10
|
+
jsxImportSource: "@builder.io/qwik",
|
|
11
|
+
},
|
|
12
|
+
createFiles(name) {
|
|
13
|
+
return [
|
|
14
|
+
{
|
|
15
|
+
filename: "index.html",
|
|
16
|
+
content: `<!DOCTYPE html>
|
|
17
|
+
<html lang="en">
|
|
18
|
+
<head>
|
|
19
|
+
<meta charset="UTF-8" />
|
|
20
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
21
|
+
<title>${name}</title>
|
|
22
|
+
</head>
|
|
23
|
+
<body>
|
|
24
|
+
<div id="app"></div>
|
|
25
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
26
|
+
</body>
|
|
27
|
+
</html>
|
|
28
|
+
`,
|
|
29
|
+
description: "Generating HTML template",
|
|
30
|
+
emoji: "š»",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
filename: "src/main.tsx",
|
|
34
|
+
content: `import '@builder.io/qwik/qwikloader.js';
|
|
35
|
+
import { render } from '@builder.io/qwik';
|
|
36
|
+
import { App } from './App';
|
|
37
|
+
|
|
38
|
+
render(document.getElementById('app') as HTMLElement, <App />);
|
|
39
|
+
`,
|
|
40
|
+
description: "Generating Qwik entry",
|
|
41
|
+
emoji: "š»",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
filename: "src/App.tsx",
|
|
45
|
+
content: `import { component$ } from '@builder.io/qwik';
|
|
46
|
+
|
|
47
|
+
export const App = component$(() => {
|
|
48
|
+
return (
|
|
49
|
+
<div style={{ padding: '2rem', fontFamily: 'system-ui' }}>
|
|
50
|
+
<h1>${name}</h1>
|
|
51
|
+
<p>Frontend resource created with TDK</p>
|
|
52
|
+
</div>
|
|
53
|
+
);
|
|
54
|
+
});
|
|
55
|
+
`,
|
|
56
|
+
description: "Generating Qwik app",
|
|
57
|
+
emoji: "š»",
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=qwik.js.map
|
|
@@ -1,10 +1,20 @@
|
|
|
1
1
|
import { TdkError } from "../utils/errors.js";
|
|
2
|
+
import { litFrontendProvider } from "./lit.js";
|
|
3
|
+
import { preactFrontendProvider } from "./preact.js";
|
|
4
|
+
import { qwikFrontendProvider } from "./qwik.js";
|
|
2
5
|
import { reactFrontendProvider } from "./react.js";
|
|
6
|
+
import { solidFrontendProvider } from "./solid.js";
|
|
7
|
+
import { svelteFrontendProvider } from "./svelte.js";
|
|
3
8
|
import { vueFrontendProvider } from "./vue.js";
|
|
4
9
|
export const DEFAULT_FRONTEND_FRAMEWORK = "react";
|
|
5
10
|
export const FRONTEND_FRAMEWORKS = {
|
|
6
11
|
react: reactFrontendProvider,
|
|
7
12
|
vue: vueFrontendProvider,
|
|
13
|
+
svelte: svelteFrontendProvider,
|
|
14
|
+
preact: preactFrontendProvider,
|
|
15
|
+
lit: litFrontendProvider,
|
|
16
|
+
solid: solidFrontendProvider,
|
|
17
|
+
qwik: qwikFrontendProvider,
|
|
8
18
|
};
|
|
9
19
|
export function getFrontendFramework(frameworkId) {
|
|
10
20
|
const id = (frameworkId ?? DEFAULT_FRONTEND_FRAMEWORK).trim().toLowerCase();
|
|
@@ -17,9 +27,10 @@ export function getFrontendFramework(frameworkId) {
|
|
|
17
27
|
}
|
|
18
28
|
export function resolveFrontendFramework(resourceType, frameworkId) {
|
|
19
29
|
if (resourceType !== "frontend") {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
30
|
+
// Backends take their own framework ids (see backend-frameworks/registry.ts).
|
|
31
|
+
if (frameworkId !== undefined && resourceType !== "backend") {
|
|
32
|
+
throw new TdkError("--framework can only be used with --type frontend or --type backend.", [
|
|
33
|
+
"Add --type frontend or --type backend, or drop --framework for this resource type",
|
|
23
34
|
]);
|
|
24
35
|
}
|
|
25
36
|
return undefined;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const solidFrontendProvider = {
|
|
2
|
+
id: "solid",
|
|
3
|
+
label: "Solid + Vite",
|
|
4
|
+
dependencies: {
|
|
5
|
+
"solid-js": "^1.9.0",
|
|
6
|
+
},
|
|
7
|
+
devDependencies: {
|
|
8
|
+
"vite-plugin-solid": "^2.11.0",
|
|
9
|
+
},
|
|
10
|
+
compilerOptions: {
|
|
11
|
+
jsx: "preserve",
|
|
12
|
+
jsxImportSource: "solid-js",
|
|
13
|
+
},
|
|
14
|
+
createFiles(name) {
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
filename: "index.html",
|
|
18
|
+
content: `<!DOCTYPE html>
|
|
19
|
+
<html lang="en">
|
|
20
|
+
<head>
|
|
21
|
+
<meta charset="UTF-8" />
|
|
22
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
23
|
+
<title>${name}</title>
|
|
24
|
+
</head>
|
|
25
|
+
<body>
|
|
26
|
+
<div id="app"></div>
|
|
27
|
+
<script type="module" src="/src/main.tsx"></script>
|
|
28
|
+
</body>
|
|
29
|
+
</html>
|
|
30
|
+
`,
|
|
31
|
+
description: "Generating HTML template",
|
|
32
|
+
emoji: "š»",
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
filename: "src/main.tsx",
|
|
36
|
+
content: `import { render } from 'solid-js/web';
|
|
37
|
+
import App from './App';
|
|
38
|
+
|
|
39
|
+
render(() => <App />, document.getElementById('app')!);
|
|
40
|
+
`,
|
|
41
|
+
description: "Generating Solid entry",
|
|
42
|
+
emoji: "š»",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
filename: "src/App.tsx",
|
|
46
|
+
content: `function App() {
|
|
47
|
+
return (
|
|
48
|
+
<div style={{ padding: '2rem', 'font-family': 'system-ui' }}>
|
|
49
|
+
<h1>${name}</h1>
|
|
50
|
+
<p>Frontend resource created with TDK</p>
|
|
51
|
+
</div>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export default App;
|
|
56
|
+
`,
|
|
57
|
+
description: "Generating Solid app",
|
|
58
|
+
emoji: "š»",
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
//# sourceMappingURL=solid.js.map
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
export const svelteFrontendProvider = {
|
|
2
|
+
id: "svelte",
|
|
3
|
+
label: "Svelte + Vite",
|
|
4
|
+
dependencies: {
|
|
5
|
+
svelte: "^5.0.0",
|
|
6
|
+
},
|
|
7
|
+
devDependencies: {
|
|
8
|
+
"@sveltejs/vite-plugin-svelte": "^4.0.4",
|
|
9
|
+
},
|
|
10
|
+
compilerOptions: {},
|
|
11
|
+
createFiles(name) {
|
|
12
|
+
return [
|
|
13
|
+
{
|
|
14
|
+
filename: "index.html",
|
|
15
|
+
content: `<!DOCTYPE html>
|
|
16
|
+
<html lang="en">
|
|
17
|
+
<head>
|
|
18
|
+
<meta charset="UTF-8" />
|
|
19
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
20
|
+
<title>${name}</title>
|
|
21
|
+
</head>
|
|
22
|
+
<body>
|
|
23
|
+
<div id="app"></div>
|
|
24
|
+
<script type="module" src="/src/main.ts"></script>
|
|
25
|
+
</body>
|
|
26
|
+
</html>
|
|
27
|
+
`,
|
|
28
|
+
description: "Generating HTML template",
|
|
29
|
+
emoji: "š»",
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
filename: "src/main.ts",
|
|
33
|
+
content: `import { mount } from 'svelte';
|
|
34
|
+
import App from './App.svelte';
|
|
35
|
+
|
|
36
|
+
const app = mount(App, { target: document.getElementById('app')! });
|
|
37
|
+
|
|
38
|
+
export default app;
|
|
39
|
+
`,
|
|
40
|
+
description: "Generating Svelte entry",
|
|
41
|
+
emoji: "š»",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
filename: "src/App.svelte",
|
|
45
|
+
content: `<script lang="ts">
|
|
46
|
+
const message: string = 'Frontend resource created with TDK';
|
|
47
|
+
</script>
|
|
48
|
+
|
|
49
|
+
<main style="padding: 2rem; font-family: system-ui">
|
|
50
|
+
<h1>${name}</h1>
|
|
51
|
+
<p>{message}</p>
|
|
52
|
+
</main>
|
|
53
|
+
`,
|
|
54
|
+
description: "Generating Svelte app",
|
|
55
|
+
emoji: "š»",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
filename: "src/vite-env.d.ts",
|
|
59
|
+
content: `/// <reference types="svelte" />
|
|
60
|
+
/// <reference types="vite/client" />
|
|
61
|
+
`,
|
|
62
|
+
description: "Generating Svelte module types",
|
|
63
|
+
emoji: "āļø",
|
|
64
|
+
},
|
|
65
|
+
];
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
//# sourceMappingURL=svelte.js.map
|
package/cli/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tdk-cli-internal",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "1.3.
|
|
4
|
+
"version": "1.3.88",
|
|
5
5
|
"description": "TDK CLI ā start services on your laptop.",
|
|
6
6
|
"keywords": [
|
|
7
7
|
"tdk",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"prepack": "../scripts/stage-npm-engine.sh && npm run build"
|
|
54
54
|
},
|
|
55
55
|
"dependencies": {
|
|
56
|
-
"chalk": "^
|
|
56
|
+
"chalk": "^6.0.1",
|
|
57
57
|
"commander": "^15.0.0",
|
|
58
58
|
"handlebars": "^4.7.8",
|
|
59
59
|
"ink": "^7.1.1",
|
|
@@ -107,7 +107,7 @@
|
|
|
107
107
|
"type": "string"
|
|
108
108
|
},
|
|
109
109
|
"appType": {
|
|
110
|
-
"description": "Resource type determining build strategy:\n⢠backend - Hono/Express API server\n⢠frontend - Vite single-page application (React or
|
|
110
|
+
"description": "Resource type determining build strategy:\n⢠backend - Hono/Express API server\n⢠frontend - Vite single-page application (React, Vue, Svelte, Preact, Lit, Solid or Qwik, see framework)\n⢠sdk - Shared library package\n⢠worker - Background job processor\n⢠migrator - Database migration runner\n⢠library - Shared code library\n⢠bring-your-own - Wrap an existing service. No app scaffold. Needs Dockerfile or --image.",
|
|
111
111
|
"enum": [
|
|
112
112
|
"backend",
|
|
113
113
|
"frontend",
|
|
@@ -153,6 +153,16 @@
|
|
|
153
153
|
"description": "Whether this bring-your-own resource receives a Traefik route. Defaults to true.",
|
|
154
154
|
"type": "boolean"
|
|
155
155
|
},
|
|
156
|
+
"restart": {
|
|
157
|
+
"description": "Docker Compose restart policy for this bring-your-own resource. Use \"no\" or \"on-failure\" for one-shot jobs such as database migrations, so a finished job is not restarted. Defaults to unless-stopped.",
|
|
158
|
+
"enum": [
|
|
159
|
+
"no",
|
|
160
|
+
"on-failure",
|
|
161
|
+
"unless-stopped",
|
|
162
|
+
"always"
|
|
163
|
+
],
|
|
164
|
+
"type": "string"
|
|
165
|
+
},
|
|
156
166
|
"image": {
|
|
157
167
|
"description": "Docker image name instead of building from Dockerfile. Optional for bring-your-own type.",
|
|
158
168
|
"type": "string"
|
|
@@ -215,19 +225,28 @@
|
|
|
215
225
|
"uniqueItems": true
|
|
216
226
|
},
|
|
217
227
|
"framework": {
|
|
218
|
-
"description": "
|
|
219
|
-
"
|
|
228
|
+
"description": "Framework provider id. For frontend resources it selects the Vite and TypeScript config (omitted means react, legacy manifests). For backend resources it selects the HTTP framework on the Bun runtime (omitted means hono; not used with a language that owns its runtime, such as python). Valid ids come from the CLI provider registries, which reject unknown ids before writing a resource.",
|
|
229
|
+
"examples": [
|
|
220
230
|
"react",
|
|
221
|
-
"vue"
|
|
231
|
+
"vue",
|
|
232
|
+
"svelte",
|
|
233
|
+
"preact",
|
|
234
|
+
"lit",
|
|
235
|
+
"solid",
|
|
236
|
+
"qwik",
|
|
237
|
+
"hono",
|
|
238
|
+
"express"
|
|
222
239
|
],
|
|
240
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
223
241
|
"type": "string"
|
|
224
242
|
},
|
|
225
243
|
"language": {
|
|
226
|
-
"description": "Backend language provider used to scaffold and run the service. Only meaningful for backend resources; omitted means bun (legacy manifests).",
|
|
227
|
-
"
|
|
244
|
+
"description": "Backend language provider id used to scaffold and run the service. Only meaningful for backend resources; omitted means bun (legacy manifests). Valid ids come from the CLI provider registry.",
|
|
245
|
+
"examples": [
|
|
228
246
|
"bun",
|
|
229
247
|
"python"
|
|
230
248
|
],
|
|
249
|
+
"pattern": "^[a-z][a-z0-9-]*$",
|
|
231
250
|
"type": "string"
|
|
232
251
|
},
|
|
233
252
|
"healthCheckPath": {
|
|
@@ -267,6 +267,13 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
267
267
|
is_byo and not manifest.get('exposeViaProxy', True)
|
|
268
268
|
) if manifest else False
|
|
269
269
|
|
|
270
|
+
# One-shot jobs (migrations, seeders) must not be restarted after they exit 0, so a
|
|
271
|
+
# bring-your-own resource can choose its Compose restart policy. Default is unchanged.
|
|
272
|
+
restart_policy = 'unless-stopped'
|
|
273
|
+
if is_byo and manifest.get('restart') in ['no', 'on-failure', 'unless-stopped', 'always']:
|
|
274
|
+
restart_policy = manifest.get('restart')
|
|
275
|
+
restart_policy = '"no"' if restart_policy == 'no' else restart_policy
|
|
276
|
+
|
|
270
277
|
if is_worker or is_proxy_disabled_byo:
|
|
271
278
|
traefik_labels = ' - "traefik.enable=false"'
|
|
272
279
|
healthcheck_section = "" if is_worker or is_byo else """ healthcheck:
|
|
@@ -299,7 +306,7 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
299
306
|
{resource_entry_name}:
|
|
300
307
|
image: {image_name}
|
|
301
308
|
init: true
|
|
302
|
-
restart:
|
|
309
|
+
restart: {restart_policy}
|
|
303
310
|
{build_config}
|
|
304
311
|
{ports_section}
|
|
305
312
|
env_file:
|
|
@@ -350,6 +357,7 @@ def _generate_single_backend_entry(resource_path, resource_name, res, manifest,
|
|
|
350
357
|
stack=stack,
|
|
351
358
|
internal_port=internal_port,
|
|
352
359
|
port_anchor=internal_port,
|
|
360
|
+
restart_policy=restart_policy,
|
|
353
361
|
dev_port=dev_port,
|
|
354
362
|
db_name=db_name,
|
|
355
363
|
db_url_for_tilt=db_url_for_tilt,
|
|
@@ -77,7 +77,7 @@ def generate_frontend_tsconfig(resource_path, write_fn, internal_deps=None, is_d
|
|
|
77
77
|
resource_path
|
|
78
78
|
))
|
|
79
79
|
print(" Docker build will resolve @{npm_scope}/* from node_modules")
|
|
80
|
-
if framework not in ['react', 'vue']:
|
|
80
|
+
if framework not in ['react', 'vue', 'svelte', 'preact', 'lit', 'solid', 'qwik']:
|
|
81
81
|
fail("Unknown frontend framework for TypeScript generation: " + str(framework))
|
|
82
82
|
|
|
83
83
|
compiler_options = {
|
|
@@ -99,6 +99,15 @@ def generate_frontend_tsconfig(resource_path, write_fn, internal_deps=None, is_d
|
|
|
99
99
|
}
|
|
100
100
|
if framework == 'react':
|
|
101
101
|
compiler_options['jsx'] = 'react-jsx'
|
|
102
|
+
elif framework == 'preact':
|
|
103
|
+
compiler_options['jsx'] = 'react-jsx'
|
|
104
|
+
compiler_options['jsxImportSource'] = 'preact'
|
|
105
|
+
elif framework == 'qwik':
|
|
106
|
+
compiler_options['jsx'] = 'react-jsx'
|
|
107
|
+
compiler_options['jsxImportSource'] = '@builder.io/qwik'
|
|
108
|
+
elif framework == 'solid':
|
|
109
|
+
compiler_options['jsx'] = 'preserve'
|
|
110
|
+
compiler_options['jsxImportSource'] = 'solid-js'
|
|
102
111
|
|
|
103
112
|
content = {
|
|
104
113
|
"compilerOptions": compiler_options,
|
|
@@ -555,7 +555,7 @@ def generate_resource_health_check(resource_name, resource_path, manifest, check
|
|
|
555
555
|
health_checks = []
|
|
556
556
|
|
|
557
557
|
# Check 1: Required files exist
|
|
558
|
-
frontend_entry = "src/main.ts" if manifest.get("framework", "react")
|
|
558
|
+
frontend_entry = "src/main.ts" if manifest.get("framework", "react") in ["vue", "svelte", "lit"] else "src/main.tsx"
|
|
559
559
|
backend_files = {
|
|
560
560
|
"python": ["pyproject.toml", "src/main.py"],
|
|
561
561
|
}.get(manifest.get("language", "bun"), ["package.json", "prisma/schema.prisma"])
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Lit-specific Vite templates for frontend resources.
|
|
2
|
+
|
|
3
|
+
LIT_VITE_FRONTEND = """{header}
|
|
4
|
+
import {{ resolve }} from 'node:path';
|
|
5
|
+
import {{ defineConfig }} from 'vite';
|
|
6
|
+
|
|
7
|
+
export default defineConfig({{
|
|
8
|
+
base: '{base_path}',
|
|
9
|
+
build: {{
|
|
10
|
+
cssCodeSplit: false,
|
|
11
|
+
minify: false,
|
|
12
|
+
modulePreload: false,
|
|
13
|
+
rollupOptions: {{
|
|
14
|
+
output: {{
|
|
15
|
+
entryFileNames: '[name].js',
|
|
16
|
+
format: 'esm',
|
|
17
|
+
}},
|
|
18
|
+
}},
|
|
19
|
+
target: 'esnext',
|
|
20
|
+
}},
|
|
21
|
+
define: {{
|
|
22
|
+
global: 'globalThis',
|
|
23
|
+
}},
|
|
24
|
+
optimizeDeps: {{
|
|
25
|
+
include: [{optimize_deps_include}],
|
|
26
|
+
}},
|
|
27
|
+
plugins: [],
|
|
28
|
+
preview: {{
|
|
29
|
+
host: '0.0.0.0',
|
|
30
|
+
port: {port},
|
|
31
|
+
}},
|
|
32
|
+
resolve: {{
|
|
33
|
+
alias: {{
|
|
34
|
+
'@/autogenerated': resolve(__dirname),
|
|
35
|
+
'@': resolve(__dirname, '../src'),
|
|
36
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
37
|
+
{internal_aliases}
|
|
38
|
+
}},
|
|
39
|
+
}},
|
|
40
|
+
server: {{
|
|
41
|
+
host: '0.0.0.0',
|
|
42
|
+
port: {port},
|
|
43
|
+
hmr: {{
|
|
44
|
+
port: {hmr_port},
|
|
45
|
+
}},
|
|
46
|
+
{proxy_config}
|
|
47
|
+
}},
|
|
48
|
+
}});
|
|
49
|
+
"""
|
|
50
|
+
|
|
51
|
+
LIT_VITE_FRONTEND_BUILD = """{header}
|
|
52
|
+
import {{ resolve }} from 'node:path';
|
|
53
|
+
import {{ defineConfig }} from 'vite';
|
|
54
|
+
|
|
55
|
+
export default defineConfig({{
|
|
56
|
+
mode: 'production',
|
|
57
|
+
base: '{base_path}',
|
|
58
|
+
build: {{
|
|
59
|
+
cssCodeSplit: false,
|
|
60
|
+
minify: true,
|
|
61
|
+
modulePreload: false,
|
|
62
|
+
rollupOptions: {{
|
|
63
|
+
output: {{
|
|
64
|
+
entryFileNames: '[name].js',
|
|
65
|
+
format: 'esm',
|
|
66
|
+
manualChunks: undefined,
|
|
67
|
+
}},
|
|
68
|
+
}},
|
|
69
|
+
target: 'esnext',
|
|
70
|
+
}},
|
|
71
|
+
define: {{
|
|
72
|
+
global: 'globalThis',
|
|
73
|
+
__DEV__: 'false',
|
|
74
|
+
'process.env.NODE_ENV': '"production"',
|
|
75
|
+
}},
|
|
76
|
+
optimizeDeps: {{
|
|
77
|
+
include: [{optimize_deps_include}],
|
|
78
|
+
}},
|
|
79
|
+
plugins: [],
|
|
80
|
+
resolve: {{
|
|
81
|
+
alias: {{
|
|
82
|
+
'@/autogenerated': resolve(__dirname),
|
|
83
|
+
'@': resolve(__dirname, '../src'),
|
|
84
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
85
|
+
}},
|
|
86
|
+
conditions: ['browser', 'import', 'module', 'es2020', 'default'],
|
|
87
|
+
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext', 'main'],
|
|
88
|
+
}},
|
|
89
|
+
}});
|
|
90
|
+
"""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Preact-specific Vite templates for frontend resources.
|
|
2
|
+
|
|
3
|
+
PREACT_VITE_FRONTEND = """{header}
|
|
4
|
+
import {{ resolve }} from 'node:path';
|
|
5
|
+
import preact from '@preact/preset-vite';
|
|
6
|
+
import {{ defineConfig }} from 'vite';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({{
|
|
9
|
+
base: '{base_path}',
|
|
10
|
+
build: {{
|
|
11
|
+
cssCodeSplit: false,
|
|
12
|
+
minify: false,
|
|
13
|
+
modulePreload: false,
|
|
14
|
+
rollupOptions: {{
|
|
15
|
+
output: {{
|
|
16
|
+
entryFileNames: '[name].js',
|
|
17
|
+
format: 'esm',
|
|
18
|
+
}},
|
|
19
|
+
}},
|
|
20
|
+
target: 'esnext',
|
|
21
|
+
}},
|
|
22
|
+
define: {{
|
|
23
|
+
global: 'globalThis',
|
|
24
|
+
}},
|
|
25
|
+
optimizeDeps: {{
|
|
26
|
+
include: [{optimize_deps_include}],
|
|
27
|
+
}},
|
|
28
|
+
plugins: [preact()],
|
|
29
|
+
preview: {{
|
|
30
|
+
host: '0.0.0.0',
|
|
31
|
+
port: {port},
|
|
32
|
+
}},
|
|
33
|
+
resolve: {{
|
|
34
|
+
alias: {{
|
|
35
|
+
'@/autogenerated': resolve(__dirname),
|
|
36
|
+
'@': resolve(__dirname, '../src'),
|
|
37
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
38
|
+
{internal_aliases}
|
|
39
|
+
}},
|
|
40
|
+
}},
|
|
41
|
+
server: {{
|
|
42
|
+
host: '0.0.0.0',
|
|
43
|
+
port: {port},
|
|
44
|
+
hmr: {{
|
|
45
|
+
port: {hmr_port},
|
|
46
|
+
}},
|
|
47
|
+
{proxy_config}
|
|
48
|
+
}},
|
|
49
|
+
}});
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
PREACT_VITE_FRONTEND_BUILD = """{header}
|
|
53
|
+
import {{ resolve }} from 'node:path';
|
|
54
|
+
import preact from '@preact/preset-vite';
|
|
55
|
+
import {{ defineConfig }} from 'vite';
|
|
56
|
+
|
|
57
|
+
export default defineConfig({{
|
|
58
|
+
mode: 'production',
|
|
59
|
+
base: '{base_path}',
|
|
60
|
+
build: {{
|
|
61
|
+
cssCodeSplit: false,
|
|
62
|
+
minify: true,
|
|
63
|
+
modulePreload: false,
|
|
64
|
+
rollupOptions: {{
|
|
65
|
+
output: {{
|
|
66
|
+
entryFileNames: '[name].js',
|
|
67
|
+
format: 'esm',
|
|
68
|
+
manualChunks: undefined,
|
|
69
|
+
}},
|
|
70
|
+
}},
|
|
71
|
+
target: 'esnext',
|
|
72
|
+
}},
|
|
73
|
+
define: {{
|
|
74
|
+
global: 'globalThis',
|
|
75
|
+
__DEV__: 'false',
|
|
76
|
+
'process.env.NODE_ENV': '"production"',
|
|
77
|
+
}},
|
|
78
|
+
optimizeDeps: {{
|
|
79
|
+
include: [{optimize_deps_include}],
|
|
80
|
+
}},
|
|
81
|
+
plugins: [preact()],
|
|
82
|
+
resolve: {{
|
|
83
|
+
alias: {{
|
|
84
|
+
'@/autogenerated': resolve(__dirname),
|
|
85
|
+
'@': resolve(__dirname, '../src'),
|
|
86
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
87
|
+
}},
|
|
88
|
+
conditions: ['browser', 'import', 'module', 'es2020', 'default'],
|
|
89
|
+
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext', 'main'],
|
|
90
|
+
}},
|
|
91
|
+
}});
|
|
92
|
+
"""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Qwik-specific Vite templates for frontend resources.
|
|
2
|
+
|
|
3
|
+
QWIK_VITE_FRONTEND = """{header}
|
|
4
|
+
import {{ resolve }} from 'node:path';
|
|
5
|
+
import {{ qwikVite }} from '@builder.io/qwik/optimizer';
|
|
6
|
+
import {{ defineConfig }} from 'vite';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({{
|
|
9
|
+
base: '{base_path}',
|
|
10
|
+
build: {{
|
|
11
|
+
cssCodeSplit: false,
|
|
12
|
+
minify: false,
|
|
13
|
+
modulePreload: false,
|
|
14
|
+
rollupOptions: {{
|
|
15
|
+
output: {{
|
|
16
|
+
entryFileNames: '[name].js',
|
|
17
|
+
format: 'esm',
|
|
18
|
+
}},
|
|
19
|
+
}},
|
|
20
|
+
target: 'esnext',
|
|
21
|
+
}},
|
|
22
|
+
define: {{
|
|
23
|
+
global: 'globalThis',
|
|
24
|
+
}},
|
|
25
|
+
optimizeDeps: {{
|
|
26
|
+
include: [{optimize_deps_include}],
|
|
27
|
+
}},
|
|
28
|
+
plugins: [qwikVite({{ csr: true }})],
|
|
29
|
+
preview: {{
|
|
30
|
+
host: '0.0.0.0',
|
|
31
|
+
port: {port},
|
|
32
|
+
}},
|
|
33
|
+
resolve: {{
|
|
34
|
+
alias: {{
|
|
35
|
+
'@/autogenerated': resolve(__dirname),
|
|
36
|
+
'@': resolve(__dirname, '../src'),
|
|
37
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
38
|
+
{internal_aliases}
|
|
39
|
+
}},
|
|
40
|
+
}},
|
|
41
|
+
server: {{
|
|
42
|
+
host: '0.0.0.0',
|
|
43
|
+
port: {port},
|
|
44
|
+
hmr: {{
|
|
45
|
+
port: {hmr_port},
|
|
46
|
+
}},
|
|
47
|
+
{proxy_config}
|
|
48
|
+
}},
|
|
49
|
+
}});
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
QWIK_VITE_FRONTEND_BUILD = """{header}
|
|
53
|
+
import {{ resolve }} from 'node:path';
|
|
54
|
+
import {{ qwikVite }} from '@builder.io/qwik/optimizer';
|
|
55
|
+
import {{ defineConfig }} from 'vite';
|
|
56
|
+
|
|
57
|
+
export default defineConfig({{
|
|
58
|
+
mode: 'production',
|
|
59
|
+
base: '{base_path}',
|
|
60
|
+
build: {{
|
|
61
|
+
cssCodeSplit: false,
|
|
62
|
+
minify: true,
|
|
63
|
+
modulePreload: false,
|
|
64
|
+
rollupOptions: {{
|
|
65
|
+
output: {{
|
|
66
|
+
entryFileNames: '[name].js',
|
|
67
|
+
format: 'esm',
|
|
68
|
+
manualChunks: undefined,
|
|
69
|
+
}},
|
|
70
|
+
}},
|
|
71
|
+
target: 'esnext',
|
|
72
|
+
}},
|
|
73
|
+
define: {{
|
|
74
|
+
global: 'globalThis',
|
|
75
|
+
__DEV__: 'false',
|
|
76
|
+
'process.env.NODE_ENV': '"production"',
|
|
77
|
+
}},
|
|
78
|
+
optimizeDeps: {{
|
|
79
|
+
include: [{optimize_deps_include}],
|
|
80
|
+
}},
|
|
81
|
+
plugins: [qwikVite({{ csr: true }})],
|
|
82
|
+
resolve: {{
|
|
83
|
+
alias: {{
|
|
84
|
+
'@/autogenerated': resolve(__dirname),
|
|
85
|
+
'@': resolve(__dirname, '../src'),
|
|
86
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
87
|
+
}},
|
|
88
|
+
conditions: ['browser', 'import', 'module', 'es2020', 'default'],
|
|
89
|
+
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext', 'main'],
|
|
90
|
+
}},
|
|
91
|
+
}});
|
|
92
|
+
"""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Solid-specific Vite templates for frontend resources.
|
|
2
|
+
|
|
3
|
+
SOLID_VITE_FRONTEND = """{header}
|
|
4
|
+
import {{ resolve }} from 'node:path';
|
|
5
|
+
import solid from 'vite-plugin-solid';
|
|
6
|
+
import {{ defineConfig }} from 'vite';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({{
|
|
9
|
+
base: '{base_path}',
|
|
10
|
+
build: {{
|
|
11
|
+
cssCodeSplit: false,
|
|
12
|
+
minify: false,
|
|
13
|
+
modulePreload: false,
|
|
14
|
+
rollupOptions: {{
|
|
15
|
+
output: {{
|
|
16
|
+
entryFileNames: '[name].js',
|
|
17
|
+
format: 'esm',
|
|
18
|
+
}},
|
|
19
|
+
}},
|
|
20
|
+
target: 'esnext',
|
|
21
|
+
}},
|
|
22
|
+
define: {{
|
|
23
|
+
global: 'globalThis',
|
|
24
|
+
}},
|
|
25
|
+
optimizeDeps: {{
|
|
26
|
+
include: [{optimize_deps_include}],
|
|
27
|
+
}},
|
|
28
|
+
plugins: [solid()],
|
|
29
|
+
preview: {{
|
|
30
|
+
host: '0.0.0.0',
|
|
31
|
+
port: {port},
|
|
32
|
+
}},
|
|
33
|
+
resolve: {{
|
|
34
|
+
alias: {{
|
|
35
|
+
'@/autogenerated': resolve(__dirname),
|
|
36
|
+
'@': resolve(__dirname, '../src'),
|
|
37
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
38
|
+
{internal_aliases}
|
|
39
|
+
}},
|
|
40
|
+
}},
|
|
41
|
+
server: {{
|
|
42
|
+
host: '0.0.0.0',
|
|
43
|
+
port: {port},
|
|
44
|
+
hmr: {{
|
|
45
|
+
port: {hmr_port},
|
|
46
|
+
}},
|
|
47
|
+
{proxy_config}
|
|
48
|
+
}},
|
|
49
|
+
}});
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
SOLID_VITE_FRONTEND_BUILD = """{header}
|
|
53
|
+
import {{ resolve }} from 'node:path';
|
|
54
|
+
import solid from 'vite-plugin-solid';
|
|
55
|
+
import {{ defineConfig }} from 'vite';
|
|
56
|
+
|
|
57
|
+
export default defineConfig({{
|
|
58
|
+
mode: 'production',
|
|
59
|
+
base: '{base_path}',
|
|
60
|
+
build: {{
|
|
61
|
+
cssCodeSplit: false,
|
|
62
|
+
minify: true,
|
|
63
|
+
modulePreload: false,
|
|
64
|
+
rollupOptions: {{
|
|
65
|
+
output: {{
|
|
66
|
+
entryFileNames: '[name].js',
|
|
67
|
+
format: 'esm',
|
|
68
|
+
manualChunks: undefined,
|
|
69
|
+
}},
|
|
70
|
+
}},
|
|
71
|
+
target: 'esnext',
|
|
72
|
+
}},
|
|
73
|
+
define: {{
|
|
74
|
+
global: 'globalThis',
|
|
75
|
+
__DEV__: 'false',
|
|
76
|
+
'process.env.NODE_ENV': '"production"',
|
|
77
|
+
}},
|
|
78
|
+
optimizeDeps: {{
|
|
79
|
+
include: [{optimize_deps_include}],
|
|
80
|
+
}},
|
|
81
|
+
plugins: [solid()],
|
|
82
|
+
resolve: {{
|
|
83
|
+
alias: {{
|
|
84
|
+
'@/autogenerated': resolve(__dirname),
|
|
85
|
+
'@': resolve(__dirname, '../src'),
|
|
86
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
87
|
+
}},
|
|
88
|
+
conditions: ['browser', 'import', 'module', 'es2020', 'default'],
|
|
89
|
+
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext', 'main'],
|
|
90
|
+
}},
|
|
91
|
+
}});
|
|
92
|
+
"""
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Svelte-specific Vite templates for frontend resources.
|
|
2
|
+
|
|
3
|
+
SVELTE_VITE_FRONTEND = """{header}
|
|
4
|
+
import {{ resolve }} from 'node:path';
|
|
5
|
+
import {{ svelte }} from '@sveltejs/vite-plugin-svelte';
|
|
6
|
+
import {{ defineConfig }} from 'vite';
|
|
7
|
+
|
|
8
|
+
export default defineConfig({{
|
|
9
|
+
base: '{base_path}',
|
|
10
|
+
build: {{
|
|
11
|
+
cssCodeSplit: false,
|
|
12
|
+
minify: false,
|
|
13
|
+
modulePreload: false,
|
|
14
|
+
rollupOptions: {{
|
|
15
|
+
output: {{
|
|
16
|
+
entryFileNames: '[name].js',
|
|
17
|
+
format: 'esm',
|
|
18
|
+
}},
|
|
19
|
+
}},
|
|
20
|
+
target: 'esnext',
|
|
21
|
+
}},
|
|
22
|
+
define: {{
|
|
23
|
+
global: 'globalThis',
|
|
24
|
+
}},
|
|
25
|
+
optimizeDeps: {{
|
|
26
|
+
include: [{optimize_deps_include}],
|
|
27
|
+
}},
|
|
28
|
+
plugins: [svelte()],
|
|
29
|
+
preview: {{
|
|
30
|
+
host: '0.0.0.0',
|
|
31
|
+
port: {port},
|
|
32
|
+
}},
|
|
33
|
+
resolve: {{
|
|
34
|
+
alias: {{
|
|
35
|
+
'@/autogenerated': resolve(__dirname),
|
|
36
|
+
'@': resolve(__dirname, '../src'),
|
|
37
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
38
|
+
{internal_aliases}
|
|
39
|
+
}},
|
|
40
|
+
}},
|
|
41
|
+
server: {{
|
|
42
|
+
host: '0.0.0.0',
|
|
43
|
+
port: {port},
|
|
44
|
+
hmr: {{
|
|
45
|
+
port: {hmr_port},
|
|
46
|
+
}},
|
|
47
|
+
{proxy_config}
|
|
48
|
+
}},
|
|
49
|
+
}});
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
SVELTE_VITE_FRONTEND_BUILD = """{header}
|
|
53
|
+
import {{ resolve }} from 'node:path';
|
|
54
|
+
import {{ svelte }} from '@sveltejs/vite-plugin-svelte';
|
|
55
|
+
import {{ defineConfig }} from 'vite';
|
|
56
|
+
|
|
57
|
+
export default defineConfig({{
|
|
58
|
+
mode: 'production',
|
|
59
|
+
base: '{base_path}',
|
|
60
|
+
build: {{
|
|
61
|
+
cssCodeSplit: false,
|
|
62
|
+
minify: true,
|
|
63
|
+
modulePreload: false,
|
|
64
|
+
rollupOptions: {{
|
|
65
|
+
output: {{
|
|
66
|
+
entryFileNames: '[name].js',
|
|
67
|
+
format: 'esm',
|
|
68
|
+
manualChunks: undefined,
|
|
69
|
+
}},
|
|
70
|
+
}},
|
|
71
|
+
target: 'esnext',
|
|
72
|
+
}},
|
|
73
|
+
define: {{
|
|
74
|
+
global: 'globalThis',
|
|
75
|
+
__DEV__: 'false',
|
|
76
|
+
'process.env.NODE_ENV': '"production"',
|
|
77
|
+
}},
|
|
78
|
+
optimizeDeps: {{
|
|
79
|
+
include: [{optimize_deps_include}],
|
|
80
|
+
}},
|
|
81
|
+
plugins: [svelte()],
|
|
82
|
+
resolve: {{
|
|
83
|
+
alias: {{
|
|
84
|
+
'@/autogenerated': resolve(__dirname),
|
|
85
|
+
'@': resolve(__dirname, '../src'),
|
|
86
|
+
'set-cookie-parser': resolve(__dirname, '../src/utils/empty-module.js'),
|
|
87
|
+
}},
|
|
88
|
+
conditions: ['browser', 'import', 'module', 'es2020', 'default'],
|
|
89
|
+
mainFields: ['browser', 'module', 'jsnext:main', 'jsnext', 'main'],
|
|
90
|
+
}},
|
|
91
|
+
}});
|
|
92
|
+
"""
|
|
@@ -17,6 +17,11 @@ load('../../../../topologies/tilt/manifest/constants.star', 'GENERATED_CONFIG_FI
|
|
|
17
17
|
|
|
18
18
|
load('./frameworks/react.star', 'REACT_VITE_FRONTEND', 'REACT_VITE_FRONTEND_BUILD')
|
|
19
19
|
load('./frameworks/vue.star', 'VUE_VITE_FRONTEND', 'VUE_VITE_FRONTEND_BUILD')
|
|
20
|
+
load('./frameworks/svelte.star', 'SVELTE_VITE_FRONTEND', 'SVELTE_VITE_FRONTEND_BUILD')
|
|
21
|
+
load('./frameworks/preact.star', 'PREACT_VITE_FRONTEND', 'PREACT_VITE_FRONTEND_BUILD')
|
|
22
|
+
load('./frameworks/lit.star', 'LIT_VITE_FRONTEND', 'LIT_VITE_FRONTEND_BUILD')
|
|
23
|
+
load('./frameworks/solid.star', 'SOLID_VITE_FRONTEND', 'SOLID_VITE_FRONTEND_BUILD')
|
|
24
|
+
load('./frameworks/qwik.star', 'QWIK_VITE_FRONTEND', 'QWIK_VITE_FRONTEND_BUILD')
|
|
20
25
|
load('../../../platform/docker/networking/api_path_constants.star', 'get_frontend_base_path')
|
|
21
26
|
load('./helpers.star',
|
|
22
27
|
'build_header',
|
|
@@ -38,6 +43,26 @@ _FRAMEWORK_TEMPLATES = {
|
|
|
38
43
|
'dev': VUE_VITE_FRONTEND,
|
|
39
44
|
'build': VUE_VITE_FRONTEND_BUILD,
|
|
40
45
|
},
|
|
46
|
+
'svelte': {
|
|
47
|
+
'dev': SVELTE_VITE_FRONTEND,
|
|
48
|
+
'build': SVELTE_VITE_FRONTEND_BUILD,
|
|
49
|
+
},
|
|
50
|
+
'preact': {
|
|
51
|
+
'dev': PREACT_VITE_FRONTEND,
|
|
52
|
+
'build': PREACT_VITE_FRONTEND_BUILD,
|
|
53
|
+
},
|
|
54
|
+
'lit': {
|
|
55
|
+
'dev': LIT_VITE_FRONTEND,
|
|
56
|
+
'build': LIT_VITE_FRONTEND_BUILD,
|
|
57
|
+
},
|
|
58
|
+
'solid': {
|
|
59
|
+
'dev': SOLID_VITE_FRONTEND,
|
|
60
|
+
'build': SOLID_VITE_FRONTEND_BUILD,
|
|
61
|
+
},
|
|
62
|
+
'qwik': {
|
|
63
|
+
'dev': QWIK_VITE_FRONTEND,
|
|
64
|
+
'build': QWIK_VITE_FRONTEND_BUILD,
|
|
65
|
+
},
|
|
41
66
|
}
|
|
42
67
|
|
|
43
68
|
def _normalize_vite_base_path(base_path):
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tdk-landscape/tdk-cli-core",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.88",
|
|
4
4
|
"description": "TDK CLI ā start services on your laptop.",
|
|
5
5
|
"homepage": "https://tdk-landscape.github.io/tdk-website",
|
|
6
6
|
"repository": {
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
],
|
|
68
68
|
"license": "MIT",
|
|
69
69
|
"dependencies": {
|
|
70
|
-
"chalk": "^
|
|
70
|
+
"chalk": "^6.0.1",
|
|
71
71
|
"commander": "^15.0.0",
|
|
72
72
|
"handlebars": "^4.7.8",
|
|
73
73
|
"ink": "^7.1.1",
|