@aigne/doc-smith 0.8.10-beta.2 → 0.8.10

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.
@@ -154,23 +154,120 @@ describe("deploy", () => {
154
154
  expect(saveValueToConfigSpy).toHaveBeenCalledWith(
155
155
  "checkoutId",
156
156
  "checkout-123",
157
- "Checkout ID for document deployment service",
157
+ "Checkout ID for document deployment website",
158
158
  );
159
159
  expect(saveValueToConfigSpy).toHaveBeenCalledWith(
160
160
  "paymentUrl",
161
161
  expect.stringContaining("payment"),
162
- "Payment URL for document deployment service",
162
+ "Payment URL for document deployment website",
163
163
  );
164
164
 
165
165
  // Verify console output shows progress
166
166
  const logs = consoleOutput.filter((o) => o.type === "log").map((o) => o.args.join(" "));
167
167
  expect(logs.some((log) => log.includes("Step 1/4: Waiting for payment"))).toBe(true);
168
- expect(logs.some((log) => log.includes("Step 2/4: Installing service"))).toBe(true);
169
- expect(logs.some((log) => log.includes("Step 3/4: Starting service"))).toBe(true);
170
- expect(logs.some((log) => log.includes("Step 4/4: Getting service URL"))).toBe(true);
168
+ expect(logs.some((log) => log.includes("Step 2/4: Installing Website"))).toBe(true);
169
+ expect(logs.some((log) => log.includes("Step 3/4: Starting Website"))).toBe(true);
170
+ expect(logs.some((log) => log.includes("Step 4/4: Getting Website URL"))).toBe(true);
171
171
  expect(logs.some((log) => log.includes("Your website is available at"))).toBe(true);
172
172
  });
173
173
 
