@algolia/wizard 0.75.0 → 0.76.0

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.
Files changed (2) hide show
  1. package/dist/main.js +306 -56
  2. package/package.json +1 -1
package/dist/main.js CHANGED
@@ -2234,6 +2234,7 @@ async function promptForApplication(highlight) {
2234
2234
  }
2235
2235
  async function promptToChangeApplication(currentId) {
2236
2236
  const store = useWizard.getState();
2237
+ store.clearNotices();
2237
2238
  store.setLoadingMessage("Loading applications\u2026");
2238
2239
  try {
2239
2240
  const env = await findEnvApplicationId();
@@ -2260,7 +2261,7 @@ async function ensureApplication(resumeAppId) {
2260
2261
  // package.json
2261
2262
  var package_default = {
2262
2263
  name: "@algolia/wizard",
2263
- version: "0.75.0",
2264
+ version: "0.76.0",
2264
2265
  description: "Magically implement Algolia functionality in your codebase",
2265
2266
  type: "module",
2266
2267
  engines: {
@@ -6314,6 +6315,9 @@ var defaultWorkflow = {
6314
6315
  ]
6315
6316
  };
6316
6317
 
6318
+ // src/workflows/playbook.ts
6319
+ import "zod";
6320
+
6317
6321
  // src/actions/playbookSteps/selectPlaybook.ts
6318
6322
  import { z as z32 } from "zod";
6319
6323
 
@@ -6333,6 +6337,16 @@ var DashboardApiError = class extends Error {
6333
6337
  return isRecord(this.body) ? this.body : void 0;
6334
6338
  }
6335
6339
  };
6340
+ async function retryOnDashboardError(call, recover) {
6341
+ for (; ; ) {
6342
+ try {
6343
+ return await call();
6344
+ } catch (err) {
6345
+ if (!(err instanceof DashboardApiError)) throw err;
6346
+ await recover(err);
6347
+ }
6348
+ }
6349
+ }
6336
6350
  function isRecord(value) {
6337
6351
  return !!value && typeof value === "object" && !Array.isArray(value);
6338
6352
  }
@@ -6435,6 +6449,21 @@ async function getPlaybooks() {
6435
6449
  );
6436
6450
  return data;
6437
6451
  }
6452
+ async function createPlaybookExecution(appId, slug, indexName, options) {
6453
+ const { data } = await dashboardRequest(
6454
+ `/api/1/playbook-integrations/applications/${appId}/playbooks/${slug}/executions`,
6455
+ playbookExecutionCreateResponseSchema,
6456
+ {
6457
+ method: "POST",
6458
+ headers: { "content-type": "application/json" },
6459
+ body: JSON.stringify({
6460
+ index_name: indexName,
6461
+ force_new: options?.forceNew ?? false
6462
+ })
6463
+ }
6464
+ );
6465
+ return data;
6466
+ }
6438
6467
  async function createSampleIndex(appId, playbookSlug) {
6439
6468
  const { data } = await dashboardRequest(
6440
6469
  `/api/1/playbook-integrations/applications/${appId}/playbooks/${playbookSlug}/sample_index`,
@@ -6443,6 +6472,20 @@ async function createSampleIndex(appId, playbookSlug) {
6443
6472
  );
6444
6473
  return data;
6445
6474
  }
6475
+ async function getPlaybookExecution(uuid) {
6476
+ const { data } = await dashboardRequest(
6477
+ `/api/1/playbook-integrations/playbooks/executions/${uuid}`,
6478
+ playbookExecutionSchema
6479
+ );
6480
+ return data;
6481
+ }
6482
+ async function assessPlaybookExecution(uuid) {
6483
+ await dashboardRequest(
6484
+ `/api/1/playbook-integrations/playbooks/executions/${uuid}/assess`,
6485
+ messageResponseSchema,
6486
+ { method: "POST" }
6487
+ );
6488
+ }
6446
6489
 
6447
6490
  // src/actions/playbookSteps/selectPlaybook.ts
6448
6491
  var selectPlaybookSchema = z32.object({
@@ -6477,45 +6520,15 @@ async function selectPlaybookStep(ctx, requestedSlug) {
6477
6520
  return persistSlug(ctx, selection);
6478
6521
  }
6479
6522
 
6480
- // src/actions/playbookSteps/confirmPlaybook.ts
6481
- import { z as z33 } from "zod";
6482
- var confirmPlaybookSchema = z33.void();
6483
- var CONTINUE_OPTION = "Looks good, continue";
6484
- var GO_BACK_OPTION = "Go back";
6485
- var SELECT_APP_OPTION = "Select app";
6486
- async function confirmPlaybookStep(ctx) {
6487
- const { slug } = ctx.getStepOutput("select-playbook");
6488
- for (; ; ) {
6489
- const selection = await ctx.requestUserInput({
6490
- prompt: "Ready to continue?",
6491
- promptType: "multipleChoice",
6492
- options: [CONTINUE_OPTION, GO_BACK_OPTION, SELECT_APP_OPTION],
6493
- messages: [`Playbook: ${slug}`, `Application: ${ctx.appId}`],
6494
- helpText: "Going back re-opens the playbook catalogue. Select app opens the application catalogue \u2014 keep the current app to stay here, or pick another to restart the wizard."
6495
- });
6496
- if (typeof selection !== "string") {
6497
- throw new Error("confirm-playbook received an unexpected result");
6498
- }
6499
- if (selection === SELECT_APP_OPTION) {
6500
- await ctx.changeApplication();
6501
- continue;
6502
- }
6503
- if (selection === GO_BACK_OPTION) {
6504
- return ctx.returnToStep("select-playbook");
6505
- }
6506
- return;
6507
- }
6508
- }
6509
-
6510
6523
  // src/actions/playbookSteps/selectIndex.ts
6511
- import { z as z34 } from "zod";
6512
- var selectIndexSchema = z34.object({
6513
- indexName: z34.string(),
6514
- sampleIndex: z34.boolean()
6524
+ import { z as z33 } from "zod";
6525
+ var selectIndexSchema = z33.object({
6526
+ indexName: z33.string(),
6527
+ sampleIndex: z33.boolean()
6515
6528
  });
6516
6529
  var CREATE_SAMPLE_INDEX = "Create a sample index";
6517
- var GO_BACK_OPTION2 = "Go back to playbook selection";
6518
- var SELECT_APP_OPTION2 = "Select app";
6530
+ var GO_BACK_OPTION = "Go back to playbook selection";
6531
+ var SELECT_APP_OPTION = "Select app";
6519
6532
  var MIN_ENTRIES_FOR_SELECTION = 1;
6520
6533
  function formatIndexOption(index) {
6521
6534
  if (index.entries < MIN_ENTRIES_FOR_SELECTION) {
@@ -6541,8 +6554,8 @@ async function selectIndexStep2(ctx) {
6541
6554
  const options = [
6542
6555
  ...indexOptions,
6543
6556
  CREATE_SAMPLE_INDEX,
6544
- GO_BACK_OPTION2,
6545
- SELECT_APP_OPTION2
6557
+ GO_BACK_OPTION,
6558
+ SELECT_APP_OPTION
6546
6559
  ];
6547
6560
  const disabled = hasIndices ? [
6548
6561
  ...indices.map((idx) => !isIndexSelectable(idx)),
@@ -6571,11 +6584,11 @@ you can explore or switch to another application`;
6571
6584
  "selectIndex received an unexpected non-text result"
6572
6585
  );
6573
6586
  }
6574
- if (selection === GO_BACK_OPTION2) {
6587
+ if (selection === GO_BACK_OPTION) {
6575
6588
  ctx.setUserInput("fetchedIndices", void 0);
6576
6589
  return ctx.returnToStep("select-playbook");
6577
6590
  }
6578
- if (selection === SELECT_APP_OPTION2) {
6591
+ if (selection === SELECT_APP_OPTION) {
6579
6592
  await ctx.changeApplication();
6580
6593
  continue;
6581
6594
  }
@@ -6604,8 +6617,8 @@ you can explore or switch to another application`;
6604
6617
  // src/actions/playbookSteps/confirmIndex.ts
6605
6618
  import "zod";
6606
6619
  var confirmIndexSchema = playbookExecutionSchema.nullable();
6607
- var CONTINUE_OPTION2 = "Looks good, continue";
6608
- var GO_BACK_OPTION3 = "Go back";
6620
+ var CONTINUE_OPTION = "Looks good, continue";
6621
+ var GO_BACK_OPTION2 = "Go back";
6609
6622
  async function confirmIndexStep(ctx) {
6610
6623
  const { sampleIndex } = ctx.getStepOutput("select-index");
6611
6624
  if (!sampleIndex) {
@@ -6615,7 +6628,7 @@ async function confirmIndexStep(ctx) {
6615
6628
  const selection = await ctx.requestUserInput({
6616
6629
  prompt: "Ready to create sample index?",
6617
6630
  promptType: "multipleChoice",
6618
- options: [CONTINUE_OPTION2, GO_BACK_OPTION3],
6631
+ options: [CONTINUE_OPTION, GO_BACK_OPTION2],
6619
6632
  messages: [
6620
6633
  `A new index called "algolia_playbooks_${slug}_sample_index" will be created with sample ${slug} data.`
6621
6634
  ],
@@ -6624,7 +6637,7 @@ async function confirmIndexStep(ctx) {
6624
6637
  if (typeof selection !== "string") {
6625
6638
  throw new Error("confirm-index received an unexpected result");
6626
6639
  }
6627
- if (selection === GO_BACK_OPTION3) {
6640
+ if (selection === GO_BACK_OPTION2) {
6628
6641
  return ctx.returnToStep("select-index");
6629
6642
  }
6630
6643
  ctx.notify({
@@ -6654,6 +6667,227 @@ async function confirmIndexStep(ctx) {
6654
6667
  }
6655
6668
  }
6656
6669
 
6670
+ // src/actions/playbookSteps/dataAssessment.ts
6671
+ var CONTINUE_EXECUTION_OPTION = "Continue";
6672
+ var RESTART_OPTION = "Restart";
6673
+ var GO_BACK_OPTION3 = "Go back";
6674
+ var SWITCH_APPLICATION_OPTION = "Switch application";
6675
+ var SWITCH_INDEX_OPTION = "Switch index";
6676
+ var RETRY_OPTION = "Retry";
6677
+ var POLL_INTERVAL_MS = 5e3;
6678
+ var POLL_TIMEOUT_MS = 6e4;
6679
+ var ASSESSING_NOTICE_HOLD_MS = 2e4;
6680
+ var CREATING_EXECUTION_NOTICE = "creating playbook execution\u2026";
6681
+ var POLL_NOTICES = [
6682
+ { message: "created playbook execution", holdMs: POLL_INTERVAL_MS },
6683
+ { message: "sampled records", holdMs: POLL_INTERVAL_MS },
6684
+ {
6685
+ message: "assessing schema and readiness \u2014 this usually takes ~20s for indices under 1M records.",
6686
+ holdMs: ASSESSING_NOTICE_HOLD_MS
6687
+ },
6688
+ { message: "detecting required fields\u2026" }
6689
+ ];
6690
+ async function dataAssessmentStep(ctx) {
6691
+ const { slug } = ctx.getStepOutput("select-playbook");
6692
+ const { indexName, existingExecution } = indexForAssessment(ctx);
6693
+ if (existingExecution) return existingExecution;
6694
+ try {
6695
+ showNotice(ctx, CREATING_EXECUTION_NOTICE);
6696
+ const { id: appId } = await requireApplication();
6697
+ const execution = await resolveExecution(ctx, appId, slug, indexName);
6698
+ return await runAssessment(ctx, execution, indexName);
6699
+ } finally {
6700
+ ctx.clearNotices();
6701
+ }
6702
+ }
6703
+ function indexForAssessment(ctx) {
6704
+ const selected = ctx.getStepOutput("select-index");
6705
+ if (!selected.sampleIndex) {
6706
+ return { indexName: selected.indexName, existingExecution: null };
6707
+ }
6708
+ const created = ctx.getStepOutput("confirm-index");
6709
+ if (!created) {
6710
+ throw new Error(
6711
+ "data-assessment expected confirm-index to create a sample index"
6712
+ );
6713
+ }
6714
+ return {
6715
+ indexName: created.source_index_name,
6716
+ existingExecution: created
6717
+ };
6718
+ }
6719
+ function showNotice(ctx, message) {
6720
+ ctx.clearNotices();
6721
+ ctx.notify({ messages: [message] });
6722
+ }
6723
+ function startPollNotices(ctx) {
6724
+ let index = 0;
6725
+ let timer;
6726
+ const showCurrent = () => {
6727
+ const notice = POLL_NOTICES[index];
6728
+ showNotice(ctx, notice.message);
6729
+ if (notice.holdMs == null) return;
6730
+ timer = setTimeout(() => {
6731
+ index += 1;
6732
+ showCurrent();
6733
+ }, notice.holdMs);
6734
+ };
6735
+ showCurrent();
6736
+ return () => clearTimeout(timer);
6737
+ }
6738
+ async function runAssessment(ctx, execution, indexName) {
6739
+ if (execution.step_status === "done") {
6740
+ return execution;
6741
+ }
6742
+ if (execution.step_status === "not_started" || execution.step_status === "error") {
6743
+ await assessExecution(ctx, execution.uuid, indexName);
6744
+ } else if (execution.step_status !== "in_progress") {
6745
+ throw unexpectedAssessmentStatus(execution.step_status);
6746
+ }
6747
+ for (; ; ) {
6748
+ const assessed = await pollUntilAssessed(ctx, execution.uuid, indexName);
6749
+ if (assessed.step_status === "done") {
6750
+ return assessed;
6751
+ }
6752
+ if (assessed.step_status !== "error") {
6753
+ throw unexpectedAssessmentStatus(assessed.step_status);
6754
+ }
6755
+ await promptAssessmentRecovery(
6756
+ ctx,
6757
+ assessmentFailureMessage(assessed),
6758
+ assessed.status_reason === "index_empty"
6759
+ );
6760
+ await assessExecution(ctx, execution.uuid, indexName);
6761
+ }
6762
+ }
6763
+ function unexpectedAssessmentStatus(status) {
6764
+ return new Error(
6765
+ `data-assessment received an unexpected assessment status: ${status}`
6766
+ );
6767
+ }
6768
+ async function resolveExecution(ctx, appId, slug, indexName) {
6769
+ const created = await createWithRecovery(ctx, appId, slug, indexName);
6770
+ if (!created.resumed) return created;
6771
+ const choice = await ctx.requestUserInput({
6772
+ prompt: `${indexName} has a playbook in progress.`,
6773
+ promptType: "multipleChoice",
6774
+ options: [CONTINUE_EXECUTION_OPTION, RESTART_OPTION, GO_BACK_OPTION3],
6775
+ secondary: [{ kind: "text", value: "resume Assessment" }]
6776
+ });
6777
+ if (choice === CONTINUE_EXECUTION_OPTION) return created;
6778
+ if (choice === RESTART_OPTION) {
6779
+ return createWithRecovery(ctx, appId, slug, indexName, { forceNew: true });
6780
+ }
6781
+ if (choice === GO_BACK_OPTION3) {
6782
+ return ctx.returnToStep("select-index");
6783
+ }
6784
+ throw new Error("data-assessment received an unexpected execution choice");
6785
+ }
6786
+ async function createWithRecovery(ctx, appId, slug, indexName, options) {
6787
+ return retryOnDashboardError(
6788
+ () => {
6789
+ showNotice(ctx, CREATING_EXECUTION_NOTICE);
6790
+ return createPlaybookExecution(appId, slug, indexName, options);
6791
+ },
6792
+ onRequestFailure(ctx, indexName)
6793
+ );
6794
+ }
6795
+ function onRequestFailure(ctx, indexName) {
6796
+ return async (err) => {
6797
+ await promptAssessmentRecovery(
6798
+ ctx,
6799
+ requestFailureMessage(indexName, err),
6800
+ isEmptyIndexError(err)
6801
+ );
6802
+ };
6803
+ }
6804
+ function requestFailureMessage(indexName, err) {
6805
+ if (isEmptyIndexError(err)) {
6806
+ return `Index "${indexName}" has no records to assess.`;
6807
+ }
6808
+ const message = err.errorBody()?.message;
6809
+ if (typeof message === "string" && message.trim()) return message;
6810
+ return "Couldn't complete the request.";
6811
+ }
6812
+ function isEmptyIndexError(err) {
6813
+ const body = err.errorBody();
6814
+ return body?.status_reason === "index_empty" || body?.message === "index_empty";
6815
+ }
6816
+ async function pollUntilAssessed(ctx, uuid, indexName) {
6817
+ const logId = ctx.logStart("Assessing index data");
6818
+ const deadline = Date.now() + POLL_TIMEOUT_MS;
6819
+ let logStatus = "error";
6820
+ let stopNotices = startPollNotices(ctx);
6821
+ try {
6822
+ for (; ; ) {
6823
+ const execution = await retryOnDashboardError(
6824
+ () => getPlaybookExecution(uuid),
6825
+ async (err) => {
6826
+ stopNotices();
6827
+ ctx.clearNotices();
6828
+ await promptAssessmentRecovery(
6829
+ ctx,
6830
+ requestFailureMessage(indexName, err),
6831
+ isEmptyIndexError(err)
6832
+ );
6833
+ stopNotices = startPollNotices(ctx);
6834
+ }
6835
+ );
6836
+ if (execution.step_status === "done") {
6837
+ logStatus = "success";
6838
+ return execution;
6839
+ }
6840
+ if (execution.step_status === "error") {
6841
+ ctx.clearNotices();
6842
+ return execution;
6843
+ }
6844
+ if (Date.now() >= deadline) {
6845
+ throw new Error("Timed out waiting for the data assessment to finish.");
6846
+ }
6847
+ await sleep(POLL_INTERVAL_MS);
6848
+ }
6849
+ } catch (err) {
6850
+ ctx.clearNotices();
6851
+ throw err;
6852
+ } finally {
6853
+ stopNotices();
6854
+ ctx.logEnd(logId, logStatus);
6855
+ }
6856
+ }
6857
+ var sleep = (ms) => new Promise((resolve5) => setTimeout(resolve5, ms));
6858
+ async function assessExecution(ctx, uuid, indexName) {
6859
+ await retryOnDashboardError(
6860
+ () => assessPlaybookExecution(uuid),
6861
+ onRequestFailure(ctx, indexName)
6862
+ );
6863
+ }
6864
+ async function promptAssessmentRecovery(ctx, message, retryDisabled) {
6865
+ const choice = await ctx.requestUserInput({
6866
+ prompt: "Data assessment failed.",
6867
+ promptType: "multipleChoice",
6868
+ options: [SWITCH_APPLICATION_OPTION, SWITCH_INDEX_OPTION, RETRY_OPTION],
6869
+ messages: [message],
6870
+ disabled: [false, false, retryDisabled],
6871
+ helpText: "Retry re-runs assessment on this index. Switch index or application to pick a different target."
6872
+ });
6873
+ if (choice === SWITCH_APPLICATION_OPTION) {
6874
+ return ctx.changeApplication();
6875
+ }
6876
+ if (choice === SWITCH_INDEX_OPTION) {
6877
+ return ctx.returnToStep("select-index");
6878
+ }
6879
+ if (choice === RETRY_OPTION) {
6880
+ return;
6881
+ }
6882
+ throw new Error("data-assessment received an unexpected recovery choice");
6883
+ }
6884
+ function assessmentFailureMessage(execution) {
6885
+ if (execution.status_reason === "index_empty") {
6886
+ return `Index "${execution.source_index_name}" has no records to assess.`;
6887
+ }
6888
+ return execution.status_reason ?? "Data assessment failed.";
6889
+ }
6890
+
6657
6891
  // src/lib/cli.ts
6658
6892
  var USAGE = `Usage: wizard [workflow-id] [options]
6659
6893
  wizard playbook [playbook-slug] [options]
@@ -6721,13 +6955,6 @@ var playbookWorkflow = {
6721
6955
  outputSchema: selectPlaybookSchema,
6722
6956
  run: (ctx) => selectPlaybookStep(ctx, getPlaybookSlugArg())
6723
6957
  }),
6724
- defineStep({
6725
- id: "confirm-playbook",
6726
- title: "Confirm selections",
6727
- outputSchema: confirmPlaybookSchema,
6728
- visible: false,
6729
- run: (ctx) => confirmPlaybookStep(ctx)
6730
- }),
6731
6958
  defineStep({
6732
6959
  id: "select-index",
6733
6960
  title: "Select index",
@@ -6742,6 +6969,12 @@ var playbookWorkflow = {
6742
6969
  visible: false,
6743
6970
  tips: ["apps-and-indices", "records-are-json", "speed"],
6744
6971
  run: (ctx) => confirmIndexStep(ctx)
6972
+ }),
6973
+ defineStep({
6974
+ id: "data-assessment",
6975
+ title: "Assess index data",
6976
+ outputSchema: playbookExecutionSchema,
6977
+ run: (ctx) => dataAssessmentStep(ctx)
6745
6978
  })
6746
6979
  ]
6747
6980
  };
@@ -7637,7 +7870,7 @@ function App() {
7637
7870
  const isCommandApprovalPrompt = isAwaitingUserInput && inputReq?.promptType === "commandApproval";
7638
7871
  const promptPending = isAwaitingUserInput && !isCommandApprovalPrompt;
7639
7872
  const holdForTip = stepHasTips && promptPending && tipState === "revealing";
7640
- const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" || isCommandApprovalPrompt || holdForTip);
7873
+ const showTips = stepHasTips && (phase === "running" && currentStep?.status === "running" && !loadingMessage && !settingUpAppId || isCommandApprovalPrompt);
7641
7874
  const showNoticesInMain = !stepHasTips;
7642
7875
  const showNotices = (!isAwaitingUserInput || holdForTip) && !review2;
7643
7876
  useInput9(
@@ -7826,6 +8059,23 @@ var selectPlaybookIndex = {
7826
8059
  indexName: "wizard_seed_orders",
7827
8060
  sampleIndex: false
7828
8061
  };
8062
+ var dataAssessment = {
8063
+ uuid: "seed-exec-uuid",
8064
+ playbook_slug: selectPlaybook.slug,
8065
+ application_id: "SEEDAPPID",
8066
+ source_index_name: selectPlaybookIndex.indexName,
8067
+ current_step: "assessment",
8068
+ step_status: "done",
8069
+ status_reason: null,
8070
+ completed: true,
8071
+ assessment_result: {
8072
+ ready: true,
8073
+ schema_comparison: [],
8074
+ settings_recommendation: {}
8075
+ },
8076
+ settings_snapshot: null,
8077
+ created_at: "2026-09-22T09:00:00.000Z"
8078
+ };
7829
8079
  var review = {
7830
8080
  summaryPoints: [
7831
8081
  "Ingested 25 generated Product records into wizard_seed_products.",
@@ -7847,9 +8097,9 @@ var SEEDS = {
7847
8097
  },
7848
8098
  playbook: {
7849
8099
  "select-playbook": selectPlaybook,
7850
- "confirm-playbook": void 0,
7851
8100
  "select-index": selectPlaybookIndex,
7852
- "confirm-index": null
8101
+ "confirm-index": null,
8102
+ "data-assessment": dataAssessment
7853
8103
  }
7854
8104
  };
7855
8105
  var SEED_ALGOLIA_STATE = {
@@ -8020,7 +8270,7 @@ function delay(ms) {
8020
8270
  // package.json with { type: 'json' }
8021
8271
  var package_default2 = {
8022
8272
  name: "@algolia/wizard",
8023
- version: "0.75.0",
8273
+ version: "0.76.0",
8024
8274
  description: "Magically implement Algolia functionality in your codebase",
8025
8275
  type: "module",
8026
8276
  engines: {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@algolia/wizard",
3
- "version": "0.75.0",
3
+ "version": "0.76.0",
4
4
  "description": "Magically implement Algolia functionality in your codebase",
5
5
  "type": "module",
6
6
  "engines": {