@cimplify/sdk 0.44.33 → 0.44.34

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.
@@ -12,13 +12,42 @@ var CLI_ERROR_CODE = {
12
12
  ALREADY_LINKED: "ALREADY_LINKED",
13
13
  SERVER_ERROR: "SERVER_ERROR"};
14
14
  var EXIT_CODE = {
15
- ERROR: 1};
15
+ ABORTED: 3,
16
+ NOT_LINKED: 4,
17
+ ALREADY_LINKED: 5,
18
+ GIT_ERROR: 6,
19
+ INTERACTIVE_REQUIRED: 7,
20
+ PROJECT_NOT_FOUND: 8,
21
+ NETWORK_ERROR: 10,
22
+ SERVER_ERROR: 11,
23
+ TIMEOUT: 12,
24
+ NOT_LOGGED_IN: 20,
25
+ AUTH_FAILED: 21,
26
+ UNAUTHORIZED: 22,
27
+ INVALID_INPUT: 30
28
+ };
29
+ var EXIT_CODE_FOR = {
30
+ NOT_LOGGED_IN: EXIT_CODE.NOT_LOGGED_IN,
31
+ NOT_LINKED: EXIT_CODE.NOT_LINKED,
32
+ NETWORK_ERROR: EXIT_CODE.NETWORK_ERROR,
33
+ AUTH_FAILED: EXIT_CODE.AUTH_FAILED,
34
+ PROJECT_NOT_FOUND: EXIT_CODE.PROJECT_NOT_FOUND,
35
+ GIT_ERROR: EXIT_CODE.GIT_ERROR,
36
+ INVALID_INPUT: EXIT_CODE.INVALID_INPUT,
37
+ ALREADY_LINKED: EXIT_CODE.ALREADY_LINKED,
38
+ SERVER_ERROR: EXIT_CODE.SERVER_ERROR,
39
+ ABORTED: EXIT_CODE.ABORTED,
40
+ UNAUTHORIZED: EXIT_CODE.UNAUTHORIZED,
41
+ TIMEOUT: EXIT_CODE.TIMEOUT,
42
+ INTERACTIVE_REQUIRED: EXIT_CODE.INTERACTIVE_REQUIRED
43
+ };
16
44
  var CliError = class extends Error {
17
- constructor(code, message, exitCode = EXIT_CODE.ERROR) {
45
+ constructor(code, message, options = {}) {
18
46
  super(message);
19
47
  this.name = "CliError";
20
48
  this.code = code;
21
- this.exitCode = exitCode;
49
+ this.exitCode = options.exitCode ?? EXIT_CODE_FOR[code];
50
+ this.remediation = options.remediation;
22
51
  }
23
52
  };
24
53
 
@@ -196,6 +225,13 @@ function parseArgs(argv) {
196
225
  }
197
226
  return { positional, flags };
198
227
  }
228
+ function flagString(args, name) {
229
+ const v = args.flags.get(name);
230
+ return typeof v === "string" ? v : void 0;
231
+ }
232
+ function flagBool(args, name) {
233
+ return args.flags.has(name);
234
+ }
199
235
  var AUTH_FILE_NAME = "auth.json";
200
236
  var ENV_XDG_CONFIG_HOME = "XDG_CONFIG_HOME";
201
237
  var APP_CONFIG_DIR_NAME = "cimplify";
@@ -234,34 +270,79 @@ var BOLD_OPEN = "\x1B[1m";
234
270
  var DIM_OPEN = "\x1B[2m";
235
271
  var GREEN_OPEN = "\x1B[32m";
236
272
  var PREFIX_SUCCESS = "\u2713";
273
+ var ENV_JSON = "CIMPLIFY_JSON";
274
+ function envFlag(name) {
275
+ const v = process.env[name];
276
+ return v === "1" || v === "true";
277
+ }
278
+ function isJsonMode() {
279
+ return envFlag(ENV_JSON);
280
+ }
237
281
  function wrap(open, value) {
238
282
  return `${open}${value}${RESET}`;
239
283
  }