174
+ test("successful deployment flow with subscription", async () => {
175
+ // Mock API responses for the complete flow
176
+ let callCount = 0;
177
+ global.fetch = mock(async (url) => {
178
+ callCount++;
179
+
180
+ // Step 1: Create payment session
181
+ if (url.includes("/api/checkout-sessions/start")) {
182
+ return {
183
+ ok: true,
184
+ status: 200,
185
+ json: async () => ({
186
+ checkoutSession: { id: "checkout-123" },
187
+ paymentUrl: "https://payment.test/checkout-123",
188
+ }),
189
+ };
190
+ }
191
+
192
+ // Step 2-4: Poll payment/installation/service status
193
+ if (url.includes("/api/vendors/order/checkout-123/status")) {
194
+ if (callCount <= 2) {
195
+ // First call: payment completed, installation in progress
196
+ return {
197
+ ok: true,
198
+ status: 200,
199
+ json: async () => ({
200
+ payment_status: "paid",
201
+ vendors: [{ id: "vendor-1", progress: 50, appUrl: null }],
202
+ }),
203
+ };
204
+ } else {
205
+ // Subsequent calls: installation complete
206
+ return {
207
+ ok: true,
208
+ status: 200,
209
+ json: async () => ({
210
+ payment_status: "paid",
211
+ vendors: [{ id: "vendor-1", progress: 100, appUrl: "https://app.test" }],
212
+ }),
213
+ };
214
+ }
215
+ }
216
+
217
+ // Step 5: Get order details
218
+ if (url.includes("/api/vendors/order/checkout-123/detail")) {
219
+ return {
220
+ ok: true,
221
+ status: 200,
222
+ json: async () => ({
223
+ vendors: [
224
+ {
225
+ appUrl: "https://app.test",
226
+ dashboardUrl: "https://dashboard.test",
227
+ homeUrl: "https://home.test",
228
+ token: "auth-token-123",
229
+ },
230
+ ],
231
+ subscriptionUrl: "https://subscription.test",
232
+ }),
233
+ };
234
+ }
235
+
236
+ throw new Error(`Unexpected URL: ${url}`);
237
+ });
238
+
239
+ const result = await deploy();
240
+
241
+ // Verify result
242
+ expect(result).toEqual({
243
+ appUrl: "https://app.test",
244
+ homeUrl: "https://home.test",
245
+ token: "auth-token-123",
246
+ });
247
+
248
+ // Verify saveValueToConfig was called
249
+ expect(saveValueToConfigSpy).toHaveBeenCalledWith(
250
+ "checkoutId",
251
+ "checkout-123",
252
+ "Checkout ID for document deployment website",
253
+ );
254
+ expect(saveValueToConfigSpy).toHaveBeenCalledWith(
255
+ "paymentUrl",
256
+ expect.stringContaining("payment"),
257
+ "Payment URL for document deployment website",
258
+ );
259
+
260
+ // Verify console output shows progress
261
+ const logs = consoleOutput.filter((o) => o.type === "log").map((o) => o.args.join(" "));
262
+
263
+ expect(logs.some((log) => log.includes("Step 1/4: Waiting for payment"))).toBe(true);
264
+ expect(logs.some((log) => log.includes("Step 2/4: Installing Website"))).toBe(true);
265
+ expect(logs.some((log) => log.includes("Step 3/4: Starting Website"))).toBe(true);
266
+ expect(logs.some((log) => log.includes("Step 4/4: Getting Website URL"))).toBe(true);
267
+ expect(logs.some((log) => log.includes("Your website is available at"))).toBe(true);
268
+ expect(logs.some((log) => log.includes("Your subscription management URL"))).toBe(true);
269
+ });
270
+
174
271
  test("handles missing payment link ID", async () => {
175
272
  getComponentInfoWithMountPointSpy.mockResolvedValue({
176
273
  mountPoint: "/payment",
@@ -359,7 +456,7 @@ describe("deploy", () => {
359
456
  expect(saveValueToConfigSpy).toHaveBeenCalledWith(
360
457
  "checkoutId",
361
458
  "",
362
- "Checkout ID for document deployment service",
459
+ "Checkout ID for document deployment website",
363
460
  );
364
461
  });
365
462
  });
package/utils/deploy.mjs CHANGED
@@ -12,7 +12,7 @@ const INTERVAL_MS = 3000; // 3 seconds between each check
12
12
  const TIMEOUTS = {
13
13
  paymentWait: 300, // Step 2: Payment wait timeout (5 minutes)
14
14
  installation: 300, // Step 3: Installation timeout (5 minutes)
15
- serviceStart: 300, // Step 4: Service startup timeout (5 minutes)
15
+ serviceStart: 300, // Step 4: Website startup timeout (5 minutes)
16
16
  };
17
17
 
18
18
  // ==================== Utility Functions ====================
@@ -76,8 +76,8 @@ const API_ENDPOINTS = {
76
76
  let prefix = "";
77
77
  let paymentLinkId = "";
78
78
  /**
79
- * Deploy a new Discuss Kit service and return the installation URL
80
- * @returns {Promise<string>} - The URL of the deployed service
79
+ * Deploy a new Discuss Kit Website and return the installation URL
80
+ * @returns {Promise<string>} - The URL of the deployed Website
81
81
  */
82
82
  export async function deploy(id, cachedUrl) {
83
83
  const { mountPoint, PAYMENT_LINK_ID } = await getComponentInfoWithMountPoint(
@@ -113,28 +113,33 @@ export async function deploy(id, cachedUrl) {
113
113
  }
114
114
 
115
115
  // Step 2: Wait for payment completion
116
- console.log(`${chalk.blue("ā³")} Step 1/4: Waiting for payment...`);
117
- console.log(`${chalk.blue("šŸ”—")} Payment link: ${chalk.cyan(paymentUrl)}\n`);
116
+ console.log(`ā³ Step 1/4: Waiting for payment...`);
117
+ console.log(`šŸ”— Payment link: ${chalk.cyan(paymentUrl)}\n`);
118
118
  await pollPaymentStatus(checkoutId);
119
- await saveValueToConfig("checkoutId", checkoutId, "Checkout ID for document deployment service");
120
- await saveValueToConfig("paymentUrl", paymentUrl, "Payment URL for document deployment service");
119
+ await saveValueToConfig("checkoutId", checkoutId, "Checkout ID for document deployment website");
120
+ await saveValueToConfig("paymentUrl", paymentUrl, "Payment URL for document deployment website");
121
121
 
122
- // Step 3: Wait for service installation
123
- console.log(`${chalk.blue("šŸ“¦")} Step 2/4: Installing service...`);
122
+ // Step 3: Wait for website installation
123
+ console.log(`šŸ“¦ Step 2/4: Installing Website...`);
124
124
  const readyVendors = await waitInstallation(checkoutId);
125
125
 
126
- // Step 4: Wait for service startup
127
- console.log(`${chalk.blue("šŸš€")} Step 3/4: Starting service...`);
128
- const runningVendors = await waitServiceRunning(readyVendors);
126
+ // Step 4: Wait for website startup
127
+ console.log(`šŸš€ Step 3/4: Starting Website...`);
128
+ const runningVendors = await waitWebsiteRunning(readyVendors);
129
129
 
130
130
  // Step 5: Get final URL
131
- console.log(`${chalk.blue("🌐")} Step 4/4: Getting service URL...`);
131
+ console.log(`🌐 Step 4/4: Getting Website URL...`);
132
132
  const urlInfo = await getDashboardAndUrl(checkoutId, runningVendors);
133
- const { appUrl, homeUrl, token } = urlInfo || {};
133
+ const { appUrl, homeUrl, token, subscriptionUrl } = urlInfo || {};
134
134
 
135
- console.log(
136
- `\n${chalk.blue("šŸ”—")} Your website is available at: ${chalk.cyan(homeUrl || appUrl)}\n`,
137
- );
135
+ console.log(`\nšŸ”— Your website is available at: ${chalk.cyan(homeUrl || appUrl)}`);
136
+
137
+ if (subscriptionUrl) {
138
+ console.log(`šŸ”— Your subscription management URL: ${chalk.cyan(subscriptionUrl)}\n`);
139
+ } else {
140
+ // just log one space line
141
+ console.log("");
142
+ }
138
143
 
139
144
  return {
140
145
  appUrl,
@@ -174,7 +179,7 @@ async function checkCacheCheckoutId(checkoutId) {
174
179
 
175
180
  return isPaid ? checkoutId : "";
176
181
  } catch (_error) {
177
- await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment service");
182
+ await saveValueToConfig("checkoutId", "", "Checkout ID for document deployment website");
178
183
  return "";
179
184
  }
180
185
  }
@@ -310,15 +315,15 @@ async function waitInstallation(checkoutId) {
310
315
  },
311
316
  maxAttempts: Math.ceil((TIMEOUTS.installation * 1000) / INTERVAL_MS),
312
317
  intervalMs: INTERVAL_MS,
313
- timeoutMessage: "Installation timeout - services failed to install within 5 minutes",
318
+ timeoutMessage: "Installation timeout - website failed to install within 5 minutes",
314
319
  stepName: "Installation",
315
320
  });
316
321
  }
317
322
 
318
323
  /**
319
- * Wait for service to start running - Step 4
324
+ * Wait for Website to start running - Step 4
320
325
  */
321
- async function waitServiceRunning(readyVendors) {
326
+ async function waitWebsiteRunning(readyVendors) {
322
327
  return pollWithTimeout({
323
328
  checkCondition: async () => {
324
329
  // Check running status of all vendors concurrently
@@ -346,8 +351,8 @@ async function waitServiceRunning(readyVendors) {
346
351
  },
347
352
  maxAttempts: Math.ceil((TIMEOUTS.serviceStart * 1000) / INTERVAL_MS),
348
353
  intervalMs: INTERVAL_MS,
349
- timeoutMessage: "Service start timeout - services failed to start within 5 minutes",
350
- stepName: "Service Start",
354
+ timeoutMessage: "Website start timeout - website failed to start within 5 minutes",
355
+ stepName: "Website Start",
351
356
  });
352
357
  }
353
358
 
@@ -385,6 +390,7 @@ async function getDashboardAndUrl(checkoutId, runningVendors) {
385
390
 
386
391
  return {
387
392
  appUrl,
393
+ subscriptionUrl: data.subscriptionUrl,
388
394
  dashboardUrl: data.vendors[0]?.dashboardUrl,
389
395
  homeUrl: data.vendors[0]?.homeUrl,
390
396
  token: data.vendors[0]?.token,
@@ -300,13 +300,13 @@ function checkContentStructure(markdown, source, errorMessages) {
300
300
  }
301
301
 
302
302
  // Check if content ends with proper punctuation (indicating completeness)
303
- const validEndingPunctuation = [".", "怂", ")", "|", "*", ">", "`", "!"];
303
+ const validEndingPunctuation = [".", "怂", ")", "|", "*", ">", "`", "!", ")"];
304
304
  const trimmedText = markdown.trim();
305
305
  const hasValidEnding = validEndingPunctuation.some((punct) => trimmedText.endsWith(punct));
306
306
 
307
307
  if (trimmedText.length > 0 && !hasValidEnding) {
308
308
  errorMessages.push(
309
- `Found incomplete content in ${source}: content does not end with proper punctuation (${validEndingPunctuation.join(", ")}). Please return the complete content`,
309
+ `Found incomplete content in ${source}: content does not end with proper punctuation [${validEndingPunctuation.join(", ")}]. Please return the complete content`,
310
310
  );
311
311
  }
312
312
  }