@dk/jolly 0.1.5 → 0.1.7

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/bun.lock CHANGED
@@ -5,7 +5,7 @@
5
5
  "": {
6
6
  "name": "@saleor/jolly",
7
7
  "dependencies": {
8
- "dotenv": "^17.4.0",
8
+ "@dotenvx/dotenvx": "^1.59.1",
9
9
  "yargs": "^17.7.2",
10
10
  },
11
11
  "devDependencies": {
@@ -16,6 +16,16 @@
16
16
  },
17
17
  },
18
18
  "packages": {
19
+ "@dotenvx/dotenvx": ["@dotenvx/dotenvx@1.59.1", "", { "dependencies": { "commander": "^11.1.0", "dotenv": "^17.2.1", "eciesjs": "^0.4.10", "execa": "^5.1.1", "fdir": "^6.2.0", "ignore": "^5.3.0", "object-treeify": "1.1.33", "picomatch": "^4.0.2", "which": "^4.0.0" }, "bin": { "dotenvx": "src/cli/dotenvx.js" } }, "sha512-Qg+meC+XFxliuVSDlEPkKnaUjdaJKK6FNx/Wwl2UxhQR8pyPIuLhMavsF7ePdB9qFZUWV1jEK3ckbJir/WmF4w=="],
20
+
21
+ "@ecies/ciphers": ["@ecies/ciphers@0.2.6", "", { "peerDependencies": { "@noble/ciphers": "^1.0.0" } }, "sha512-patgsRPKGkhhoBjETV4XxD0En4ui5fbX0hzayqI3M8tvNMGUoUvmyYAIWwlxBc1KX5cturfqByYdj5bYGRpN9g=="],
22
+
23
+ "@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
24
+
25
+ "@noble/curves": ["@noble/curves@1.9.7", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-gbKGcRUYIjA3/zCCNaWDciTMFI0dCkvou3TL8Zmy5Nc7sJ47a0jtOeZoTaMxkuqRo9cRhjOdZJXegxYE5FN/xw=="],
26
+
27
+ "@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
28
+
19
29
  "@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
20
30
 
21
31
  "@types/yargs": ["@types/yargs@17.0.35", "", { "dependencies": { "@types/yargs-parser": "*" } }, "sha512-qUHkeCyQFxMXg79wQfTtfndEC+N9ZZg76HJftDJp+qH2tV7Gj4OJi7l+PiWwJ+pWtW8GwSmqsDj/oymhrTWXjg=="],
@@ -34,26 +44,70 @@
34
44
 
35
45
  "color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
36
46
 
47
+ "commander": ["commander@11.1.0", "", {}, "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ=="],
48
+
49
+ "cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
50
+
37
51
  "dotenv": ["dotenv@17.4.0", "", {}, "sha512-kCKF62fwtzwYm0IGBNjRUjtJgMfGapII+FslMHIjMR5KTnwEmBmWLDRSnc3XSNP8bNy34tekgQyDT0hr7pERRQ=="],
38
52
 
53
+ "eciesjs": ["eciesjs@0.4.18", "", { "dependencies": { "@ecies/ciphers": "^0.2.5", "@noble/ciphers": "^1.3.0", "@noble/curves": "^1.9.7", "@noble/hashes": "^1.8.0" } }, "sha512-wG99Zcfcys9fZux7Cft8BAX/YrOJLJSZ3jyYPfhZHqN2E+Ffx+QXBDsv3gubEgPtV6dTzJMSQUwk1H98/t/0wQ=="],
54
+
39
55
  "emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
40
56
 
41
57
  "escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
42
58
 
59
+ "execa": ["execa@5.1.1", "", { "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", "human-signals": "^2.1.0", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.1", "onetime": "^5.1.2", "signal-exit": "^3.0.3", "strip-final-newline": "^2.0.0" } }, "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg=="],
60
+
61
+ "fdir": ["fdir@6.5.0", "", { "peerDependencies": { "picomatch": "^3 || ^4" }, "optionalPeers": ["picomatch"] }, "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg=="],
62
+
43
63
  "get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
44
64
 
65
+ "get-stream": ["get-stream@6.0.1", "", {}, "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="],
66
+
67
+ "human-signals": ["human-signals@2.1.0", "", {}, "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="],
68
+
69
+ "ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
70
+
45
71
  "is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
46
72
 
73
+ "is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
74
+
75
+ "isexe": ["isexe@3.1.5", "", {}, "sha512-6B3tLtFqtQS4ekarvLVMZ+X+VlvQekbe4taUkf/rhVO3d/h0M2rfARm/pXLcPEsjjMsFgrFgSrhQIxcSVrBz8w=="],
76
+
77
+ "merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
78
+
79
+ "mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
80
+
81
+ "npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
82
+
83
+ "object-treeify": ["object-treeify@1.1.33", "", {}, "sha512-EFVjAYfzWqWsBMRHPMAXLCDIJnpMhdWAqR7xG6M6a2cs6PMFpl/+Z20w9zDW4vkxOFfddegBKq9Rehd0bxWE7A=="],
84
+
85
+ "onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
86
+
87
+ "path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
88
+
89
+ "picomatch": ["picomatch@4.0.4", "", {}, "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A=="],
90
+
47
91
  "require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
48
92
 
93
+ "shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
94
+
95
+ "shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
96
+
97
+ "signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
98
+
49
99
  "string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
50
100
 
51
101
  "strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
52
102
 
103
+ "strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
104
+
53
105
  "typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
54
106
 
55
107
  "undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
56
108
 
109
+ "which": ["which@4.0.0", "", { "dependencies": { "isexe": "^3.1.1" }, "bin": { "node-which": "bin/which.js" } }, "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg=="],
110
+
57
111
  "wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
58
112
 
59
113
  "y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
@@ -61,5 +115,9 @@
61
115
  "yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
62
116
 
63
117
  "yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
118
+
119
+ "cross-spawn/which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
120
+
121
+ "cross-spawn/which/isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
64
122
  }
65
123
  }
package/dist/bootstrap.js CHANGED
@@ -11,47 +11,70 @@ class SaleorCloudClient {
11
11
  }
12
12
  }
13
13
  async request(endpoint, options) {
14
- const response = await fetch(`${this.baseUrl}${endpoint}`, {
14
+ const mergedOptions = {
15
+ method: options?.method || "GET",
15
16
  ...options,
16
17
  headers: {
17
- Authorization: `Bearer ${this.token}`,
18
+ Authorization: `Token ${this.token}`,
18
19
  "Content-Type": "application/json",
19
20
  ...options?.headers
20
21
  }
21
- });
22
+ };
23
+ const response = await fetch(`${this.baseUrl}${endpoint}`, mergedOptions);
22
24
  if (!response.ok) {
23
- throw new Error(`API error: ${response.status} ${response.statusText}`);
25
+ const body = await response.text();
26
+ throw new Error(`API error: ${response.status} ${response.statusText} - ${body}`);
24
27
  }
25
28
  return response.json();
26
29
  }
27
- async getStores() {
28
- return this.request("/stores");
30
+ async getOrganizations() {
31
+ return this.request("/organizations");
29
32
  }
30
- async createStore(name, region = "us-east-1") {
31
- return this.request("/stores", {
33
+ async getProjects(organizationSlug) {
34
+ return this.request(`/organizations/${organizationSlug}/projects`);
35
+ }
36
+ async createProject(organizationSlug, name, region) {
37
+ return this.request(`/organizations/${organizationSlug}/projects`, {
32
38
  method: "POST",
33
39
  body: JSON.stringify({ name, region })
34
40
  });
35
41
  }
36
- async getEnvironments(storeId) {
37
- return this.request(`/stores/${storeId}/environments`);
42
+ async getEnvironments(organizationSlug, projectSlug) {
43
+ return this.request(`/organizations/${organizationSlug}/projects/${projectSlug}/environments`);
38
44
  }
39
- async createEnvironment(storeId, name) {
40
- return this.request(`/stores/${storeId}/environments`, {
45
+ async createEnvironment(organizationSlug, projectSlug, name, region) {
46
+ return this.request(`/organizations/${organizationSlug}/projects/${projectSlug}/environments`, {
41
47
  method: "POST",
42
- body: JSON.stringify({ name })
48
+ body: JSON.stringify({ name, region })
43
49
  });
44
50
  }
51
+ async getEnvironment(organizationSlug, projectSlug, environmentSlug) {
52
+ return this.request(`/organizations/${organizationSlug}/projects/${projectSlug}/environments/${environmentSlug}`);
53
+ }
45
54
  async registerApp(environmentId, appType, name) {
46
55
  return this.request(`/environments/${environmentId}/apps`, {
47
56
  method: "POST",
48
57
  body: JSON.stringify({ type: appType, name })
49
58
  });
50
59
  }
60
+ async getStores() {
61
+ return this.getOrganizations();
62
+ }
63
+ async createStore(name, region = "us-east-1") {
64
+ const { organizations } = await this.getOrganizations();
65
+ if (organizations.length === 0) {
66
+ throw new Error("No organizations found. Create one at https://cloud.saleor.io");
67
+ }
68
+ return this.createProject(organizations[0].slug, name, region);
69
+ }
70
+ async createEnvironmentFromStore(storeId, name) {
71
+ const { environments } = await this.getEnvironments(storeId, "default");
72
+ return this.createEnvironment(storeId, environments.length > 0 ? environments[0].project?.slug || "default" : "default", name, "default");
73
+ }
51
74
  }
52
75
 
53
76
  // src/api/auth.ts
54
- import { config } from "dotenv";
77
+ import { config } from "@dotenvx/dotenvx";
55
78
  config();
56
79
  function requireToken() {
57
80
  const token = process.env.SALEOR_CLOUD_TOKEN;
@@ -125,14 +148,14 @@ function info(msg) {
125
148
  async function createStore(name, region) {
126
149
  const token = requireToken();
127
150
  const client = new SaleorCloudClient(token);
128
- info(`Creating store: ${name} in ${region}...`);
151
+ console.log(info(`Creating store: ${name} in ${region}...`));
129
152
  try {
130
153
  const result = await client.createStore(name, region);
131
- success(`Store created successfully!`);
132
- info(`Store ID: ${result.store.id}`);
133
- info(`Dashboard: https://cloud.saleor.io/stores/${result.store.id}`);
154
+ console.log(success(`Store created successfully!`));
155
+ console.log(info(`Project slug: ${result.project.slug}`));
156
+ console.log(info(`Dashboard: https://cloud.saleor.io/organizations/default/projects/${result.project.slug}`));
134
157
  } catch (err) {
135
- error(`Failed to create store: ${err}`);
158
+ console.log(error(`Failed to create store: ${err}`));
136
159
  process.exit(1);
137
160
  }
138
161
  }
package/dist/index.js CHANGED
@@ -33,47 +33,70 @@ class SaleorCloudClient {
33
33
  }
34
34
  }
35
35
  async request(endpoint, options) {
36
- const response = await fetch(`${this.baseUrl}${endpoint}`, {
36
+ const mergedOptions = {
37
+ method: options?.method || "GET",
37
38
  ...options,
38
39
  headers: {
39
- Authorization: `Bearer ${this.token}`,
40
+ Authorization: `Token ${this.token}`,
40
41
  "Content-Type": "application/json",
41
42
  ...options?.headers
42
43
  }
43
- });
44
+ };
45
+ const response = await fetch(`${this.baseUrl}${endpoint}`, mergedOptions);
44
46
  if (!response.ok) {
45
- throw new Error(`API error: ${response.status} ${response.statusText}`);
47
+ const body = await response.text();
48
+ throw new Error(`API error: ${response.status} ${response.statusText} - ${body}`);
46
49
  }
47
50
  return response.json();
48
51
  }
49
- async getStores() {
50
- return this.request("/stores");
52
+ async getOrganizations() {
53
+ return this.request("/organizations");
51
54
  }
52
- async createStore(name, region = "us-east-1") {
53
- return this.request("/stores", {
55
+ async getProjects(organizationSlug) {
56
+ return this.request(`/organizations/${organizationSlug}/projects`);
57
+ }
58
+ async createProject(organizationSlug, name, region) {
59
+ return this.request(`/organizations/${organizationSlug}/projects`, {
54
60
  method: "POST",
55
61
  body: JSON.stringify({ name, region })
56
62
  });
57
63
  }
58
- async getEnvironments(storeId) {
59
- return this.request(`/stores/${storeId}/environments`);
64
+ async getEnvironments(organizationSlug, projectSlug) {
65
+ return this.request(`/organizations/${organizationSlug}/projects/${projectSlug}/environments`);
60
66
  }
61
- async createEnvironment(storeId, name) {
62
- return this.request(`/stores/${storeId}/environments`, {
67
+ async createEnvironment(organizationSlug, projectSlug, name, region) {
68
+ return this.request(`/organizations/${organizationSlug}/projects/${projectSlug}/environments`, {
63
69
  method: "POST",
64
- body: JSON.stringify({ name })
70
+ body: JSON.stringify({ name, region })
65
71
  });
66
72
  }
73
+ async getEnvironment(organizationSlug, projectSlug, environmentSlug) {
74
+ return this.request(`/organizations/${organizationSlug}/projects/${projectSlug}/environments/${environmentSlug}`);
75
+ }
67
76
  async registerApp(environmentId, appType, name) {
68
77
  return this.request(`/environments/${environmentId}/apps`, {
69
78
  method: "POST",
70
79
  body: JSON.stringify({ type: appType, name })
71
80
  });
72
81
  }
82
+ async getStores() {
83
+ return this.getOrganizations();
84
+ }
85
+ async createStore(name, region = "us-east-1") {
86
+ const { organizations } = await this.getOrganizations();
87
+ if (organizations.length === 0) {
88
+ throw new Error("No organizations found. Create one at https://cloud.saleor.io");
89
+ }
90
+ return this.createProject(organizations[0].slug, name, region);
91
+ }
92
+ async createEnvironmentFromStore(storeId, name) {
93
+ const { environments } = await this.getEnvironments(storeId, "default");
94
+ return this.createEnvironment(storeId, environments.length > 0 ? environments[0].project?.slug || "default" : "default", name, "default");
95
+ }
73
96
  }
74
97
 
75
98
  // src/api/auth.ts
76
- import { config } from "dotenv";
99
+ import { config } from "@dotenvx/dotenvx";
77
100
  import { writeFileSync, existsSync, readFileSync } from "fs";
78
101
  import { join } from "path";
79
102
  config();
@@ -194,51 +217,51 @@ function info(msg) {
194
217
  async function createStore(name, region) {
195
218
  const token = requireToken();
196
219
  const client = new SaleorCloudClient(token);
197
- info(`Creating store: ${name} in ${region}...`);
220
+ console.log(info(`Creating store: ${name} in ${region}...`));
198
221
  try {
199
222
  const result = await client.createStore(name, region);
200
- success(`Store created successfully!`);
201
- info(`Store ID: ${result.store.id}`);
202
- info(`Dashboard: https://cloud.saleor.io/stores/${result.store.id}`);
223
+ console.log(success(`Store created successfully!`));
224
+ console.log(info(`Project slug: ${result.project.slug}`));
225
+ console.log(info(`Dashboard: https://cloud.saleor.io/organizations/default/projects/${result.project.slug}`));
203
226
  } catch (err) {
204
- error(`Failed to create store: ${err}`);
227
+ console.log(error(`Failed to create store: ${err}`));
205
228
  process.exit(1);
206
229
  }
207
230
  }
208
231
  async function listStores() {
209
232
  const token = requireToken();
210
233
  const client = new SaleorCloudClient(token);
211
- info("Fetching stores...");
234
+ console.log(info("Fetching organizations..."));
212
235
  try {
213
- const result = await client.getStores();
214
- if (result.stores.length === 0) {
215
- info("No stores found. Create one with: jolly store create --name <name>");
236
+ const { organizations } = await client.getOrganizations();
237
+ if (organizations.length === 0) {
238
+ console.log(info("No organizations found. Create one at https://cloud.saleor.io"));
216
239
  return;
217
240
  }
218
- success(`Found ${result.stores.length} store(s):
219
- `);
220
- for (const store of result.stores) {
221
- console.log(` ${store.name} (${store.id})`);
222
- console.log(` Region: ${store.region}`);
223
- console.log(` Created: ${new Date(store.created_at).toLocaleDateString()}`);
241
+ console.log(success(`Found ${organizations.length} organization(s):
242
+ `));
243
+ for (const org of organizations) {
244
+ console.log(` ${org.name} (${org.slug})`);
245
+ console.log(` Email: ${org.owner_email}`);
246
+ console.log(` Created: ${new Date(org.created).toLocaleDateString()}`);
224
247
  console.log();
225
248
  }
226
249
  } catch (err) {
227
- error(`Failed to list stores: ${err}`);
250
+ console.log(error(`Failed to list stores: ${err}`));
228
251
  process.exit(1);
229
252
  }
230
253
  }
231
- async function createEnvironment(storeId, name) {
254
+ async function createEnvironment(organizationSlug, name) {
232
255
  const token = requireToken();
233
256
  const client = new SaleorCloudClient(token);
234
- info(`Creating environment: ${name} for store ${storeId}...`);
257
+ console.log(info(`Creating environment: ${name} for organization ${organizationSlug}...`));
235
258
  try {
236
- const result = await client.createEnvironment(storeId, name);
237
- success(`Environment created successfully!`);
238
- info(`Environment ID: ${result.environment.id}`);
239
- info(`API URL will be available at: https://${result.environment.id}.saleor.cloud`);
259
+ const { environment } = await client.createEnvironment(organizationSlug, "default", name, "us-east-1");
260
+ console.log(success(`Environment created successfully!`));
261
+ console.log(info(`Environment key: ${environment.key}`));
262
+ console.log(info(`Domain: ${environment.domain}`));
240
263
  } catch (err) {
241
- error(`Failed to create environment: ${err}`);
264
+ console.log(error(`Failed to create environment: ${err}`));
242
265
  process.exit(1);
243
266
  }
244
267
  }
@@ -323,26 +346,26 @@ var PAYMENT_APP_URLS = {
323
346
  stripe: "https://stripe-payment.saleor.io"
324
347
  };
325
348
  async function createApp(name, type, environmentId, provider) {
326
- info(`Creating ${type} app: ${name}`);
349
+ console.log(info(`Creating ${type} app: ${name}`));
327
350
  if (type === "payment") {
328
351
  const paymentProvider = provider || "dummy";
329
- info(`Payment provider: ${paymentProvider}`);
330
- info(`Using hosted payment app: ${PAYMENT_APP_URLS[paymentProvider]}`);
352
+ console.log(info(`Payment provider: ${paymentProvider}`));
353
+ console.log(info(`Using hosted payment app: ${PAYMENT_APP_URLS[paymentProvider]}`));
331
354
  if (environmentId) {
332
355
  await registerHostedApp(environmentId, name, paymentProvider);
333
356
  } else {
334
- success(`
335
- Payment app "${name}" configured to use ${PAYMENT_APP_URLS[paymentProvider]}`);
336
- info(`
337
- To complete setup:`);
338
- info(`1. Go to your dashboard at https://cloud.saleor.io`);
339
- info(`2. Navigate to Apps > Third party apps`);
340
- info(`3. Add the ${paymentProvider} payment app from ${PAYMENT_APP_URLS[paymentProvider]}`);
357
+ console.log(success(`
358
+ Payment app "${name}" configured to use ${PAYMENT_APP_URLS[paymentProvider]}`));
359
+ console.log(info(`
360
+ To complete setup:`));
361
+ console.log(info(`1. Go to your dashboard at https://cloud.saleor.io`));
362
+ console.log(info(`2. Navigate to Apps > Third party apps`));
363
+ console.log(info(`3. Add the ${paymentProvider} payment app from ${PAYMENT_APP_URLS[paymentProvider]}`));
341
364
  }
342
365
  return;
343
366
  }
344
367
  const template = APP_TEMPLATES[type];
345
- info(`Cloning template from: ${template.repo}`);
368
+ console.log(info(`Cloning template from: ${template.repo}`));
346
369
  try {
347
370
  const { spawn } = await import("child_process");
348
371
  const child = spawn("git", ["clone", template.repo, name], {
@@ -350,39 +373,39 @@ To complete setup:`);
350
373
  });
351
374
  child.on("close", (code) => {
352
375
  if (code === 0) {
353
- success(`
354
- ${type} app "${name}" created successfully!`);
355
- info(`
356
- To get started:`);
357
- info(`cd ${name}`);
358
- info(`npm install`);
359
- info(`npm run dev`);
376
+ console.log(success(`
377
+ ${type} app "${name}" created successfully!`));
378
+ console.log(info(`
379
+ To get started:`));
380
+ console.log(info(`cd ${name}`));
381
+ console.log(info(`npm install`));
382
+ console.log(info(`npm run dev`));
360
383
  if (environmentId) {
361
- info(`
362
- Registering app with environment ${environmentId}...`);
384
+ console.log(info(`
385
+ Registering app with environment ${environmentId}...`));
363
386
  registerLocalApp(environmentId, name, type);
364
387
  }
365
388
  } else {
366
- error(`Failed to clone template (exit code: ${code})`);
389
+ console.log(error(`Failed to clone template (exit code: ${code})`));
367
390
  process.exit(1);
368
391
  }
369
392
  });
370
393
  } catch (err) {
371
- error(`Failed to create app: ${err}`);
394
+ console.log(error(`Failed to create app: ${err}`));
372
395
  process.exit(1);
373
396
  }
374
397
  }
375
398
  async function registerHostedApp(environmentId, name, provider) {
376
399
  const token = requireToken();
377
400
  const client = new SaleorCloudClient(token);
378
- info(`Registering hosted ${provider} payment app with environment...`);
401
+ console.log(info(`Registering hosted ${provider} payment app with environment...`));
379
402
  try {
380
403
  const result = await client.registerApp(environmentId, "payment", name);
381
- success(`Payment app registered successfully!`);
382
- info(`App ID: ${result.app.id}`);
383
- info(`Payment URL: ${PAYMENT_APP_URLS[provider]}`);
404
+ console.log(success(`Payment app registered successfully!`));
405
+ console.log(info(`App ID: ${result.app.id}`));
406
+ console.log(info(`Payment URL: ${PAYMENT_APP_URLS[provider]}`));
384
407
  } catch (err) {
385
- error(`Failed to register app: ${err}`);
408
+ console.log(error(`Failed to register app: ${err}`));
386
409
  process.exit(1);
387
410
  }
388
411
  }
@@ -391,11 +414,11 @@ async function registerLocalApp(environmentId, name, type) {
391
414
  const client = new SaleorCloudClient(token);
392
415
  try {
393
416
  const result = await client.registerApp(environmentId, type, name);
394
- success(`App registered with environment!`);
395
- info(`App ID: ${result.app.id}`);
417
+ console.log(success(`App registered with environment!`));
418
+ console.log(info(`App ID: ${result.app.id}`));
396
419
  } catch (err) {
397
- warning(`Could not register app automatically: ${err}`);
398
- info(`You can register manually in the dashboard.`);
420
+ console.log(warning(`Could not register app automatically: ${err}`));
421
+ console.log(info(`You can register manually in the dashboard.`));
399
422
  }
400
423
  }
401
424
  function warning(msg) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dk/jolly",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Saleor project bootstrapper and agent configurator",
5
5
  "type": "module",
6
6
  "bin": {
@@ -9,18 +9,18 @@
9
9
  "init-jolly": "./dist/agent.js"
10
10
  },
11
11
  "scripts": {
12
- "build": "bun build src/cli/index.ts --outdir=dist --target=node --external yargs --external dotenv && bun build src/cli/bootstrap.ts --outdir=dist --target=node --external yargs --external dotenv && bun build src/cli/agent.ts --outdir=dist --target=node --external yargs --external dotenv",
12
+ "build": "bun build src/cli/index.ts --outdir=dist --target=node --external yargs --external @dotenvx/dotenvx && bun build src/cli/bootstrap.ts --outdir=dist --target=node --external yargs --external @dotenvx/dotenvx && bun build src/cli/agent.ts --outdir=dist --target=node --external yargs --external @dotenvx/dotenvx",
13
13
  "prepublishOnly": "bun run build",
14
14
  "jolly": "bun src/cli/index.ts",
15
15
  "dev": "bun --watch src/cli/index.ts",
16
16
  "test": "bun test",
17
17
  "typecheck": "bun tsc --noEmit",
18
- "release": "npm version patch && npm publish",
19
- "release:minor": "npm version minor && npm publish",
20
- "release:major": "npm version major && npm publish"
18
+ "release": "npm version patch --no-git-tag-version && npm publish",
19
+ "release:minor": "npm version minor --no-git-tag-version && npm publish",
20
+ "release:major": "npm version major --no-git-tag-version && npm publish"
21
21
  },
22
22
  "dependencies": {
23
- "dotenv": "^17.4.0",
23
+ "@dotenvx/dotenvx": "^1.59.1",
24
24
  "yargs": "^17.7.2"
25
25
  },
26
26
  "devDependencies": {
package/src/api/auth.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { config } from 'dotenv';
1
+ import { config } from '@dotenvx/dotenvx';
2
2
  import { writeFileSync, existsSync, readFileSync } from 'fs';
3
3
  import { join } from 'path';
4
4