240
284
  function bold(value) {
241
- return wrap(BOLD_OPEN, value);
285
+ return isJsonMode() ? value : wrap(BOLD_OPEN, value);
242
286
  }
243
287
  function dim(value) {
244
- return wrap(DIM_OPEN, value);
288
+ return isJsonMode() ? value : wrap(DIM_OPEN, value);
245
289
  }
246
290
  function green(value) {
247
- return wrap(GREEN_OPEN, value);
291
+ return isJsonMode() ? value : wrap(GREEN_OPEN, value);
248
292
  }
249
293
  function success(message) {
294
+ if (isJsonMode()) return;
250
295
  console.log(`${green(PREFIX_SUCCESS)} ${message}`);
251
296
  }
252
297
  function info(message) {
298
+ if (isJsonMode()) return;
253
299
  console.log(message);
254
300
  }
301
+ var ENV_EMITTED = "__CIMPLIFY_RESULT_EMITTED";
302
+ function result(data) {
303
+ if (!isJsonMode()) return;
304
+ if (process.env[ENV_EMITTED] === "1") return;
305
+ process.env[ENV_EMITTED] = "1";
306
+ process.stdout.write(`${JSON.stringify({ ok: true, data })}
307
+ `);
308
+ }
309
+ var REPO_PROVIDER = {
310
+ FREESTYLE: "freestyle",
311
+ GITHUB: "github",
312
+ GITEA: "gitea",
313
+ EXTERNAL: "external"
314
+ };
315
+ new Set(Object.values(REPO_PROVIDER));
255
316
 
256
317
  // src/cli/commands/projects.ts
257
318
  var SUB_LS = "ls";
258
319
  var SUB_LIST = "list";
259
320
  var SUB_CREATE = "create";
321
+ var FLAG_NO_REPO = "no-repo";
322
+ var FLAG_CONNECT = "connect";
260
323
  var PROJECT_TYPE_DEFAULT = "nextjs-app";
261
324
  var COL_GAP = " ";
262
325
  function projectsEndpoint(businessId) {
263
326
  return `/v1/businesses/${encodeURIComponent(businessId)}/projects`;
264
327
  }
328
+ function provisionRepoEndpoint(businessId, projectId) {
329
+ return `/v1/businesses/${encodeURIComponent(businessId)}/projects/${encodeURIComponent(projectId)}/repo/provision`;
330
+ }
331
+ function connectRepoEndpoint(businessId, projectId) {
332
+ return `/v1/businesses/${encodeURIComponent(businessId)}/projects/${encodeURIComponent(projectId)}/repo/connect`;
333
+ }
334
+ function detectProviderFromUrl(url) {
335
+ try {
336
+ const parsed = new URL(url);
337
+ if (parsed.hostname === "git.freestyle.sh") return REPO_PROVIDER.FREESTYLE;
338
+ if (parsed.hostname === "github.com" || parsed.hostname.endsWith(".github.com")) {
339
+ return REPO_PROVIDER.GITHUB;
340
+ }
341
+ if (parsed.hostname.includes("gitea")) return REPO_PROVIDER.GITEA;
342
+ } catch {
343
+ }
344
+ return REPO_PROVIDER.EXTERNAL;
345
+ }
265
346
  async function run(argv) {
266
347
  const args = parseArgs(argv);
267
348
  const sub = args.positional[0];
@@ -282,10 +363,13 @@ async function run(argv) {
282
363
  if (!name) {
283
364
  throw new CliError(
284
365
  CLI_ERROR_CODE.INVALID_INPUT,
285
- `Usage: cimplify projects ${SUB_CREATE} <name>`
366
+ `Usage: cimplify projects ${SUB_CREATE} <name> [--no-repo | --connect <url>]`
286
367
  );
287
368
  }
288
- await createProject(client, auth.businessId, name);
369
+ await createProject(client, auth.businessId, name, {
370
+ noRepo: flagBool(args, FLAG_NO_REPO),
371
+ connectRemote: flagString(args, FLAG_CONNECT)
372
+ });
289
373
  return;
290
374
  }
291
375
  throw new CliError(CLI_ERROR_CODE.INVALID_INPUT, `Unknown subcommand "${sub}"`);
@@ -294,6 +378,7 @@ async function listProjects(client, businessId) {
294
378
  const projects = await client.get(projectsEndpoint(businessId));
295
379
  if (projects.length === 0) {
296
380
  info(dim("No projects yet. Create one: `cimplify projects create <name>`"));
381
+ result({ projects: [] });
297
382
  return;
298
383
  }
299
384
  const idWidth = Math.max(...projects.map((p) => p.id.length));
@@ -316,12 +401,73 @@ async function listProjects(client, businessId) {
316
401
  ].join(COL_GAP)
317
402
  );
318
403
  }
