buncargo 1.0.5 → 1.0.8

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/bin.js ADDED
@@ -0,0 +1,343 @@
1
+ #!/usr/bin/env bun
2
+ import {
3
+ runCli
4
+ } from "./index-xcx25j3c.js";
5
+ import {
6
+ createDevEnvironment
7
+ } from "./index-cft124d3.js";
8
+ import"./index-8gd8fkwx.js";
9
+ import"./index-6qd90dkp.js";
10
+ import"./index-tjqw9vtj.js";
11
+ import"./index-tn0r1rx7.js";
12
+ import"./index-2fr3g85b.js";
13
+ import"./index-6fm7mvwj.js";
14
+ import"./index-08wa79cs.js";
15
+ import {
16
+ __commonJS
17
+ } from "./index-qnx9j3qa.js";
18
+
19
+ // package.json
20
+ var require_package = __commonJS((exports, module) => {
21
+ module.exports = {
22
+ name: "buncargo",
23
+ version: "1.0.8",
24
+ description: "A Bun-powered development environment CLI for managing Docker Compose services, dev servers, and environment variables",
25
+ type: "module",
26
+ module: "./dist/index.js",
27
+ main: "./dist/index.js",
28
+ types: "./dist/index.d.ts",
29
+ license: "MIT",
30
+ repository: {
31
+ type: "git",
32
+ url: "git+https://github.com/HansKristoffer/buncargo.git"
33
+ },
34
+ author: "Kristoffer Hansen",
35
+ keywords: [
36
+ "bun",
37
+ "dev-tools",
38
+ "docker",
39
+ "docker-compose",
40
+ "development",
41
+ "cli",
42
+ "monorepo",
43
+ "dev-server",
44
+ "environment"
45
+ ],
46
+ engines: {
47
+ bun: ">=1.0.0"
48
+ },
49
+ files: [
50
+ "*.ts",
51
+ "core/*.ts",
52
+ "dist",
53
+ "!*.test.ts",
54
+ "!core/*.test.ts"
55
+ ],
56
+ bin: {
57
+ "dev-tools": "./dist/bin.js",
58
+ buncargo: "./dist/bin.js"
59
+ },
60
+ exports: {
61
+ ".": {
62
+ types: "./dist/index.d.ts",
63
+ bun: "./index.ts",
64
+ import: "./dist/index.js",
65
+ default: "./dist/index.js"
66
+ },
67
+ "./types": {
68
+ types: "./dist/types.d.ts",
69
+ bun: "./types.ts",
70
+ import: "./dist/types.js",
71
+ default: "./dist/types.js"
72
+ },
73
+ "./config": {
74
+ types: "./dist/config.d.ts",
75
+ bun: "./config.ts",
76
+ import: "./dist/config.js",
77
+ default: "./dist/config.js"
78
+ },
79
+ "./environment": {
80
+ types: "./dist/environment.d.ts",
81
+ bun: "./environment.ts",
82
+ import: "./dist/environment.js",
83
+ default: "./dist/environment.js"
84
+ },
85
+ "./core/ports": {
86
+ types: "./dist/core/ports.d.ts",
87
+ bun: "./core/ports.ts",
88
+ import: "./dist/core/ports.js",
89
+ default: "./dist/core/ports.js"
90
+ },
91
+ "./core/docker": {
92
+ types: "./dist/core/docker.d.ts",
93
+ bun: "./core/docker.ts",
94
+ import: "./dist/core/docker.js",
95
+ default: "./dist/core/docker.js"
96
+ },
97
+ "./core/network": {
98
+ types: "./dist/core/network.d.ts",
99
+ bun: "./core/network.ts",
100
+ import: "./dist/core/network.js",
101
+ default: "./dist/core/network.js"
102
+ },
103
+ "./core/process": {
104
+ types: "./dist/core/process.d.ts",
105
+ bun: "./core/process.ts",
106
+ import: "./dist/core/process.js",
107
+ default: "./dist/core/process.js"
108
+ },
109
+ "./core/watchdog": {
110
+ types: "./dist/core/watchdog.d.ts",
111
+ bun: "./core/watchdog.ts",
112
+ import: "./dist/core/watchdog.js",
113
+ default: "./dist/core/watchdog.js"
114
+ },
115
+ "./core/utils": {
116
+ types: "./dist/core/utils.d.ts",
117
+ bun: "./core/utils.ts",
118
+ import: "./dist/core/utils.js",
119
+ default: "./dist/core/utils.js"
120
+ },
121
+ "./cli": {
122
+ types: "./dist/cli.d.ts",
123
+ bun: "./cli.ts",
124
+ import: "./dist/cli.js",
125
+ default: "./dist/cli.js"
126
+ },
127
+ "./lint": {
128
+ types: "./dist/lint.d.ts",
129
+ bun: "./lint.ts",
130
+ import: "./dist/lint.js",
131
+ default: "./dist/lint.js"
132
+ },
133
+ "./loader": {
134
+ types: "./dist/loader.d.ts",
135
+ bun: "./loader.ts",
136
+ import: "./dist/loader.js",
137
+ default: "./dist/loader.js"
138
+ }
139
+ },
140
+ scripts: {
141
+ build: "bun run build:js && bun run build:types",
142
+ "build:js": "bun build ./index.ts ./bin.ts ./cli.ts ./config.ts ./environment.ts ./lint.ts ./loader.ts ./prisma.ts ./types.ts ./core/docker.ts ./core/index.ts ./core/network.ts ./core/ports.ts ./core/process.ts ./core/utils.ts ./core/watchdog.ts ./core/watchdog-runner.ts --outdir ./dist --target node --packages external --splitting",
143
+ "build:types": "tsc -p tsconfig.build.json",
144
+ prepublishOnly: "bun run build",
145
+ "publish:patch": "npm version patch && npm publish",
146
+ "publish:minor": "npm version minor && npm publish",
147
+ "publish:major": "npm version major && npm publish",
148
+ lint: "bun run typecheck && biome check",
149
+ "lint:write": "bun run typecheck && biome check --fix && biome format",
150
+ typecheck: "tsgo --incremental"
151
+ },
152
+ devDependencies: {
153
+ "@types/bun": "1.3.2",
154
+ "@biomejs/biome": "2.3.4",
155
+ "@typescript/native-preview": "7.0.0-dev.20260127.1",
156
+ typescript: "^5.7.0"
157
+ },
158
+ dependencies: {
159
+ picocolors: "^1.1.1"
160
+ }
161
+ };
162
+ });
163
+
164
+ // bin.ts
165
+ var CONFIG_FILES = [
166
+ "dev.config.ts",
167
+ "dev.config.js",
168
+ "dev-tools.config.ts",
169
+ "dev-tools.config.js"
170
+ ];
171
+ async function loadEnv() {
172
+ const cwd = process.cwd();
173
+ for (const file of CONFIG_FILES) {
174
+ const path = `${cwd}/${file}`;
175
+ const exists = await Bun.file(path).exists();
176
+ if (exists) {
177
+ try {
178
+ const mod = await import(path);
179
+ const config = mod.default;
180
+ if (!config) {
181
+ console.error(`❌ Config file "${file}" found but no default export.`);
182
+ console.error("");
183
+ console.error(" Export your config as default:");
184
+ console.error("");
185
+ console.error(" import { defineDevConfig } from 'buncargo'");
186
+ console.error("");
187
+ console.error(" export default defineDevConfig({ ... })");
188
+ process.exit(1);
189
+ }
190
+ if (!config.projectPrefix || !config.services) {
191
+ console.error(`❌ Config file "${file}" is not a valid dev config.`);
192
+ console.error("");
193
+ console.error(" Make sure to use defineDevConfig:");
194
+ console.error("");
195
+ console.error(" export default defineDevConfig({");
196
+ console.error(" projectPrefix: 'myapp',");
197
+ console.error(" services: { ... }");
198
+ console.error(" })");
199
+ process.exit(1);
200
+ }
201
+ return createDevEnvironment(config);
202
+ } catch (error) {
203
+ console.error(`❌ Failed to load config file "${file}":`);
204
+ console.error(error);
205
+ process.exit(1);
206
+ }
207
+ }
208
+ }
209
+ console.error("❌ No config file found.");
210
+ console.error("");
211
+ console.error(" Create a dev.config.ts file in your project root:");
212
+ console.error("");
213
+ console.error(" import { defineDevConfig } from 'buncargo'");
214
+ console.error("");
215
+ console.error(" export default defineDevConfig({");
216
+ console.error(" projectPrefix: 'myapp',");
217
+ console.error(" services: {");
218
+ console.error(' postgres: { port: 5432, healthCheck: "pg_isready" }');
219
+ console.error(" }");
220
+ console.error(" })");
221
+ console.error("");
222
+ console.error(" Supported config files:");
223
+ for (const file of CONFIG_FILES) {
224
+ console.error(` - ${file}`);
225
+ }
226
+ process.exit(1);
227
+ }
228
+ async function handleDev(args) {
229
+ const env = await loadEnv();
230
+ await runCli(env, { args });
231
+ }
232
+ async function handlePrisma(args) {
233
+ const env = await loadEnv();
234
+ if (!env.prisma) {
235
+ console.error("❌ Prisma is not configured in your dev config.");
236
+ console.error("");
237
+ console.error(" Add prisma to your config:");
238
+ console.error("");
239
+ console.error(" export default defineDevConfig({");
240
+ console.error(" ...");
241
+ console.error(" prisma: {");
242
+ console.error(" cwd: 'packages/prisma'");
243
+ console.error(" }");
244
+ console.error(" })");
245
+ process.exit(1);
246
+ }
247
+ const running = await env.isRunning();
248
+ if (!running) {
249
+ console.log("\uD83D\uDC33 Starting database container...");
250
+ await env.start({ startServers: false, wait: true });
251
+ }
252
+ const exitCode = await env.prisma.run(args);
253
+ process.exit(exitCode);
254
+ }
255
+ async function handleEnv() {
256
+ const env = await loadEnv();
257
+ console.log(JSON.stringify({
258
+ projectName: env.projectName,
259
+ ports: env.ports,
260
+ urls: env.urls,
261
+ portOffset: env.portOffset,
262
+ isWorktree: env.isWorktree,
263
+ localIp: env.localIp,
264
+ root: env.root
265
+ }, null, 2));
266
+ }
267
+ function showHelp() {
268
+ console.log(`
269
+ buncargo - Development environment CLI
270
+
271
+ USAGE:
272
+ bunx buncargo <command> [options]
273
+
274
+ COMMANDS:
275
+ dev Start the development environment
276
+ prisma <args> Run Prisma CLI with correct DATABASE_URL
277
+ env Print environment info as JSON
278
+ help Show this help message
279
+ version Show version
280
+
281
+ DEV OPTIONS:
282
+ --up-only Start containers only (no dev servers)
283
+ --down Stop containers
284
+ --reset Stop containers and remove volumes
285
+ --migrate Run migrations only
286
+ --seed Run seeders
287
+ --lint Run typecheck (no Docker required)
288
+
289
+ EXAMPLES:
290
+ bunx buncargo dev # Start everything
291
+ bunx buncargo dev --down # Stop containers
292
+ bunx buncargo prisma studio # Open Prisma Studio
293
+ bunx buncargo env # Get ports/urls as JSON
294
+
295
+ CONFIG:
296
+ Create a dev.config.ts with a default export:
297
+
298
+ import { defineDevConfig } from 'buncargo'
299
+
300
+ export default defineDevConfig({
301
+ projectPrefix: 'myapp',
302
+ services: { ... },
303
+ apps: { ... }
304
+ })
305
+ `);
306
+ }
307
+ function showVersion() {
308
+ const pkg = require_package();
309
+ console.log(`buncargo v${pkg.version}`);
310
+ }
311
+ async function main() {
312
+ const args = process.argv.slice(2);
313
+ const command = args[0];
314
+ const commandArgs = args.slice(1);
315
+ if (!command || command === "help" || command === "--help" || command === "-h") {
316
+ showHelp();
317
+ process.exit(0);
318
+ }
319
+ if (command === "version" || command === "--version" || command === "-v") {
320
+ showVersion();
321
+ process.exit(0);
322
+ }
323
+ switch (command) {
324
+ case "dev":
325
+ await handleDev(commandArgs);
326
+ break;
327
+ case "prisma":
328
+ await handlePrisma(commandArgs);
329
+ break;
330
+ case "env":
331
+ await handleEnv();
332
+ break;
333
+ default:
334
+ console.error(`❌ Unknown command: ${command}`);
335
+ console.error("");
336
+ console.error(' Run "bunx buncargo help" for available commands.');
337
+ process.exit(1);
338
+ }
339
+ }
340
+ main().catch((error) => {
341
+ console.error("❌ Fatal error:", error);
342
+ process.exit(1);
343
+ });
package/dist/cli.js ADDED
@@ -0,0 +1,13 @@
1
+ import {
2
+ getFlagValue,
3
+ hasFlag,
4
+ runCli
5
+ } from "./index-xcx25j3c.js";
6
+ import"./index-8gd8fkwx.js";
7
+ import"./index-6qd90dkp.js";
8
+ import"./index-qnx9j3qa.js";
9
+ export {
10
+ runCli,
11
+ hasFlag,
12
+ getFlagValue
13
+ };
package/dist/config.js ADDED
@@ -0,0 +1,15 @@
1
+ import {
2
+ assertValidConfig,
3
+ defineDevConfig,
4
+ definePartialConfig,
5
+ mergeConfigs,
6
+ validateConfig
7
+ } from "./index-tjqw9vtj.js";
8
+ import"./index-qnx9j3qa.js";
9
+ export {
10
+ validateConfig,
11
+ mergeConfigs,
12
+ definePartialConfig,
13
+ defineDevConfig,
14
+ assertValidConfig
15
+ };
@@ -0,0 +1,29 @@
1
+ import {
2
+ MAX_ATTEMPTS,
3
+ POLL_INTERVAL,
4
+ areContainersRunning,
5
+ createBuiltInHealthCheck,
6
+ isContainerRunning,
7
+ startContainers,
8
+ startService,
9
+ stopContainers,
10
+ waitForAllServices,
11
+ waitForService,
12
+ waitForServiceByType
13
+ } from "../index-2fr3g85b.js";
14
+ import"../index-6fm7mvwj.js";
15
+ import"../index-08wa79cs.js";
16
+ import"../index-qnx9j3qa.js";
17
+ export {
18
+ waitForServiceByType,
19
+ waitForService,
20
+ waitForAllServices,
21
+ stopContainers,
22
+ startService,
23
+ startContainers,
24
+ isContainerRunning,
25
+ createBuiltInHealthCheck,
26
+ areContainersRunning,
27
+ POLL_INTERVAL,
28
+ MAX_ATTEMPTS
29
+ };
@@ -0,0 +1,105 @@
1
+ import {
2
+ getHeartbeatFile,
3
+ getWatchdogPid,
4
+ getWatchdogPidFile,
5
+ isWatchdogRunning,
6
+ readHeartbeat,
7
+ removeHeartbeatFile,
8
+ spawnWatchdog,
9
+ startHeartbeat,
10
+ stopHeartbeat,
11
+ stopWatchdog
12
+ } from "../index-8gd8fkwx.js";
13
+ import {
14
+ buildApps,
15
+ exec,
16
+ execAsync,
17
+ isProcessAlive,
18
+ spawnDevServer,
19
+ startDevServers,
20
+ stopAllProcesses,
21
+ stopProcess
22
+ } from "../index-6qd90dkp.js";
23
+ import {
24
+ MAX_ATTEMPTS,
25
+ POLL_INTERVAL,
26
+ areContainersRunning,
27
+ createBuiltInHealthCheck,
28
+ isContainerRunning,
29
+ startContainers,
30
+ startService,
31
+ stopContainers,
32
+ waitForAllServices,
33
+ waitForService,
34
+ waitForServiceByType
35
+ } from "../index-2fr3g85b.js";
36
+ import {
37
+ getEnvVar,
38
+ getLocalIp,
39
+ isCI,
40
+ isPortAvailable,
41
+ logApiUrl,
42
+ logExpoApiUrl,
43
+ logFrontendPort,
44
+ sleep,
45
+ waitForDevServers,
46
+ waitForServer
47
+ } from "../index-6fm7mvwj.js";
48
+ import {
49
+ calculatePortOffset,
50
+ computePorts,
51
+ computeUrls,
52
+ findMonorepoRoot,
53
+ getProjectName,
54
+ getWorktreeName,
55
+ isWorktree
56
+ } from "../index-08wa79cs.js";
57
+ import"../index-qnx9j3qa.js";
58
+ export {
59
+ waitForServiceByType,
60
+ waitForService,
61
+ waitForServer,
62
+ waitForDevServers,
63
+ waitForAllServices,
64
+ stopWatchdog,
65
+ stopProcess,
66
+ stopHeartbeat,
67
+ stopContainers,
68
+ stopAllProcesses,
69
+ startService,
70
+ startHeartbeat,
71
+ startDevServers,
72
+ startContainers,
73
+ spawnWatchdog,
74
+ spawnDevServer,
75
+ sleep,
76
+ removeHeartbeatFile,
77
+ readHeartbeat,
78
+ logFrontendPort,
79
+ logExpoApiUrl,
80
+ logApiUrl,
81
+ isWorktree,
82
+ isWatchdogRunning,
83
+ isProcessAlive,
84
+ isPortAvailable,
85
+ isContainerRunning,
86
+ isCI,
87
+ getWorktreeName,
88
+ getWatchdogPidFile,
89
+ getWatchdogPid,
90
+ getProjectName,
91
+ getLocalIp,
92
+ getHeartbeatFile,
93
+ getEnvVar,
94
+ findMonorepoRoot,
95
+ execAsync,
96
+ exec,
97
+ createBuiltInHealthCheck,
98
+ computeUrls,
99
+ computePorts,
100
+ calculatePortOffset,
101
+ buildApps,
102
+ areContainersRunning,
103
+ POLL_INTERVAL,
104
+ MAX_ATTEMPTS
105
+ };
@@ -0,0 +1,14 @@
1
+ import {
2
+ getLocalIp,
3
+ isPortAvailable,
4
+ waitForDevServers,
5
+ waitForServer
6
+ } from "../index-6fm7mvwj.js";
7
+ import"../index-08wa79cs.js";
8
+ import"../index-qnx9j3qa.js";
9
+ export {
10
+ waitForServer,
11
+ waitForDevServers,
12
+ isPortAvailable,
13
+ getLocalIp
14
+ };
@@ -0,0 +1,19 @@
1
+ import {
2
+ calculatePortOffset,
3
+ computePorts,
4
+ computeUrls,
5
+ findMonorepoRoot,
6
+ getProjectName,
7
+ getWorktreeName,
8
+ isWorktree
9
+ } from "../index-08wa79cs.js";
10
+ import"../index-qnx9j3qa.js";
11
+ export {
12
+ isWorktree,
13
+ getWorktreeName,
14
+ getProjectName,
15
+ findMonorepoRoot,
16
+ computeUrls,
17
+ computePorts,
18
+ calculatePortOffset
19
+ };
@@ -0,0 +1,21 @@
1
+ import {
2
+ buildApps,
3
+ exec,
4
+ execAsync,
5
+ isProcessAlive,
6
+ spawnDevServer,
7
+ startDevServers,
8
+ stopAllProcesses,
9
+ stopProcess
10
+ } from "../index-6qd90dkp.js";
11
+ import"../index-qnx9j3qa.js";
12
+ export {
13
+ stopProcess,
14
+ stopAllProcesses,
15
+ startDevServers,
16
+ spawnDevServer,
17
+ isProcessAlive,
18
+ execAsync,
19
+ exec,
20
+ buildApps
21
+ };
@@ -0,0 +1,18 @@
1
+ import {
2
+ getEnvVar,
3
+ isCI,
4
+ logApiUrl,
5
+ logExpoApiUrl,
6
+ logFrontendPort,
7
+ sleep
8
+ } from "../index-6fm7mvwj.js";
9
+ import"../index-08wa79cs.js";
10
+ import"../index-qnx9j3qa.js";
11
+ export {
12
+ sleep,
13
+ logFrontendPort,
14
+ logExpoApiUrl,
15
+ logApiUrl,
16
+ isCI,
17
+ getEnvVar
18
+ };
@@ -0,0 +1,66 @@
1
+ // core/watchdog-runner.ts
2
+ import { execSync } from "node:child_process";
3
+ import { existsSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
4
+ var PROJECT_NAME = process.env.WATCHDOG_PROJECT_NAME ?? "";
5
+ var HEARTBEAT_FILE = process.env.WATCHDOG_HEARTBEAT_FILE ?? "";
6
+ var PID_FILE = process.env.WATCHDOG_PID_FILE ?? "";
7
+ var IDLE_TIMEOUT = parseInt(process.env.WATCHDOG_TIMEOUT_MS ?? "600000", 10);
8
+ var COMPOSE_ARG = process.env.WATCHDOG_COMPOSE_ARG ?? "";
9
+ var CHECK_INTERVAL = 60000;
10
+ if (!PROJECT_NAME || !HEARTBEAT_FILE || !PID_FILE) {
11
+ console.error("[watchdog] Missing required environment variables");
12
+ process.exit(1);
13
+ }
14
+ var heartbeatFile = HEARTBEAT_FILE;
15
+ var pidFile = PID_FILE;
16
+ writeFileSync(pidFile, process.pid.toString());
17
+ function cleanup() {
18
+ try {
19
+ unlinkSync(pidFile);
20
+ } catch {}
21
+ try {
22
+ unlinkSync(heartbeatFile);
23
+ } catch {}
24
+ }
25
+ process.on("SIGTERM", () => {
26
+ cleanup();
27
+ process.exit(0);
28
+ });
29
+ process.on("SIGINT", () => {
30
+ cleanup();
31
+ process.exit(0);
32
+ });
33
+ console.log(`[watchdog] Started for ${PROJECT_NAME} (PID: ${process.pid})`);
34
+ console.log(`[watchdog] Idle timeout: ${IDLE_TIMEOUT / 60000} minutes`);
35
+ async function watchdog() {
36
+ while (true) {
37
+ await new Promise((r) => setTimeout(r, CHECK_INTERVAL));
38
+ if (!existsSync(heartbeatFile)) {
39
+ continue;
40
+ }
41
+ let lastBeat;
42
+ try {
43
+ const content = readFileSync(heartbeatFile, "utf-8");
44
+ lastBeat = parseInt(content, 10);
45
+ } catch {
46
+ continue;
47
+ }
48
+ if (Number.isNaN(lastBeat)) {
49
+ continue;
50
+ }
51
+ const elapsed = Date.now() - lastBeat;
52
+ if (elapsed > IDLE_TIMEOUT) {
53
+ console.log(`[watchdog] No heartbeat for ${Math.ceil(elapsed / 60000)} minutes, shutting down...`);
54
+ try {
55
+ execSync(`docker compose ${COMPOSE_ARG} down`.trim(), {
56
+ env: { ...process.env, COMPOSE_PROJECT_NAME: PROJECT_NAME },
57
+ stdio: "ignore"
58
+ });
59
+ } catch {}
60
+ console.log("[watchdog] Containers stopped");
61
+ cleanup();
62
+ process.exit(0);
63
+ }
64
+ }
65
+ }
66
+ watchdog();
@@ -0,0 +1,26 @@
1
+ import {
2
+ getHeartbeatFile,
3
+ getWatchdogPid,
4
+ getWatchdogPidFile,
5
+ isWatchdogRunning,
6
+ readHeartbeat,
7
+ removeHeartbeatFile,
8
+ spawnWatchdog,
9
+ startHeartbeat,
10
+ stopHeartbeat,
11
+ stopWatchdog
12
+ } from "../index-8gd8fkwx.js";
13
+ import"../index-6qd90dkp.js";
14
+ import"../index-qnx9j3qa.js";
15
+ export {
16
+ stopWatchdog,
17
+ stopHeartbeat,
18
+ startHeartbeat,
19
+ spawnWatchdog,
20
+ removeHeartbeatFile,
21
+ readHeartbeat,
22
+ isWatchdogRunning,
23
+ getWatchdogPidFile,
24
+ getWatchdogPid,
25
+ getHeartbeatFile
26
+ };
@@ -0,0 +1,14 @@
1
+ import {
2
+ createDevEnvironment
3
+ } from "./index-cft124d3.js";
4
+ import"./index-8gd8fkwx.js";
5
+ import"./index-6qd90dkp.js";
6
+ import"./index-tjqw9vtj.js";
7
+ import"./index-tn0r1rx7.js";
8
+ import"./index-2fr3g85b.js";
9
+ import"./index-6fm7mvwj.js";
10
+ import"./index-08wa79cs.js";
11
+ import"./index-qnx9j3qa.js";
12
+ export {
13
+ createDevEnvironment
14
+ };