@cimplify/sdk 0.44.21 → 0.44.22

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.
@@ -6,6 +6,7 @@ import readline from 'readline';
6
6
  // src/cli/errors.ts
7
7
  var CLI_ERROR_CODE = {
8
8
  NOT_LOGGED_IN: "NOT_LOGGED_IN",
9
+ NOT_LINKED: "NOT_LINKED",
9
10
  NETWORK_ERROR: "NETWORK_ERROR",
10
11
  AUTH_FAILED: "AUTH_FAILED",
11
12
  PROJECT_NOT_FOUND: "PROJECT_NOT_FOUND",
@@ -206,6 +207,8 @@ function flagBool(args, name) {
206
207
  return args.flags.has(name);
207
208
  }
208
209
  var AUTH_FILE_NAME = "auth.json";
210
+ var PROJECT_FILE_NAME = "project.json";
211
+ var PROJECT_DIR_NAME = ".cimplify";
209
212
  var ENV_XDG_CONFIG_HOME = "XDG_CONFIG_HOME";
210
213
  var APP_CONFIG_DIR_NAME = "cimplify";
211
214
  var HOME_CONFIG_DIR_NAME = ".config";
@@ -217,6 +220,12 @@ function authConfigDir() {
217
220
  function authConfigPath() {
218
221
  return path.join(authConfigDir(), AUTH_FILE_NAME);
219
222
  }
223
+ function projectConfigDir(cwd = process.cwd()) {
224
+ return path.join(cwd, PROJECT_DIR_NAME);
225
+ }
226
+ function projectConfigPath(cwd = process.cwd()) {
227
+ return path.join(projectConfigDir(cwd), PROJECT_FILE_NAME);
228
+ }
220
229
  async function readJsonFile(filePath) {
221
230
  try {
222
231
  const raw = await promises.readFile(filePath, ENCODING_UTF8);
@@ -236,6 +245,16 @@ async function readAuth() {
236
245
  }
237
246
  return data;
238
247
  }
248
+ async function readProjectLink(cwd = process.cwd()) {
249
+ const data = await readJsonFile(projectConfigPath(cwd));
250
+ if (!data) {
251
+ throw new CliError(
252
+ CLI_ERROR_CODE.NOT_LINKED,
253
+ "No project linked. Run `cimplify link <project-id>` first."
254
+ );
255
+ }
256
+ return data;
257
+ }
239
258
 
240
259
  // src/cli/output.ts
241
260
  var RESET = "\x1B[0m";
@@ -277,6 +296,14 @@ async function promptYesNo(question, defaultNo = true) {
277
296
  if (answer === "") return !defaultNo;
278
297
  return answer === "y" || answer === "yes";
279
298
  }
299
+
300
+ // src/cli/types.ts
301
+ var ENV_SCOPE = {
302
+ DEVELOPMENT: "development",
303
+ PREVIEW: "preview",
304
+ STAGING: "staging",
305
+ PRODUCTION: "production"
306
+ };
280
307
  var DOMAIN_TYPE = {
281
308
  CUSTOM: "custom",
282
309
  CIMPLIFY: "cimplify"
@@ -289,8 +316,34 @@ var SUB_ADD = "add";
289
316
  var SUB_VERIFY = "verify";
290
317
  var SUB_RM = "rm";
291
318
  var SUB_REMOVE = "remove";
319
+ var SUB_ATTACH = "attach";
320
+ var SUB_DETACH = "detach";
321
+ var SUB_PRIMARY = "primary";
292
322
  var FLAG_TYPE = "type";
293
323
  var FLAG_YES = "yes";
324
+ var FLAG_ENV = "env";
325
+ var FLAG_PRIMARY = "primary";
326
+ var FLAG_ATTACHED = "attached";
327
+ var ENV_SCOPE_VALUES = new Set(Object.values(ENV_SCOPE));
328
+ function resolveEnvScope(value, fallback = ENV_SCOPE.PRODUCTION) {
329
+ if (value === void 0) return fallback;
330
+ if (!ENV_SCOPE_VALUES.has(value)) {
331
+ throw new CliError(
332
+ CLI_ERROR_CODE.INVALID_INPUT,
333
+ `Invalid env "${value}". Choose: ${[...ENV_SCOPE_VALUES].join(", ")}.`
334
+ );
335
+ }
336
+ return value;
337
+ }
338
+ function projectDomainsEndpoint(businessId, projectId) {
339
+ return `/v1/businesses/${encodeURIComponent(businessId)}/projects/${encodeURIComponent(projectId)}/domains`;
340
+ }
341
+ function projectDomainItemEndpoint(businessId, projectId, attachmentId) {
342
+ return `${projectDomainsEndpoint(businessId, projectId)}/${encodeURIComponent(attachmentId)}`;
343
+ }
344
+ function projectDomainPrimaryEndpoint(businessId, projectId, attachmentId) {
345
+ return `${projectDomainItemEndpoint(businessId, projectId, attachmentId)}/primary`;
346
+ }
294
347
  var COL_GAP = " ";
295
348
  var COL_DOMAIN = "DOMAIN";
296
349
  var COL_TYPE = "TYPE";
@@ -329,13 +382,17 @@ async function run(argv) {
329
382
  if (!sub) {
330
383
  throw new CliError(
331
384
  CLI_ERROR_CODE.INVALID_INPUT,
332
- `Usage: cimplify domains <${SUB_LS}|${SUB_ADD}|${SUB_VERIFY}|${SUB_RM}>`
385
+ `Usage: cimplify domains <${SUB_LS}|${SUB_ADD}|${SUB_VERIFY}|${SUB_RM}|${SUB_ATTACH}|${SUB_DETACH}|${SUB_PRIMARY}>`
333
386
  );
334
387
  }
335
388
  const auth = await readAuth();
336
389
  const client = ApiClient.fromAuth(auth);
337
390
  if (sub === SUB_LS || sub === SUB_LIST) {
338
- await listDomains(client, auth.businessId);
391
+ if (flagBool(args, FLAG_ATTACHED)) {
392
+ await listAttachedForCurrentProject(client, auth.businessId);
393
+ } else {
394
+ await listDomains(client, auth.businessId);
395
+ }
339
396
  return;
340
397
  }
341
398
  if (sub === SUB_ADD) {
@@ -350,6 +407,18 @@ async function run(argv) {
350
407
  await removeDomain(client, auth.businessId, args);
351
408
  return;
352
409
  }
410
+ if (sub === SUB_ATTACH) {
411
+ await attachDomain(client, auth.businessId, args);
412
+ return;
413
+ }
414
+ if (sub === SUB_DETACH) {
415
+ await detachDomain(client, auth.businessId, args);
416
+ return;
417
+ }
418
+ if (sub === SUB_PRIMARY) {
419
+ await setPrimaryAttachment(client, auth.businessId, args);
420
+ return;
421
+ }
353
422
  throw new CliError(CLI_ERROR_CODE.INVALID_INPUT, `Unknown domains subcommand "${sub}"`);
354
423
  }
355
424
  async function listDomains(client, businessId) {
@@ -475,5 +544,110 @@ async function findDomain(client, businessId, domain) {
475
544
  }
476
545
  return match;
477
546
  }
547
+ async function attachDomain(client, businessId, args) {
548
+ const domain = args.positional[1];
549
+ if (!domain) {
550
+ throw new CliError(
551
+ CLI_ERROR_CODE.INVALID_INPUT,
552
+ `Usage: cimplify domains ${SUB_ATTACH} <domain> [--env=preview|production] [--primary]`
553
+ );
554
+ }
555
+ const link = await readProjectLink();
556
+ const target = await findDomain(client, businessId, domain);
557
+ if (!target.is_verified) {
558
+ throw new CliError(
559
+ CLI_ERROR_CODE.INVALID_INPUT,
560
+ `Domain "${domain}" is not verified. Run: cimplify domains verify ${domain}`
561
+ );
562
+ }
563
+ const envScope = resolveEnvScope(flagString(args, FLAG_ENV));
564
+ const isPrimary = flagBool(args, FLAG_PRIMARY);
565
+ const body = {
566
+ business_domain_id: target.id,
567
+ env_scope: envScope,
568
+ is_primary: isPrimary
569
+ };
570
+ await client.post(
571
+ projectDomainsEndpoint(businessId, link.projectId),
572
+ body
573
+ );
574
+ success(`Attached ${domain} to project for ${envScope}${isPrimary ? " (primary)" : ""}`);
575
+ info(dim("Next deploy will bind this domain. Run: cimplify deploy"));
576
+ }
577
+ async function detachDomain(client, businessId, args) {
578
+ const domain = args.positional[1];
579
+ if (!domain) {
580
+ throw new CliError(
581
+ CLI_ERROR_CODE.INVALID_INPUT,
582
+ `Usage: cimplify domains ${SUB_DETACH} <domain> [--env=preview|production] [--yes]`
583
+ );
584
+ }
585
+ const link = await readProjectLink();
586
+ const envScope = resolveEnvScope(flagString(args, FLAG_ENV));
587
+ const attachment = await findAttachmentForCurrentProject(client, businessId, link.projectId, domain, envScope);
588
+ if (!flagBool(args, FLAG_YES)) {
589
+ const confirmed = await promptYesNo(`Detach ${domain} from this project (${envScope})?`, true);
590
+ if (!confirmed) {
591
+ throw new CliError(CLI_ERROR_CODE.ABORTED, "Aborted by user.");
592
+ }
593
+ }
594
+ await client.delete(projectDomainItemEndpoint(businessId, link.projectId, attachment.id));
595
+ success(`Detached ${domain} (${envScope})`);
596
+ info(dim("Next deploy will not bind this domain. Existing deployments continue serving until redeploy."));
597
+ }
598
+ async function setPrimaryAttachment(client, businessId, args) {
599
+ const domain = args.positional[1];
600
+ if (!domain) {
601
+ throw new CliError(
602
+ CLI_ERROR_CODE.INVALID_INPUT,
603
+ `Usage: cimplify domains ${SUB_PRIMARY} <domain> [--env=preview|production]`
604
+ );
605
+ }
606
+ const link = await readProjectLink();
607
+ const envScope = resolveEnvScope(flagString(args, FLAG_ENV));
608
+ const attachment = await findAttachmentForCurrentProject(client, businessId, link.projectId, domain, envScope);
609
+ await client.post(
610
+ projectDomainPrimaryEndpoint(businessId, link.projectId, attachment.id)
611
+ );
612
+ success(`Set ${domain} as primary for ${envScope}`);
613
+ }
614
+ async function listAttachedForCurrentProject(client, businessId) {
615
+ const link = await readProjectLink();
616
+ const attachments = await client.get(
617
+ projectDomainsEndpoint(businessId, link.projectId)
618
+ );
619
+ if (attachments.length === 0) {
620
+ info(dim("No domains attached to this project. Attach one: cimplify domains attach <domain>"));
621
+ return;
622
+ }
623
+ const domains = await client.get(domainsEndpoint(businessId));
624
+ const domainById = new Map(domains.map((d) => [d.id, d]));
625
+ info(bold(["DOMAIN", "ENV", "PRIMARY", "ATTACHED"].join(COL_GAP)));
626
+ for (const a of attachments) {
627
+ const bd = domainById.get(a.business_domain_id);
628
+ info(
629
+ [
630
+ bd?.domain ?? `<unknown:${a.business_domain_id}>`,
631
+ String(a.env_scope),
632
+ a.is_primary ? "yes" : "no",
633
+ a.attached_at
634
+ ].join(COL_GAP)
635
+ );
636
+ }
637
+ }
638
+ async function findAttachmentForCurrentProject(client, businessId, projectId, domain, envScope) {
639
+ const target = await findDomain(client, businessId, domain);
640
+ const attachments = await client.get(projectDomainsEndpoint(businessId, projectId));
641
+ const match = attachments.find(
642
+ (a) => a.business_domain_id === target.id && a.env_scope === envScope
643
+ );
644
+ if (!match) {
645
+ throw new CliError(
646
+ CLI_ERROR_CODE.PROJECT_NOT_FOUND,
647
+ `${domain} is not attached to this project for env "${envScope}". List attached: cimplify domains ls --attached`
648
+ );
649
+ }
650
+ return match;
651
+ }
478
652
 
479
653
  export { run as default, printDnsRecords };
@@ -31,10 +31,16 @@ Env vars:
31
31
  bunx @cimplify/sdk env rm KEY [--yes] Remove an env var
32
32
 
33
33
  Domains:
34
- bunx @cimplify/sdk domains ls List business domains
35
- bunx @cimplify/sdk domains add <domain> Add a domain (prints DNS records to set)
36
- bunx @cimplify/sdk domains verify <dom> Trigger verification after DNS is configured
37
- bunx @cimplify/sdk domains rm <dom> Remove a domain
34
+ bunx @cimplify/sdk domains ls List business domains
35
+ bunx @cimplify/sdk domains ls --attached List domains attached to the linked project
36
+ bunx @cimplify/sdk domains add <domain> Add a domain (prints DNS records to set)
37
+ bunx @cimplify/sdk domains verify <dom> Trigger verification after DNS is configured
38
+ bunx @cimplify/sdk domains rm <dom> Remove a domain
39
+ bunx @cimplify/sdk domains attach <dom> [flags] Attach a verified domain to the linked project
40
+ flags: --env=preview|production --primary
41
+ bunx @cimplify/sdk domains detach <dom> [flags] Detach a domain from the linked project
42
+ flags: --env=preview|production --yes
43
+ bunx @cimplify/sdk domains primary <dom> [--env=...] Promote an attached domain to primary for its env
38
44
 
39
45
  Misc:
40
46
  bunx @cimplify/sdk --help, -h Show this help
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cimplify/sdk",
3
- "version": "0.44.21",
3
+ "version": "0.44.22",
4
4
  "description": "Cimplify Commerce SDK for storefronts",
5
5
  "keywords": [
6
6
  "cimplify",