404
+ result({
405
+ projects: projects.map((p) => ({
406
+ id: p.id,
407
+ name: p.name,
408
+ project_type: p.project_type ?? null
409
+ }))
410
+ });
319
411
  }
320
- async function createProject(client, businessId, name) {
412
+ async function createProject(client, businessId, name, options = {}) {
413
+ if (options.noRepo && options.connectRemote) {
414
+ throw new CliError(
415
+ CLI_ERROR_CODE.INVALID_INPUT,
416
+ "Cannot pass both --no-repo and --connect."
417
+ );
418
+ }
321
419
  const body = { name, project_type: PROJECT_TYPE_DEFAULT };
322
420
  const project = await client.post(projectsEndpoint(businessId), body);
323
421
  success(`Created project ${project.name} (${project.id})`);
324
- info(dim(`Link it: cimplify link ${project.id}`));
422
+ if (options.noRepo) {
423
+ info(dim("Skipped repo provisioning (--no-repo). Use `cimplify repo provision` later."));
424
+ info(dim(`Link locally: cimplify link ${project.id}`));
425
+ result({
426
+ project: { id: project.id, name: project.name },
427
+ repo: null
428
+ });
429
+ return;
430
+ }
431
+ if (options.connectRemote) {
432
+ const provider = detectProviderFromUrl(options.connectRemote);
433
+ if (provider === REPO_PROVIDER.FREESTYLE) {
434
+ throw new CliError(
435
+ CLI_ERROR_CODE.INVALID_INPUT,
436
+ "Cannot connect a Freestyle URL \u2014 Freestyle repos are provisioned, not connected."
437
+ );
438
+ }
439
+ const repoBody = {
440
+ provider,
441
+ remote_url: options.connectRemote
442
+ };
443
+ const repo2 = await client.post(
444
+ connectRepoEndpoint(businessId, project.id),
445
+ repoBody
446
+ );
447
+ success(`Connected ${repo2.provider} remote ${repo2.remote_url}`);
448
+ info(dim(`Link locally: cimplify link ${project.id}`));
449
+ result({
450
+ project: { id: project.id, name: project.name },
451
+ repo: { provider: repo2.provider, id: repo2.id, remote_url: repo2.remote_url, default_branch: repo2.default_branch }
452
+ });
453
+ return;
454
+ }
455
+ const repo = await client.post(
456
+ provisionRepoEndpoint(businessId, project.id),
457
+ {}
458
+ );
459
+ success(`Provisioned ${repo.provider} repo`);
460
+ info(dim(` remote: ${repo.remote_url}`));
461
+ info("");
462
+ info(dim("Wire your local repo:"));
463
+ info(dim(` cimplify link ${project.id}`));
464
+ info(dim(` git init && git remote add origin ${repo.remote_url}`));
465
+ info(dim(` git add . && git commit -m "Initial commit"`));
466
+ info(dim(` cimplify deploy`));
467
+ result({
468
+ project: { id: project.id, name: project.name },
469
+ repo: { provider: repo.provider, id: repo.id, remote_url: repo.remote_url, default_branch: repo.default_branch }
470
+ });
325
471
  }
326
472
 
327
- export { run as default };
473
+ export { run as default, detectProviderFromUrl };