@getmonoceros/workbench 1.24.2 → 1.26.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/bundled-components/services/mailpit/component.yml +17 -0
- package/bundled-components/services/mongodb/component.yml +36 -0
- package/bundled-components/services/mysql/component.yml +8 -6
- package/bundled-components/services/pgvector/component.yml +36 -0
- package/bundled-components/services/postgres/component.yml +8 -6
- package/bundled-components/services/redis/component.yml +5 -1
- package/bundled-components/services/rustfs/component.yml +28 -0
- package/dist/bin.js +112 -35
- package/dist/bin.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
id: mailpit
|
|
2
|
+
category: service
|
|
3
|
+
displayName: Mailpit
|
|
4
|
+
description: 'SMTP catcher for local dev — apps send mail to it and nothing leaves the machine. SMTP on `mailpit:1025`; web UI + API on 8025 (reach via `monoceros tunnel <name> mailpit:8025`).'
|
|
5
|
+
service:
|
|
6
|
+
image: axllent/mailpit:latest
|
|
7
|
+
defaultPort: 1025
|
|
8
|
+
healthcheck:
|
|
9
|
+
# Mailpit ships its own readiness probe in the image — no curl/wget needed.
|
|
10
|
+
test: [CMD, /mailpit, readyz]
|
|
11
|
+
interval: 15s
|
|
12
|
+
timeout: 5s
|
|
13
|
+
retries: 5
|
|
14
|
+
connectionEnv:
|
|
15
|
+
URL: smtp://${host}:${port}
|
|
16
|
+
HOST: ${host}
|
|
17
|
+
PORT: ${port}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
id: mongodb
|
|
2
|
+
category: service
|
|
3
|
+
displayName: MongoDB
|
|
4
|
+
description: 'MongoDB with seeded dev credentials and a readiness healthcheck. Reachable in-container as host `mongodb`.'
|
|
5
|
+
service:
|
|
6
|
+
image: mongo:8
|
|
7
|
+
defaultPort: 27017
|
|
8
|
+
dataMount: /data/db
|
|
9
|
+
healthcheck:
|
|
10
|
+
test: [CMD, mongosh, --quiet, --eval, 'db.adminCommand({ ping: 1 }).ok']
|
|
11
|
+
interval: 10s
|
|
12
|
+
timeout: 5s
|
|
13
|
+
retries: 5
|
|
14
|
+
vscodeExtensions: [mongodb.mongodb-vscode]
|
|
15
|
+
client:
|
|
16
|
+
npm: [mongosh]
|
|
17
|
+
connectionEnv:
|
|
18
|
+
URL: mongodb://${MONGO_INITDB_ROOT_USERNAME}:${MONGO_INITDB_ROOT_PASSWORD}@${host}:${port}/${MONGO_INITDB_DATABASE}?authSource=admin
|
|
19
|
+
HOST: ${host}
|
|
20
|
+
PORT: ${port}
|
|
21
|
+
USER: ${MONGO_INITDB_ROOT_USERNAME}
|
|
22
|
+
PASSWORD: ${MONGO_INITDB_ROOT_PASSWORD}
|
|
23
|
+
DB: ${MONGO_INITDB_DATABASE}
|
|
24
|
+
options:
|
|
25
|
+
MONGO_INITDB_ROOT_USERNAME:
|
|
26
|
+
type: string
|
|
27
|
+
default: monoceros
|
|
28
|
+
surface: env
|
|
29
|
+
MONGO_INITDB_ROOT_PASSWORD:
|
|
30
|
+
type: string
|
|
31
|
+
default: monoceros
|
|
32
|
+
surface: env
|
|
33
|
+
MONGO_INITDB_DATABASE:
|
|
34
|
+
type: string
|
|
35
|
+
default: monoceros
|
|
36
|
+
surface: env
|
|
@@ -22,13 +22,15 @@ service:
|
|
|
22
22
|
timeout: 5s
|
|
23
23
|
retries: 5
|
|
24
24
|
vscodeExtensions: [cweijan.vscode-database-client2]
|
|
25
|
+
client:
|
|
26
|
+
apt: [default-mysql-client]
|
|
25
27
|
connectionEnv:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
28
|
+
URL: mysql://root:${MYSQL_ROOT_PASSWORD}@${host}:${port}/${MYSQL_DATABASE}
|
|
29
|
+
HOST: ${host}
|
|
30
|
+
PORT: ${port}
|
|
31
|
+
USER: root
|
|
32
|
+
PASSWORD: ${MYSQL_ROOT_PASSWORD}
|
|
33
|
+
DB: ${MYSQL_DATABASE}
|
|
32
34
|
options:
|
|
33
35
|
MYSQL_ROOT_PASSWORD:
|
|
34
36
|
type: string
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
id: pgvector
|
|
2
|
+
category: service
|
|
3
|
+
displayName: pgvector (PostgreSQL + vectors)
|
|
4
|
+
description: 'PostgreSQL with the pgvector extension for embeddings / vector search — a drop-in Postgres. Reachable in-container as host `pgvector`. Enable the extension once with `CREATE EXTENSION vector;` (or in your migration).'
|
|
5
|
+
service:
|
|
6
|
+
image: pgvector/pgvector:pg18
|
|
7
|
+
defaultPort: 5432
|
|
8
|
+
dataMount: /var/lib/postgresql
|
|
9
|
+
healthcheck:
|
|
10
|
+
test: [CMD, pg_isready, -U, '${POSTGRES_USER}', -d, '${POSTGRES_DB}']
|
|
11
|
+
interval: 10s
|
|
12
|
+
timeout: 5s
|
|
13
|
+
retries: 5
|
|
14
|
+
vscodeExtensions: [cweijan.vscode-database-client2]
|
|
15
|
+
client:
|
|
16
|
+
apt: [postgresql-client]
|
|
17
|
+
connectionEnv:
|
|
18
|
+
URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${host}:${port}/${POSTGRES_DB}
|
|
19
|
+
HOST: ${host}
|
|
20
|
+
PORT: ${port}
|
|
21
|
+
USER: ${POSTGRES_USER}
|
|
22
|
+
PASSWORD: ${POSTGRES_PASSWORD}
|
|
23
|
+
DB: ${POSTGRES_DB}
|
|
24
|
+
options:
|
|
25
|
+
POSTGRES_USER:
|
|
26
|
+
type: string
|
|
27
|
+
default: monoceros
|
|
28
|
+
surface: env
|
|
29
|
+
POSTGRES_PASSWORD:
|
|
30
|
+
type: string
|
|
31
|
+
default: monoceros
|
|
32
|
+
surface: env
|
|
33
|
+
POSTGRES_DB:
|
|
34
|
+
type: string
|
|
35
|
+
default: monoceros
|
|
36
|
+
surface: env
|
|
@@ -12,13 +12,15 @@ service:
|
|
|
12
12
|
timeout: 5s
|
|
13
13
|
retries: 5
|
|
14
14
|
vscodeExtensions: [cweijan.vscode-database-client2]
|
|
15
|
+
client:
|
|
16
|
+
apt: [postgresql-client]
|
|
15
17
|
connectionEnv:
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
18
|
+
URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${host}:${port}/${POSTGRES_DB}
|
|
19
|
+
HOST: ${host}
|
|
20
|
+
PORT: ${port}
|
|
21
|
+
USER: ${POSTGRES_USER}
|
|
22
|
+
PASSWORD: ${POSTGRES_PASSWORD}
|
|
23
|
+
DB: ${POSTGRES_DB}
|
|
22
24
|
options:
|
|
23
25
|
POSTGRES_USER:
|
|
24
26
|
type: string
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
id: rustfs
|
|
2
|
+
category: service
|
|
3
|
+
displayName: RustFS
|
|
4
|
+
description: 'S3-compatible object storage (MinIO-compatible API). S3 API on `rustfs:9000`; web console on 9001 (enable with `RUSTFS_CONSOLE_ENABLE=true`, reach via `monoceros tunnel <name> rustfs:9001`).'
|
|
5
|
+
service:
|
|
6
|
+
image: rustfs/rustfs:latest
|
|
7
|
+
defaultPort: 9000
|
|
8
|
+
dataMount: /data
|
|
9
|
+
healthcheck:
|
|
10
|
+
test: [CMD, curl, -f, 'http://localhost:9000/minio/health/live']
|
|
11
|
+
interval: 10s
|
|
12
|
+
timeout: 5s
|
|
13
|
+
retries: 5
|
|
14
|
+
connectionEnv:
|
|
15
|
+
URL: http://${host}:${port}
|
|
16
|
+
HOST: ${host}
|
|
17
|
+
PORT: ${port}
|
|
18
|
+
ACCESS_KEY: ${RUSTFS_ACCESS_KEY}
|
|
19
|
+
SECRET_KEY: ${RUSTFS_SECRET_KEY}
|
|
20
|
+
options:
|
|
21
|
+
RUSTFS_ACCESS_KEY:
|
|
22
|
+
type: string
|
|
23
|
+
default: rustfsadmin
|
|
24
|
+
surface: env
|
|
25
|
+
RUSTFS_SECRET_KEY:
|
|
26
|
+
type: string
|
|
27
|
+
default: rustfsadmin
|
|
28
|
+
surface: env
|
package/dist/bin.js
CHANGED
|
@@ -203,7 +203,13 @@ var init_schema = __esm({
|
|
|
203
203
|
).optional(),
|
|
204
204
|
healthcheck: ServiceHealthcheckSchema.optional(),
|
|
205
205
|
restart: z.enum(SERVICE_RESTART_VALUES).optional(),
|
|
206
|
-
command: z.string().optional()
|
|
206
|
+
command: z.string().optional(),
|
|
207
|
+
// Connection-env templates keyed by logical SUFFIX (URL/HOST/PORT/USER/
|
|
208
|
+
// PASSWORD/DB). Baked in by `expandCuratedService`; emitted into the
|
|
209
|
+
// workspace as `<UPPER(name)>_<SUFFIX>` at apply (ADR 0021). `${host}`/
|
|
210
|
+
// `${port}`/`${<OPTION>}` are render tokens, NOT `.env` placeholders, and
|
|
211
|
+
// are left untouched by `interpolateServices`.
|
|
212
|
+
connectionEnv: z.record(z.string(), z.string()).optional()
|
|
207
213
|
});
|
|
208
214
|
ExternalServicesSchema = z.object({
|
|
209
215
|
postgres: z.string().regex(
|
|
@@ -261,6 +267,18 @@ var init_schema = __esm({
|
|
|
261
267
|
git: z.object({
|
|
262
268
|
user: GitUserSchema.optional()
|
|
263
269
|
}).optional()
|
|
270
|
+
}).superRefine((cfg, ctx) => {
|
|
271
|
+
const seen = /* @__PURE__ */ new Set();
|
|
272
|
+
cfg.services.forEach((svc, i) => {
|
|
273
|
+
if (seen.has(svc.name)) {
|
|
274
|
+
ctx.addIssue({
|
|
275
|
+
code: z.ZodIssueCode.custom,
|
|
276
|
+
path: ["services", i, "name"],
|
|
277
|
+
message: `Duplicate service name '${svc.name}'. Service names must be unique (use \`add-service \u2026 --as <name>\` to add a second instance of the same image).`
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
seen.add(svc.name);
|
|
281
|
+
});
|
|
264
282
|
});
|
|
265
283
|
}
|
|
266
284
|
});
|
|
@@ -711,15 +729,30 @@ var init_descriptor = __esm({
|
|
|
711
729
|
dataMount: z2.string().optional(),
|
|
712
730
|
healthcheck: HealthcheckSchema.optional(),
|
|
713
731
|
/**
|
|
714
|
-
* Connection env
|
|
715
|
-
*
|
|
716
|
-
*
|
|
717
|
-
*
|
|
718
|
-
* `${
|
|
719
|
-
* `${
|
|
720
|
-
*
|
|
732
|
+
* Connection env injected into the WORKSPACE container so the app / agent
|
|
733
|
+
* can reach this service without hardcoding anything. Keyed by logical
|
|
734
|
+
* SUFFIX → template; emitted at apply as `<UPPER(name)>_<SUFFIX>` per
|
|
735
|
+
* service instance (ADR 0021), e.g. suffix `URL` on a service named
|
|
736
|
+
* `postgres` → `POSTGRES_URL`. Tokens: `${host}` (the service's instance
|
|
737
|
+
* name), `${port}` (its port, falling back to `defaultPort`), and
|
|
738
|
+
* `${<OPTION>}` (its own option values, e.g. `${POSTGRES_USER}`). Example:
|
|
739
|
+
* URL: postgresql://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${host}:${port}/${POSTGRES_DB}
|
|
740
|
+
* HOST: ${host}
|
|
721
741
|
*/
|
|
722
742
|
connectionEnv: z2.record(z2.string(), z2.string()).optional(),
|
|
743
|
+
/**
|
|
744
|
+
* CLI client tool(s) for this service, installed into the WORKSPACE
|
|
745
|
+
* container at apply so the dev/agent can use them (the service runs in its
|
|
746
|
+
* own container; the workspace has no client otherwise). `apt` packages are
|
|
747
|
+
* merged into the workspace's apt-packages feature (build-time, cached);
|
|
748
|
+
* `npm` packages are installed globally in post-create (guarded, so it's a
|
|
749
|
+
* no-op once present). E.g. postgres → apt `postgresql-client` (`psql`),
|
|
750
|
+
* mongodb → npm `mongosh`. See ADR 0020.
|
|
751
|
+
*/
|
|
752
|
+
client: z2.object({
|
|
753
|
+
apt: z2.array(z2.string()).optional(),
|
|
754
|
+
npm: z2.array(z2.string()).optional()
|
|
755
|
+
}).optional(),
|
|
723
756
|
vscodeExtensions: z2.array(z2.string()).optional()
|
|
724
757
|
});
|
|
725
758
|
PersistentHomeFileSchema = z2.object({
|
|
@@ -2149,7 +2182,8 @@ function resolveService(entry2) {
|
|
|
2149
2182
|
volumes: entry2.volumes ? [...entry2.volumes] : [],
|
|
2150
2183
|
...entry2.healthcheck ? { healthcheck: entry2.healthcheck } : {},
|
|
2151
2184
|
...entry2.restart ? { restart: entry2.restart } : {},
|
|
2152
|
-
...entry2.command ? { command: entry2.command } : {}
|
|
2185
|
+
...entry2.command ? { command: entry2.command } : {},
|
|
2186
|
+
...entry2.connectionEnv ? { connectionEnv: { ...entry2.connectionEnv } } : {}
|
|
2153
2187
|
};
|
|
2154
2188
|
}
|
|
2155
2189
|
function isCuratedService(name) {
|
|
@@ -2173,6 +2207,10 @@ function expandCuratedService(name) {
|
|
|
2173
2207
|
} : {},
|
|
2174
2208
|
...def.dataMount ? { volumes: [`data:${def.dataMount}`] } : {},
|
|
2175
2209
|
...def.healthcheck ? { healthcheck: def.healthcheck } : {},
|
|
2210
|
+
// Bake the connection-env templates into the yml (suffix → template) so
|
|
2211
|
+
// they travel with the service: a renamed/duplicated instance keeps them,
|
|
2212
|
+
// and `serviceConnectionEnv` prefixes by the instance's current name.
|
|
2213
|
+
...def.connectionEnv ? { connectionEnv: { ...def.connectionEnv } } : {},
|
|
2176
2214
|
restart: "unless-stopped"
|
|
2177
2215
|
};
|
|
2178
2216
|
}
|
|
@@ -2183,21 +2221,40 @@ function curatedServiceEnvDefaults(name) {
|
|
|
2183
2221
|
function serviceConnectionEnv(services) {
|
|
2184
2222
|
const env = {};
|
|
2185
2223
|
for (const svc of services) {
|
|
2186
|
-
const
|
|
2187
|
-
if (!
|
|
2224
|
+
const conn = svc.connectionEnv ?? SERVICE_CATALOG[svc.name]?.connectionEnv;
|
|
2225
|
+
if (!conn || Object.keys(conn).length === 0) continue;
|
|
2226
|
+
const prefix = svc.name.replace(/[^A-Za-z0-9]+/g, "_").toUpperCase();
|
|
2188
2227
|
const host = svc.name;
|
|
2189
|
-
const port = String(svc.port
|
|
2228
|
+
const port = svc.port !== void 0 ? String(svc.port) : "";
|
|
2190
2229
|
const fill = (template) => template.replace(/\$\{([A-Za-z0-9_]+)\}/g, (_, token) => {
|
|
2191
2230
|
if (token === "host") return host;
|
|
2192
2231
|
if (token === "port") return port;
|
|
2193
2232
|
return svc.env[token] ?? "";
|
|
2194
2233
|
});
|
|
2195
|
-
for (const [
|
|
2196
|
-
env[
|
|
2234
|
+
for (const [suffix, template] of Object.entries(conn)) {
|
|
2235
|
+
env[`${prefix}_${suffix}`] = fill(template);
|
|
2197
2236
|
}
|
|
2198
2237
|
}
|
|
2199
2238
|
return env;
|
|
2200
2239
|
}
|
|
2240
|
+
function serviceClientAptPackages(services) {
|
|
2241
|
+
const pkgs = /* @__PURE__ */ new Set();
|
|
2242
|
+
for (const svc of services) {
|
|
2243
|
+
for (const pkg of SERVICE_CATALOG[svc.name]?.client?.apt ?? []) {
|
|
2244
|
+
pkgs.add(pkg);
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
return [...pkgs].sort();
|
|
2248
|
+
}
|
|
2249
|
+
function serviceClientNpmPackages(services) {
|
|
2250
|
+
const pkgs = /* @__PURE__ */ new Set();
|
|
2251
|
+
for (const svc of services) {
|
|
2252
|
+
for (const pkg of SERVICE_CATALOG[svc.name]?.client?.npm ?? []) {
|
|
2253
|
+
pkgs.add(pkg);
|
|
2254
|
+
}
|
|
2255
|
+
}
|
|
2256
|
+
return [...pkgs].sort();
|
|
2257
|
+
}
|
|
2201
2258
|
function deriveServiceName(image) {
|
|
2202
2259
|
const lastSegment = image.split("/").pop() ?? image;
|
|
2203
2260
|
const noTag = lastSegment.split("@")[0].split(":")[0];
|
|
@@ -2257,7 +2314,8 @@ var init_catalog = __esm({
|
|
|
2257
2314
|
...svc.dataMount ? { dataMount: svc.dataMount } : {},
|
|
2258
2315
|
defaultPort: svc.defaultPort,
|
|
2259
2316
|
...svc.vscodeExtensions ? { vscodeExtensions: svc.vscodeExtensions } : {},
|
|
2260
|
-
...svc.connectionEnv ? { connectionEnv: svc.connectionEnv } : {}
|
|
2317
|
+
...svc.connectionEnv ? { connectionEnv: svc.connectionEnv } : {},
|
|
2318
|
+
...svc.client ? { client: svc.client } : {}
|
|
2261
2319
|
};
|
|
2262
2320
|
return [key, entry2];
|
|
2263
2321
|
})
|
|
@@ -2774,10 +2832,16 @@ function resolveFeatures(opts) {
|
|
|
2774
2832
|
persistentHomeFiles: []
|
|
2775
2833
|
});
|
|
2776
2834
|
}
|
|
2777
|
-
|
|
2835
|
+
const aptPackages = [
|
|
2836
|
+
.../* @__PURE__ */ new Set([
|
|
2837
|
+
...opts.aptPackages ?? [],
|
|
2838
|
+
...serviceClientAptPackages(opts.services)
|
|
2839
|
+
])
|
|
2840
|
+
].sort();
|
|
2841
|
+
if (aptPackages.length > 0) {
|
|
2778
2842
|
resolved.push({
|
|
2779
2843
|
devcontainerKey: "ghcr.io/devcontainers-contrib/features/apt-packages:1",
|
|
2780
|
-
options: { packages:
|
|
2844
|
+
options: { packages: aptPackages.join(",") },
|
|
2781
2845
|
persistentHomePaths: [],
|
|
2782
2846
|
persistentHomeFiles: []
|
|
2783
2847
|
});
|
|
@@ -3171,6 +3235,18 @@ function buildPostCreateScript(opts) {
|
|
|
3171
3235
|
" pnpm install",
|
|
3172
3236
|
"fi"
|
|
3173
3237
|
];
|
|
3238
|
+
const clientNpm = serviceClientNpmPackages(opts.services);
|
|
3239
|
+
if (clientNpm.length > 0) {
|
|
3240
|
+
lines.push(
|
|
3241
|
+
"",
|
|
3242
|
+
"# CLI clients for the curated services (global npm installs)."
|
|
3243
|
+
);
|
|
3244
|
+
for (const pkg of clientNpm) {
|
|
3245
|
+
lines.push(
|
|
3246
|
+
`command -v ${pkg} >/dev/null 2>&1 || npm install -g --no-audit --no-fund ${pkg}`
|
|
3247
|
+
);
|
|
3248
|
+
}
|
|
3249
|
+
}
|
|
3174
3250
|
if (opts.installUrls && opts.installUrls.length > 0) {
|
|
3175
3251
|
lines.push(
|
|
3176
3252
|
"",
|
|
@@ -5405,29 +5481,30 @@ function generateAgentsMd(input) {
|
|
|
5405
5481
|
}
|
|
5406
5482
|
lines.push("");
|
|
5407
5483
|
const connEnv = serviceConnectionEnv(input.services);
|
|
5408
|
-
|
|
5484
|
+
const connUrlKeys = Object.keys(connEnv).filter((k) => k.endsWith("_URL"));
|
|
5485
|
+
if (connUrlKeys.length > 0) {
|
|
5409
5486
|
lines.push(
|
|
5410
|
-
"Connection details for the curated services above are
|
|
5411
|
-
"environment variables in this container
|
|
5412
|
-
"
|
|
5413
|
-
"hardcode them:"
|
|
5487
|
+
"Connection details for the curated services above are set as",
|
|
5488
|
+
"environment variables in this container \u2014 one set per service, prefixed",
|
|
5489
|
+
"with the (uppercased) service name. Read them from the environment; do",
|
|
5490
|
+
"not ask the user for credentials and do not hardcode them. The URLs:"
|
|
5414
5491
|
);
|
|
5415
5492
|
lines.push("");
|
|
5416
|
-
|
|
5417
|
-
lines.push(
|
|
5418
|
-
"- `DATABASE_URL` \u2014 the SQL database. Engine-specific variables are",
|
|
5419
|
-
" set too (`PGHOST`/`PGPORT`/`PGUSER`/`PGPASSWORD`/`PGDATABASE` for",
|
|
5420
|
-
" Postgres, `MYSQL_*` for MySQL)."
|
|
5421
|
-
);
|
|
5422
|
-
}
|
|
5423
|
-
if (connEnv.REDIS_URL !== void 0) {
|
|
5424
|
-
lines.push("- `REDIS_URL` \u2014 Redis.");
|
|
5493
|
+
for (const k of connUrlKeys) {
|
|
5494
|
+
lines.push(`- \`${k}\``);
|
|
5425
5495
|
}
|
|
5426
5496
|
lines.push("");
|
|
5427
5497
|
lines.push(
|
|
5428
|
-
"
|
|
5429
|
-
"
|
|
5430
|
-
"
|
|
5498
|
+
"Each service also exposes `<SERVICE>_HOST`, `<SERVICE>_PORT` and, for SQL",
|
|
5499
|
+
"databases, `<SERVICE>_USER` / `<SERVICE>_PASSWORD` / `<SERVICE>_DB`. These",
|
|
5500
|
+
"are dev-only defaults for the local container, fine to read directly."
|
|
5501
|
+
);
|
|
5502
|
+
lines.push("");
|
|
5503
|
+
lines.push(
|
|
5504
|
+
"There is deliberately **no** bare `DATABASE_URL` (multiple databases",
|
|
5505
|
+
"would collide on it). If a framework or tool defaults to `DATABASE_URL`,",
|
|
5506
|
+
"set it in the project's `.env` to the right service URL, e.g.",
|
|
5507
|
+
"`DATABASE_URL=$POSTGRES_URL`."
|
|
5431
5508
|
);
|
|
5432
5509
|
}
|
|
5433
5510
|
const hasCustom = input.services.some((s) => !isCuratedService(s.name));
|
|
@@ -7233,7 +7310,7 @@ var CLI_VERSION;
|
|
|
7233
7310
|
var init_version = __esm({
|
|
7234
7311
|
"src/version.ts"() {
|
|
7235
7312
|
"use strict";
|
|
7236
|
-
CLI_VERSION = true ? "1.
|
|
7313
|
+
CLI_VERSION = true ? "1.26.0" : "dev";
|
|
7237
7314
|
}
|
|
7238
7315
|
});
|
|
7239
7316
|
|