@tdk-landscape/tdk-cli-core 1.3.37 â 1.3.39
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/commands/config.js +1 -1
- package/dist/commands/config.js.map +1 -1
- package/dist/commands/doctor.d.ts.map +1 -1
- package/dist/commands/doctor.js +98 -6
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/resource.js +1 -1
- package/dist/commands/resource.js.map +1 -1
- package/dist/generator/extension-fetch.d.ts +7 -0
- package/dist/generator/extension-fetch.d.ts.map +1 -1
- package/dist/generator/extension-fetch.js +40 -21
- package/dist/generator/extension-fetch.js.map +1 -1
- package/dist/generator/template-engine.d.ts.map +1 -1
- package/dist/generator/template-engine.js +42 -12
- package/dist/generator/template-engine.js.map +1 -1
- package/dist/types/index.d.ts +6 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/utils/docker.d.ts +3 -2
- package/dist/utils/docker.d.ts.map +1 -1
- package/dist/utils/docker.js +12 -6
- package/dist/utils/docker.js.map +1 -1
- package/dist/utils/errors.d.ts +1 -0
- package/dist/utils/errors.d.ts.map +1 -1
- package/dist/utils/errors.js +10 -2
- package/dist/utils/errors.js.map +1 -1
- package/dist/utils/port-assignment.d.ts.map +1 -1
- package/dist/utils/port-assignment.js +6 -0
- package/dist/utils/port-assignment.js.map +1 -1
- package/dist/utils/resource-features.d.ts.map +1 -1
- package/dist/utils/resource-features.js +12 -0
- package/dist/utils/resource-features.js.map +1 -1
- package/dist/utils/tilt.d.ts +1 -0
- package/dist/utils/tilt.d.ts.map +1 -1
- package/dist/utils/tilt.js +2 -1
- package/dist/utils/tilt.js.map +1 -1
- package/engine/schemas/service-schema.json +20 -0
- package/engine/topologies/platform/docker/compose/compose.star +4 -0
- package/engine/topologies/platform/docker/compose/traefik_standalone.star +20 -0
- package/engine/topologies/platform/docker/layers/l4_runtime_layers.star +4 -1
- package/engine/topologies/platform/docker/layers/prisma/prisma_runtime.star +45 -0
- package/engine/topologies/platform/docker/networking/sablier_container_cycle.star +25 -23
- package/engine/topologies/platform/docker/networking/traefik.star +10 -20
- package/engine/topologies/platform/registries/verdaccio_loader.star +18 -0
- package/engine/topologies/tilt/manifest/constants.star +1 -0
- package/engine/topologies/tilt/manifest/schema.star +29 -1
- package/engine/topologies/tilt/manifest/validator.star +1 -1
- package/engine/topologies/tilt/resources/infra-loader.star +5 -31
- package/package.json +3 -3
|
@@ -1,27 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# On-demand scaling: Sablier + Traefik (free-tier stub)
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Path: engine/topologies/platform/docker/networking/sablier_container_cycle.star
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# The real generator (Sablier + Traefik label wiring that stops idle
|
|
7
|
+
# containers and wakes them on the next request) is part of a paid TDK
|
|
8
|
+
# license. When a valid license grants the "sablier" resource,
|
|
9
|
+
# cli/src/generator/template-engine.ts (vendorTdkExtension) overwrites this
|
|
10
|
+
# file with the licensed version fetched via extension-fetch.ts before Tilt
|
|
11
|
+
# loads it. Same function signatures either way, so nothing else in the
|
|
12
|
+
# generator pipeline changes -- every call site just gets "disabled" back
|
|
13
|
+
# for a manifest's `sablier` block until then.
|
|
14
|
+
# =============================================================================
|
|
3
15
|
|
|
4
|
-
When a workload opts in via a `sablier` block, it is fronted by the file-provider
|
|
5
|
-
middleware `sablier-<group>@file` (defined in the platform proxy dynamic config).
|
|
6
|
-
The leading comma lets callers append the suffix to an existing middlewares list.
|
|
7
|
-
"""
|
|
8
|
-
sablier_cfg = manifest.get('sablier', {}) if manifest else {}
|
|
9
|
-
if not sablier_cfg.get('enable', False):
|
|
10
|
-
return "", "", False
|
|
11
|
-
group = sablier_cfg.get('group', manifest.get('stack', '') if manifest else '')
|
|
12
|
-
if not group:
|
|
13
|
-
return ",sablier-base@file", "", True
|
|
14
|
-
return ",sablier-" + group + "@file", group, True
|
|
15
16
|
|
|
17
|
+
def _sablier_config(_manifest):
|
|
18
|
+
"""Free-tier stub - see module header. Always disabled."""
|
|
19
|
+
return False, "", ""
|
|
16
20
|
|
|
17
|
-
def _sablier_container_labels(group, indent):
|
|
18
|
-
"""Container labels that let Sablier discover, wake, and stop this workload.
|
|
19
21
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
""
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return "
|
|
22
|
+
def _sablier_middleware_suffix(_manifest, _res_name):
|
|
23
|
+
"""Free-tier stub - see module header. Always disabled."""
|
|
24
|
+
return "", False
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def _sablier_container_labels(_manifest, _res_name, _indent):
|
|
28
|
+
"""Free-tier stub - see module header. No labels to add."""
|
|
29
|
+
return ""
|
|
@@ -31,21 +31,10 @@ load("./traefik_helpers.star",
|
|
|
31
31
|
"get_api_path",
|
|
32
32
|
"project_backend_rule",
|
|
33
33
|
)
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
def _sablier_middleware_suffix(_):
|
|
40
|
-
# Stub: no Sablier middleware needed
|
|
41
|
-
return "", "", False
|
|
42
|
-
|
|
43
|
-
def _sablier_container_labels(_, __):
|
|
44
|
-
# Stub: no extra labels needed
|
|
45
|
-
return ""
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
# Sablier functions imported from sablier_container_cycle.star
|
|
34
|
+
load("./sablier_container_cycle.star",
|
|
35
|
+
"_sablier_middleware_suffix",
|
|
36
|
+
"_sablier_container_labels",
|
|
37
|
+
)
|
|
49
38
|
|
|
50
39
|
|
|
51
40
|
def get_frontend_traefik_labels(res_name, domain, base_path, port, traefik_host=None, manifest=None):
|
|
@@ -66,7 +55,7 @@ def get_frontend_traefik_labels(res_name, domain, base_path, port, traefik_host=
|
|
|
66
55
|
maintenance_middleware = ",maintenance@file"
|
|
67
56
|
|
|
68
57
|
# On-demand scaling: attach the Sablier middleware when opted in via the manifest
|
|
69
|
-
sablier_middleware,
|
|
58
|
+
sablier_middleware, sablier_enabled = _sablier_middleware_suffix(manifest, res_name)
|
|
70
59
|
|
|
71
60
|
labels = """ - "{traefik_enable_label}"
|
|
72
61
|
- 'traefik.http.routers.{res_name}.rule={frontend_route_rule}'
|
|
@@ -90,7 +79,7 @@ def get_frontend_traefik_labels(res_name, domain, base_path, port, traefik_host=
|
|
|
90
79
|
)
|
|
91
80
|
|
|
92
81
|
if sablier_enabled:
|
|
93
|
-
labels += _sablier_container_labels(
|
|
82
|
+
labels += _sablier_container_labels(manifest, res_name, " ")
|
|
94
83
|
|
|
95
84
|
return labels
|
|
96
85
|
|
|
@@ -118,7 +107,7 @@ def get_backend_traefik_labels(
|
|
|
118
107
|
maintenance_middleware = ",maintenance@file"
|
|
119
108
|
|
|
120
109
|
# On-demand scaling: attach the Sablier middleware when opted in via the manifest
|
|
121
|
-
sablier_middleware,
|
|
110
|
+
sablier_middleware, sablier_enabled = _sablier_middleware_suffix(manifest, resource_entry_name)
|
|
122
111
|
|
|
123
112
|
# Build middleware config only if traefik_path is not empty
|
|
124
113
|
if traefik_path:
|
|
@@ -161,7 +150,7 @@ def get_backend_traefik_labels(
|
|
|
161
150
|
|
|
162
151
|
# Emit Sablier discovery labels so the Sablier container can wake/stop this workload
|
|
163
152
|
if sablier_enabled:
|
|
164
|
-
labels += _sablier_container_labels(
|
|
153
|
+
labels += _sablier_container_labels(manifest, resource_entry_name, " ")
|
|
165
154
|
|
|
166
155
|
# Generate project localhost routing to match `tdk up` URLs:
|
|
167
156
|
# http://api.{project}.localhost/api/{resource-name}
|
|
@@ -204,7 +193,7 @@ def get_backend_traefik_labels(
|
|
|
204
193
|
- "traefik.http.routers.{resource_entry_name}-management.rule=Host(`{api_host}`) && PathPrefix(`{management_path}`)"
|
|
205
194
|
- "traefik.http.routers.{resource_entry_name}-management.entrypoints={project_entrypoints}"
|
|
206
195
|
- "traefik.http.routers.{resource_entry_name}-management.service={traefik_resource_name}"
|
|
207
|
-
- "traefik.http.routers.{resource_entry_name}-management.middlewares={middleware_name}-management"
|
|
196
|
+
- "traefik.http.routers.{resource_entry_name}-management.middlewares={middleware_name}-management{sablier_middleware}"
|
|
208
197
|
- "traefik.http.middlewares.{middleware_name}-management.stripprefix.prefixes={management_path}"
|
|
209
198
|
- "traefik.http.routers.{resource_entry_name}-management.priority={mgmt_priority}"
|
|
210
199
|
""".format(
|
|
@@ -214,6 +203,7 @@ def get_backend_traefik_labels(
|
|
|
214
203
|
management_path=management_path,
|
|
215
204
|
project_entrypoints=project_entrypoints,
|
|
216
205
|
middleware_name=middleware_name,
|
|
206
|
+
sablier_middleware=sablier_middleware,
|
|
217
207
|
mgmt_priority=TRAEFIK_FRONTEND_PRIORITY_BASE + len(management_path),
|
|
218
208
|
)
|
|
219
209
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# =============================================================================
|
|
2
|
+
# đĻ VERDACCIO (NPM Registry) - loader (free-tier stub)
|
|
3
|
+
# =============================================================================
|
|
4
|
+
# Path: engine/topologies/platform/registries/verdaccio_loader.star
|
|
5
|
+
# =============================================================================
|
|
6
|
+
# The real loader (stands up the Verdaccio private npm registry container and
|
|
7
|
+
# wires it into the project's Docker network) is part of a paid TDK license.
|
|
8
|
+
# When a valid license grants the "verdaccio" resource,
|
|
9
|
+
# cli/src/generator/template-engine.ts (vendorTdkExtension) overwrites this
|
|
10
|
+
# file with the licensed version fetched via extension-fetch.ts before Tilt
|
|
11
|
+
# loads it. Same function signature either way, so nothing else in the
|
|
12
|
+
# loader pipeline changes.
|
|
13
|
+
# =============================================================================
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def load_verdaccio(_should_enable, _root_prefix="", _env_file=None):
|
|
17
|
+
"""Free-tier stub - see module header. Always skipped."""
|
|
18
|
+
print("âšī¸ Verdaccio skipped â requires a TDK Premium license (run `tdk upgrade`)")
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
# === INLINED CONSTANTS for pure extension loading ===
|
|
10
10
|
VALID_STACKS = () # Stacks are project-specific, discovered dynamically
|
|
11
|
-
VALID_FEATURES = "api-client", "env-config", "api-index", "prisma", "nats", "redis", "infisical", "vitest", "traefik", "websocket", "graphql", "grpc", "vite-node", "maintenance"
|
|
11
|
+
VALID_FEATURES = "api-client", "env-config", "api-index", "prisma", "ddd", "nats", "redis", "infisical", "vitest", "traefik", "websocket", "graphql", "grpc", "vite-node", "maintenance", "sablier"
|
|
12
12
|
PORT_RANGES = {"frontend": {"min": 3000, "max": 5999}, "backend": {"min": 4000, "max": 5999}, "worker": {"min": 6000, "max": 6999}, "migrator": {"min": 7000, "max": 7999}, "sdk": {"min": 3000, "max": 9999}, "library": {"min": 3000, "max": 9999}}
|
|
13
13
|
RUNTIME = "bun"
|
|
14
14
|
TRAEFIK_CONFIG = {"entrypoint": "web", "network": "traefik-public", "default_host": "localhost", "default_port": 8080, "tls_enabled": False, "entrypoints": ["web"], "middlewares": [], "tls": {"enabled": False}, "healthcheck_path": "/health", "healthcheck_interval": "10s", "healthcheck_timeout": "5s", "frontend_priority_base": 100}
|
|
@@ -252,6 +252,34 @@ MANIFEST_SCHEMA = {
|
|
|
252
252
|
},
|
|
253
253
|
'description': 'Traefik reverse proxy configuration',
|
|
254
254
|
},
|
|
255
|
+
|
|
256
|
+
# Sablier Configuration (on-demand start/stop for idle resources)
|
|
257
|
+
'sablier': {
|
|
258
|
+
'type': 'dict',
|
|
259
|
+
'required': False,
|
|
260
|
+
'schema': {
|
|
261
|
+
'enable': {
|
|
262
|
+
'type': 'boolean',
|
|
263
|
+
'required': False,
|
|
264
|
+
'default': False,
|
|
265
|
+
'description': 'Scale this resource to zero when idle; Sablier wakes it on the next request',
|
|
266
|
+
},
|
|
267
|
+
'group': {
|
|
268
|
+
'type': 'string',
|
|
269
|
+
'required': False,
|
|
270
|
+
'description': 'Resources sharing a group wake and sleep together (defaults to `stack`)',
|
|
271
|
+
'example': 'restaurant',
|
|
272
|
+
},
|
|
273
|
+
'sessionDuration': {
|
|
274
|
+
'type': 'string',
|
|
275
|
+
'required': False,
|
|
276
|
+
'default': '10m',
|
|
277
|
+
'description': 'How long the resource stays up after its last request, as a Go duration (e.g. "10m", "1h")',
|
|
278
|
+
'example': '10m',
|
|
279
|
+
},
|
|
280
|
+
},
|
|
281
|
+
'description': 'On-demand scaling via Sablier: stop idle containers, wake them on the next request. Not recommended for stateful resources (databases) with in-flight writes. (Premium - requires TDK_LICENSE_KEY; see hasSablierLicense() in extension-fetch.ts)',
|
|
282
|
+
},
|
|
255
283
|
}
|
|
256
284
|
|
|
257
285
|
# Cross-field validation constraints
|
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
# === INLINED CONSTANTS for pure extension loading ===
|
|
10
10
|
VALID_STACKS = () # Stacks are project-specific, discovered dynamically
|
|
11
|
-
VALID_FEATURES = "api-client", "env-config", "api-index", "prisma", "nats", "redis", "infisical", "vitest", "traefik", "websocket", "graphql", "grpc", "vite-node", "maintenance", "sablier"
|
|
11
|
+
VALID_FEATURES = "api-client", "env-config", "api-index", "prisma", "ddd", "nats", "redis", "infisical", "vitest", "traefik", "websocket", "graphql", "grpc", "vite-node", "maintenance", "sablier"
|
|
12
12
|
PORT_RANGES = {"frontend": {"min": 3000, "max": 5999}, "backend": {"min": 4000, "max": 5999}, "worker": {"min": 6000, "max": 6999}, "migrator": {"min": 7000, "max": 7999}, "sdk": {"min": 3000, "max": 9999}, "library": {"min": 3000, "max": 9999}}
|
|
13
13
|
DEFAULTS = {}
|
|
14
14
|
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
|
|
21
21
|
load("../../platform/docker/constants.star", "PlatformDockerConstants")
|
|
22
22
|
load("../../platform/docker/compose/traefik_standalone.star", "generate_standalone_traefik_compose")
|
|
23
|
+
load("../../platform/registries/verdaccio_loader.star", "load_verdaccio")
|
|
23
24
|
|
|
24
25
|
# =============================================================================
|
|
25
26
|
# đī¸ DATABASE MANAGEMENT
|
|
@@ -129,38 +130,11 @@ def _load_database_management(should_enable, root_prefix="", env_file=None, writ
|
|
|
129
130
|
# =============================================================================
|
|
130
131
|
# đĻ VERDACCIO (NPM Registry)
|
|
131
132
|
# =============================================================================
|
|
133
|
+
# Loader lives in ../../platform/registries/verdaccio_loader.star (a free-tier
|
|
134
|
+
# stub in this public repo; the paid CLI overlay swaps it for the real loader
|
|
135
|
+
# â see that module's header comment).
|
|
132
136
|
|
|
133
|
-
|
|
134
|
-
"""Load Verdaccio private npm registry (premium feature â requires TDK_LICENSE_KEY)."""
|
|
135
|
-
# Verdaccio is a premium feature. Skip entirely when no license key is set.
|
|
136
|
-
if not os.environ.get("TDK_LICENSE_KEY", ""):
|
|
137
|
-
print("âšī¸ Verdaccio skipped â TDK_LICENSE_KEY not set (premium feature)")
|
|
138
|
-
return
|
|
139
|
-
if not should_enable(PlatformDockerConstants.VERDACCIO_RESOURCE_NAME):
|
|
140
|
-
print("DEBUG INFRA: Verdaccio not enabled")
|
|
141
|
-
return
|
|
142
|
-
|
|
143
|
-
# Use absolute path for docker-compose to ensure correct working directory
|
|
144
|
-
if root_prefix:
|
|
145
|
-
compose_file = root_prefix + 'docker-compose.verdaccio.yml'
|
|
146
|
-
else:
|
|
147
|
-
# Use project root from environment or relative path
|
|
148
|
-
project_root = os.environ.get('TDK_PROJECT_ROOT', '.')
|
|
149
|
-
compose_file = project_root + '/docker-compose.verdaccio.yml'
|
|
150
|
-
if not _file_exists(compose_file):
|
|
151
|
-
print("DEBUG INFRA: Skipping Verdaccio (compose file not found)")
|
|
152
|
-
return
|
|
153
|
-
print("DEBUG INFRA: Loading Verdaccio from {} with env_file={}".format(compose_file, env_file))
|
|
154
|
-
_docker_compose(compose_file, env_file)
|
|
155
|
-
print("DEBUG INFRA: Calling dc_resource for verdaccio")
|
|
156
|
-
dc_resource(PlatformDockerConstants.VERDACCIO_RESOURCE_NAME, labels=['infra.tools', 'registry'], resource_deps=['init-networks'], auto_init=True)
|
|
157
|
-
print("DEBUG INFRA: dc_resource for verdaccio completed")
|
|
158
|
-
local_resource(PlatformDockerConstants.VERDACCIO_CONNECT_NETWORK_RESOURCE,
|
|
159
|
-
cmd='docker network connect ' + PlatformDockerConstants.NETWORK_BACKEND + ' ' + PlatformDockerConstants.VERDACCIO_CONTAINER_NAME + ' 2>/dev/null || true',
|
|
160
|
-
labels=['infra.tools', 'registry'],
|
|
161
|
-
resource_deps=[PlatformDockerConstants.VERDACCIO_RESOURCE_NAME, 'init-networks'],
|
|
162
|
-
auto_init=True
|
|
163
|
-
)
|
|
137
|
+
_load_verdaccio = load_verdaccio
|
|
164
138
|
|
|
165
139
|
|
|
166
140
|
# =============================================================================
|
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.39",
|
|
4
4
|
"description": "TDK CLI - Tilt Development Kit command line interface",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"tdk",
|
|
@@ -43,7 +43,7 @@
|
|
|
43
43
|
"build:watch": "tsc --watch",
|
|
44
44
|
"lint": "biome check .",
|
|
45
45
|
"lint:fix": "biome check . --write",
|
|
46
|
-
"typecheck": "tsc --
|
|
46
|
+
"typecheck": "tsc --project tsconfig.typecheck.json",
|
|
47
47
|
"clean": "rm -rf dist",
|
|
48
48
|
"dev": "bun run build:watch",
|
|
49
49
|
"test": "vitest run",
|
|
@@ -51,7 +51,6 @@
|
|
|
51
51
|
"prepack": "../scripts/stage-npm-engine.sh && npm run build"
|
|
52
52
|
},
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@types/react": "^19.2.14",
|
|
55
54
|
"chalk": "^5.3.0",
|
|
56
55
|
"commander": "^12.0.0",
|
|
57
56
|
"handlebars": "^4.7.8",
|
|
@@ -62,6 +61,7 @@
|
|
|
62
61
|
},
|
|
63
62
|
"devDependencies": {
|
|
64
63
|
"@biomejs/biome": "^2.5.13",
|
|
64
|
+
"@types/react": "^19.2.14",
|
|
65
65
|
"@types/inquirer": "^9.0.0",
|
|
66
66
|
"@types/node": "^20.0.0",
|
|
67
67
|
"knip": "^6.35.1",
|