adapty 0.8.3-beta.1 → 0.8.4-beta.1
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/dist/commands/flows/config/get.js +2 -1
- package/dist/commands/flows/publish.js +9 -4
- package/dist/commands/placements/create.js +11 -1
- package/dist/commands/placements/update.js +11 -1
- package/dist/lib/api-schemas.d.ts +10 -0
- package/dist/lib/flow-help.d.ts +12 -0
- package/dist/lib/flow-help.js +27 -0
- package/oclif.manifest.json +1164 -1164
- package/package.json +1 -1
|
@@ -6,7 +6,8 @@ export default class FlowsConfigGet extends Command {
|
|
|
6
6
|
static args = {
|
|
7
7
|
flow_id: Args.string({ description: 'Flow ID (UUID)', required: true }),
|
|
8
8
|
};
|
|
9
|
-
static description = 'Read the flow builder config (404 until the config has been written at least once)'
|
|
9
|
+
static description = 'Read the flow builder config (404 until the config has been written at least once). ' +
|
|
10
|
+
'On a failed publish, `publication_status`, `transform_error` and `publication_error` show why.';
|
|
10
11
|
static enableJsonFlag = true;
|
|
11
12
|
static examples = ['<%= config.bin %> flows config get --app UUID 550e8400-e29b-41d4-a716-446655440000'];
|
|
12
13
|
static flags = {
|
|
@@ -3,12 +3,14 @@ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
|
|
|
3
3
|
import { confirmFlags, confirmMutation } from '../../lib/confirm.js';
|
|
4
4
|
import { ApiError } from '../../lib/errors.js';
|
|
5
5
|
import { appFlag, isValidUuid } from '../../lib/flags.js';
|
|
6
|
+
import { flowFixLinks } from '../../lib/flow-help.js';
|
|
6
7
|
import { printResponse } from '../../lib/output.js';
|
|
7
8
|
export default class FlowsPublish extends Command {
|
|
8
9
|
static args = {
|
|
9
10
|
flow_id: Args.string({ description: 'Flow ID (UUID)', required: true }),
|
|
10
11
|
};
|
|
11
|
-
static description = 'Publish a flow (async — publication completes in the background)'
|
|
12
|
+
static description = 'Publish a flow (async — publication completes in the background). ' +
|
|
13
|
+
'Publishing is async: returns status `publishing`. Poll `adapty flows get <flow_id>` for `published`/`publication_failed`; on failure, `adapty flows config get <flow_id>` shows why.';
|
|
12
14
|
static enableJsonFlag = true;
|
|
13
15
|
static examples = ['<%= config.bin %> flows publish --app UUID 550e8400-e29b-41d4-a716-446655440000'];
|
|
14
16
|
static flags = {
|
|
@@ -35,12 +37,15 @@ export default class FlowsPublish extends Command {
|
|
|
35
37
|
if (error instanceof ApiError && (error.statusCode === 400 || error.errorCode === 'validation_error')) {
|
|
36
38
|
this.error(`Flow publish failed: ${error.message}\n` +
|
|
37
39
|
'Publishing needs a flow with a valid config. Fix it, then run `adapty flows publish` again:\n' +
|
|
38
|
-
|
|
39
|
-
' • Adapty flows agent skill: https://adapty.io/docs/flow-generator-skill', { exit: 1 });
|
|
40
|
+
flowFixLinks(args.flow_id), { exit: 1 });
|
|
40
41
|
}
|
|
41
42
|
throw error;
|
|
42
43
|
}
|
|
43
|
-
this.
|
|
44
|
+
if (!this.jsonEnabled()) {
|
|
45
|
+
this.log('Publishing started — status: publishing. This is asynchronous; the flow is NOT published yet.');
|
|
46
|
+
this.log(`Check progress: adapty flows get --app ${flags.app} ${args.flow_id} (wait for status 'published' or 'publication_failed')`);
|
|
47
|
+
this.log(`If it fails: adapty flows config get --app ${flags.app} ${args.flow_id} (shows why)`);
|
|
48
|
+
}
|
|
44
49
|
printResponse(result, this.log.bind(this));
|
|
45
50
|
return result;
|
|
46
51
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Command, Flags } from '@oclif/core';
|
|
2
2
|
import { createAuthenticatedClient } from '../../lib/client-from-config.js';
|
|
3
3
|
import { appFlag } from '../../lib/flags.js';
|
|
4
|
+
import { draftFlowError } from '../../lib/flow-help.js';
|
|
4
5
|
import { printResponse } from '../../lib/output.js';
|
|
5
6
|
import { audienceEntryProblem } from '../../lib/placement-audiences.js';
|
|
6
7
|
export default class PlacementsCreate extends Command {
|
|
@@ -59,7 +60,16 @@ export default class PlacementsCreate extends Command {
|
|
|
59
60
|
body.audiences = parsed;
|
|
60
61
|
}
|
|
61
62
|
const client = await createAuthenticatedClient(this.config);
|
|
62
|
-
|
|
63
|
+
let result;
|
|
64
|
+
try {
|
|
65
|
+
result = await client.post(`/apps/${flags.app}/placements`, body);
|
|
66
|
+
}
|
|
67
|
+
catch (error) {
|
|
68
|
+
const message = draftFlowError(error, flags.app, body.audiences);
|
|
69
|
+
if (message)
|
|
70
|
+
this.error(message, { exit: 2 });
|
|
71
|
+
throw error;
|
|
72
|
+
}
|
|
63
73
|
this.log('Placement created!');
|
|
64
74
|
printResponse(result, this.log.bind(this));
|
|
65
75
|
return result;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Args, Command, Flags } from '@oclif/core';
|
|
2
2
|
import { createAuthenticatedClient } from '../../lib/client-from-config.js';
|
|
3
3
|
import { appFlag, isValidUuid } from '../../lib/flags.js';
|
|
4
|
+
import { draftFlowError } from '../../lib/flow-help.js';
|
|
4
5
|
import { printResponse } from '../../lib/output.js';
|
|
5
6
|
import { audienceEntryProblem } from '../../lib/placement-audiences.js';
|
|
6
7
|
export default class PlacementsUpdate extends Command {
|
|
@@ -68,7 +69,16 @@ export default class PlacementsUpdate extends Command {
|
|
|
68
69
|
body.audiences = parsed;
|
|
69
70
|
}
|
|
70
71
|
const client = await createAuthenticatedClient(this.config);
|
|
71
|
-
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
result = await client.put(`/apps/${flags.app}/placements/${args.placement_id}`, body);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const message = draftFlowError(error, flags.app, body.audiences);
|
|
78
|
+
if (message)
|
|
79
|
+
this.error(message, { exit: 2 });
|
|
80
|
+
throw error;
|
|
81
|
+
}
|
|
72
82
|
this.log('Placement updated!');
|
|
73
83
|
printResponse(result, this.log.bind(this));
|
|
74
84
|
return result;
|
|
@@ -87,8 +87,14 @@ export interface FlowRemoteConfigDTO {
|
|
|
87
87
|
}
|
|
88
88
|
export interface FlowConfigDTO {
|
|
89
89
|
config: Record<string, unknown>;
|
|
90
|
+
/** Human message for a failed publication (raw passthrough from the flow version). */
|
|
91
|
+
publication_error?: null | string;
|
|
92
|
+
/** Publication lifecycle of the flow version: transforming|transformed|uploading|uploaded|published|failed. */
|
|
93
|
+
publication_status?: string;
|
|
90
94
|
remote_configs: FlowRemoteConfigDTO[];
|
|
91
95
|
status: FlowStatus;
|
|
96
|
+
/** Raw transform failure: a JSON issues payload or a summary string. Parse with `parseFlowPublicationError`. */
|
|
97
|
+
transform_error?: null | string;
|
|
92
98
|
/** Millisecond timestamp of the last content change; the value `expected_updated_at` is compared against on write. */
|
|
93
99
|
updated_at: number;
|
|
94
100
|
}
|
|
@@ -146,12 +152,16 @@ export type PlacementAudienceEntryDTO = PlacementFlowAudienceEntryDTO | Placemen
|
|
|
146
152
|
export interface PlacementSummaryDTO {
|
|
147
153
|
developer_id: string;
|
|
148
154
|
id: string;
|
|
155
|
+
/** Placement activation state: true = Live, false = Inactive. */
|
|
156
|
+
is_active: boolean;
|
|
149
157
|
title: string;
|
|
150
158
|
}
|
|
151
159
|
export interface PlacementDetailDTO {
|
|
152
160
|
audiences?: PlacementAudienceEntryDTO[];
|
|
153
161
|
developer_id: string;
|
|
154
162
|
id: string;
|
|
163
|
+
/** Placement activation state: true = Live, false = Inactive. */
|
|
164
|
+
is_active: boolean;
|
|
155
165
|
title: string;
|
|
156
166
|
}
|
|
157
167
|
export interface PlacementWriteRequestDTO {
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare function builderUrl(flowId: string): string;
|
|
2
|
+
/** The two "• …" footer lines pointing at the Builder UI and the flows agent skill. */
|
|
3
|
+
export declare function flowFixLinks(flowId: string): string;
|
|
4
|
+
/**
|
|
5
|
+
* When `error` is the backend's draft-flow rejection, returns an enriched message with the
|
|
6
|
+
* publish command and fix links; otherwise returns null so the caller rethrows unchanged.
|
|
7
|
+
* `flowId` is taken from the single flow audience, or `<FLOW_ID>` when it is ambiguous.
|
|
8
|
+
*/
|
|
9
|
+
export declare function draftFlowError(error: unknown, app: string, audiences: null | {
|
|
10
|
+
content_type?: string;
|
|
11
|
+
flow_id?: string;
|
|
12
|
+
}[]): null | string;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// Shared "how to fix a flow" links, used by `flows publish` (config-error message)
|
|
2
|
+
// and by `placements create`/`update` (draft-attach error). One source for both URLs.
|
|
3
|
+
import { ApiError } from './errors.js';
|
|
4
|
+
export function builderUrl(flowId) {
|
|
5
|
+
return `https://app.adapty.io/flows/${flowId}/builder`;
|
|
6
|
+
}
|
|
7
|
+
/** The two "• …" footer lines pointing at the Builder UI and the flows agent skill. */
|
|
8
|
+
export function flowFixLinks(flowId) {
|
|
9
|
+
return ` • Builder UI: ${builderUrl(flowId)}\n • Adapty flows agent skill: https://adapty.io/docs/flow-generator-skill`;
|
|
10
|
+
}
|
|
11
|
+
// The backend message when a placement tries to attach an unpublished flow. There is no
|
|
12
|
+
// distinct error_code (it comes back as generic validation_error), so match on the text.
|
|
13
|
+
const DRAFT_FLOW_MARKER = 'Flow must be published before placing in a placement';
|
|
14
|
+
/**
|
|
15
|
+
* When `error` is the backend's draft-flow rejection, returns an enriched message with the
|
|
16
|
+
* publish command and fix links; otherwise returns null so the caller rethrows unchanged.
|
|
17
|
+
* `flowId` is taken from the single flow audience, or `<FLOW_ID>` when it is ambiguous.
|
|
18
|
+
*/
|
|
19
|
+
export function draftFlowError(error, app, audiences) {
|
|
20
|
+
if (!(error instanceof ApiError) || !error.message.includes(DRAFT_FLOW_MARKER))
|
|
21
|
+
return null;
|
|
22
|
+
const flows = (audiences ?? []).filter((a) => a.content_type === 'flow' && typeof a.flow_id === 'string');
|
|
23
|
+
const flowId = flows.length === 1 ? flows[0].flow_id : '<FLOW_ID>';
|
|
24
|
+
return ('Cannot attach a draft flow to a placement — publish it first.\n' +
|
|
25
|
+
`Publish: adapty flows publish --app ${app} ${flowId}\n` +
|
|
26
|
+
flowFixLinks(flowId));
|
|
27
|
+
}
|