adapty 0.1.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 (71) hide show
  1. package/README.md +110 -0
  2. package/bin/dev.cmd +3 -0
  3. package/bin/dev.js +5 -0
  4. package/bin/run.cmd +3 -0
  5. package/bin/run.js +5 -0
  6. package/dist/commands/access-levels/create.d.ts +18 -0
  7. package/dist/commands/access-levels/create.js +28 -0
  8. package/dist/commands/access-levels/get.d.ts +19 -0
  9. package/dist/commands/access-levels/get.js +26 -0
  10. package/dist/commands/access-levels/list.d.ts +19 -0
  11. package/dist/commands/access-levels/list.js +20 -0
  12. package/dist/commands/access-levels/update.d.ts +20 -0
  13. package/dist/commands/access-levels/update.js +32 -0
  14. package/dist/commands/apps/create.d.ts +25 -0
  15. package/dist/commands/apps/create.js +47 -0
  16. package/dist/commands/apps/get.d.ts +20 -0
  17. package/dist/commands/apps/get.js +29 -0
  18. package/dist/commands/apps/list.d.ts +18 -0
  19. package/dist/commands/apps/list.js +19 -0
  20. package/dist/commands/apps/update.d.ts +22 -0
  21. package/dist/commands/apps/update.js +42 -0
  22. package/dist/commands/auth/login.d.ts +6 -0
  23. package/dist/commands/auth/login.js +106 -0
  24. package/dist/commands/auth/logout.d.ts +9 -0
  25. package/dist/commands/auth/logout.js +18 -0
  26. package/dist/commands/auth/status.d.ts +7 -0
  27. package/dist/commands/auth/status.js +26 -0
  28. package/dist/commands/auth/whoami.d.ts +16 -0
  29. package/dist/commands/auth/whoami.js +21 -0
  30. package/dist/commands/paywalls/create.d.ts +17 -0
  31. package/dist/commands/paywalls/create.js +31 -0
  32. package/dist/commands/paywalls/get.d.ts +19 -0
  33. package/dist/commands/paywalls/get.js +26 -0
  34. package/dist/commands/paywalls/list.d.ts +18 -0
  35. package/dist/commands/paywalls/list.js +20 -0
  36. package/dist/commands/paywalls/update.d.ts +20 -0
  37. package/dist/commands/paywalls/update.js +37 -0
  38. package/dist/commands/placements/create.d.ts +19 -0
  39. package/dist/commands/placements/create.js +30 -0
  40. package/dist/commands/placements/get.d.ts +20 -0
  41. package/dist/commands/placements/get.js +27 -0
  42. package/dist/commands/placements/list.d.ts +19 -0
  43. package/dist/commands/placements/list.js +20 -0
  44. package/dist/commands/placements/update.d.ts +22 -0
  45. package/dist/commands/placements/update.js +36 -0
  46. package/dist/commands/products/create.d.ts +33 -0
  47. package/dist/commands/products/create.js +59 -0
  48. package/dist/commands/products/get.d.ts +32 -0
  49. package/dist/commands/products/get.js +34 -0
  50. package/dist/commands/products/list.d.ts +30 -0
  51. package/dist/commands/products/list.js +31 -0
  52. package/dist/commands/products/update.d.ts +36 -0
  53. package/dist/commands/products/update.js +65 -0
  54. package/dist/index.d.ts +1 -0
  55. package/dist/index.js +1 -0
  56. package/dist/lib/api-client.d.ts +15 -0
  57. package/dist/lib/api-client.js +75 -0
  58. package/dist/lib/auth.d.ts +1 -0
  59. package/dist/lib/auth.js +8 -0
  60. package/dist/lib/client-from-config.d.ts +4 -0
  61. package/dist/lib/client-from-config.js +15 -0
  62. package/dist/lib/config.d.ts +9 -0
  63. package/dist/lib/config.js +22 -0
  64. package/dist/lib/errors.d.ts +23 -0
  65. package/dist/lib/errors.js +63 -0
  66. package/dist/lib/flags.d.ts +22 -0
  67. package/dist/lib/flags.js +36 -0
  68. package/dist/lib/output.d.ts +6 -0
  69. package/dist/lib/output.js +18 -0
  70. package/oclif.manifest.json +1284 -0
  71. package/package.json +100 -0
@@ -0,0 +1,106 @@
1
+ import { Command } from '@oclif/core';
2
+ import open from 'open';
3
+ import { ApiClient } from '../../lib/api-client.js';
4
+ import { buildUserAgent } from '../../lib/client-from-config.js';
5
+ import { readConfig, writeConfig } from '../../lib/config.js';
6
+ function sleep(ms) {
7
+ return new Promise((resolve) => {
8
+ setTimeout(resolve, ms);
9
+ });
10
+ }
11
+ export default class AuthLogin extends Command {
12
+ static description = 'Authenticate with Adapty via browser';
13
+ static examples = ['<%= config.bin %> auth login'];
14
+ async run() {
15
+ const config = await readConfig(this.config.configDir);
16
+ if (config.access_token && config.user) {
17
+ this.log(`Already authenticated as ${config.user.email}. Re-authenticating...`);
18
+ }
19
+ const client = new ApiClient({
20
+ userAgent: buildUserAgent(this.config),
21
+ });
22
+ let device;
23
+ try {
24
+ device = await client.post('/auth/device', { client_id: 'adapty-cli' });
25
+ }
26
+ catch (error) {
27
+ this.error(error instanceof Error ? error.message : 'Failed to initiate auth flow', { exit: 1 });
28
+ }
29
+ this.log(`\nYour code: ${device.user_code}\n`);
30
+ this.log(`If browser doesn't open, visit: ${device.verification_uri_complete}\n`);
31
+ try {
32
+ await open(device.verification_uri_complete);
33
+ }
34
+ catch {
35
+ // browser open failed silently — URL already printed
36
+ }
37
+ this.log('Waiting for authorization...');
38
+ let interval = device.interval * 1000;
39
+ const deadline = Date.now() + device.expires_in * 1000;
40
+ let consecutiveErrors = 0;
41
+ // Handle Ctrl+C
42
+ const onSignal = () => {
43
+ this.log('\nLogin cancelled.');
44
+ process.exit(0);
45
+ };
46
+ process.on('SIGINT', onSignal);
47
+ try {
48
+ while (Date.now() < deadline) {
49
+ await sleep(interval);
50
+ let result;
51
+ try {
52
+ result = await client.post('/auth/token', {
53
+ device_code: device.device_code,
54
+ grant_type: 'urn:ietf:params:oauth:grant-type:device_code',
55
+ });
56
+ }
57
+ catch (error) {
58
+ consecutiveErrors++;
59
+ if (consecutiveErrors >= 10) {
60
+ this.error('Too many consecutive network errors. Check your connection and try again.', { exit: 1 });
61
+ }
62
+ if (consecutiveErrors >= 3) {
63
+ process.stderr.write(`Warning: ${consecutiveErrors} consecutive network errors (${error instanceof Error ? error.message : 'unknown'})\n`);
64
+ }
65
+ continue;
66
+ }
67
+ consecutiveErrors = 0;
68
+ if ('error' in result) {
69
+ switch (result.error) {
70
+ case 'access_denied': {
71
+ this.error('Authorization denied.', { exit: 1 });
72
+ break;
73
+ }
74
+ case 'authorization_pending': {
75
+ continue;
76
+ }
77
+ case 'slow_down': {
78
+ interval += 5000;
79
+ continue;
80
+ }
81
+ case 'expired_token': {
82
+ this.error('Code expired. Run `adapty auth login` again.', { exit: 1 });
83
+ break; // unreachable but satisfies linter
84
+ }
85
+ default: {
86
+ this.error(`Unexpected error: ${result.error}`, { exit: 1 });
87
+ }
88
+ }
89
+ }
90
+ if ('access_token' in result) {
91
+ await writeConfig({
92
+ access_token: result.access_token,
93
+ user: result.user,
94
+ }, this.config.configDir);
95
+ this.log(`\nAuthenticated as ${result.user.email}`);
96
+ this.log(`Token saved to ${this.config.configDir}/config.json`);
97
+ return;
98
+ }
99
+ }
100
+ this.error('Code expired. Run `adapty auth login` again.', { exit: 1 });
101
+ }
102
+ finally {
103
+ process.removeListener('SIGINT', onSignal);
104
+ }
105
+ }
106
+ }
@@ -0,0 +1,9 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AuthLogout extends Command {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ run(): Promise<{
7
+ status: string;
8
+ }>;
9
+ }
@@ -0,0 +1,18 @@
1
+ import { Command } from '@oclif/core';
2
+ import { readConfig, writeConfig } from '../../lib/config.js';
3
+ export default class AuthLogout extends Command {
4
+ static description = 'Remove stored authentication token';
5
+ static enableJsonFlag = true;
6
+ static examples = ['<%= config.bin %> auth logout'];
7
+ async run() {
8
+ await this.parse(AuthLogout);
9
+ const config = await readConfig(this.config.configDir);
10
+ if (!config.access_token) {
11
+ this.log('Not currently authenticated.');
12
+ return { status: 'not_authenticated' };
13
+ }
14
+ await writeConfig({}, this.config.configDir);
15
+ this.log('Logged out. Note: token remains valid server-side until expiry.');
16
+ return { status: 'logged_out' };
17
+ }
18
+ }
@@ -0,0 +1,7 @@
1
+ import { Command } from '@oclif/core';
2
+ export default class AuthStatus extends Command {
3
+ static description: string;
4
+ static enableJsonFlag: boolean;
5
+ static examples: string[];
6
+ run(): Promise<Record<string, unknown>>;
7
+ }
@@ -0,0 +1,26 @@
1
+ import { Command } from '@oclif/core';
2
+ import { readConfig } from '../../lib/config.js';
3
+ export default class AuthStatus extends Command {
4
+ static description = 'Show current authentication state (local only)';
5
+ static enableJsonFlag = true;
6
+ static examples = ['<%= config.bin %> auth status'];
7
+ async run() {
8
+ await this.parse(AuthStatus);
9
+ const config = await readConfig(this.config.configDir);
10
+ if (!config.access_token || !config.user) {
11
+ this.log('Not authenticated. Run `adapty auth login`.');
12
+ return { authenticated: false };
13
+ }
14
+ const masked = config.access_token.slice(0, 8) + '****';
15
+ const configPath = `${this.config.configDir}/config.json`;
16
+ this.log(`Email: ${config.user.email}`);
17
+ this.log(`Token: ${masked}`);
18
+ this.log(`Config: ${configPath}`);
19
+ return {
20
+ authenticated: true,
21
+ config_path: configPath,
22
+ email: config.user.email,
23
+ token_prefix: config.access_token.slice(0, 8),
24
+ };
25
+ }
26
+ }
@@ -0,0 +1,16 @@
1
+ import { Command } from '@oclif/core';
2
+ interface MeResponse {
3
+ companies: Array<{
4
+ id: string;
5
+ title: string;
6
+ }>;
7
+ email: string;
8
+ name: string;
9
+ }
10
+ export default class AuthWhoami extends Command {
11
+ static description: string;
12
+ static enableJsonFlag: boolean;
13
+ static examples: string[];
14
+ run(): Promise<MeResponse>;
15
+ }
16
+ export {};
@@ -0,0 +1,21 @@
1
+ import { Command } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ export default class AuthWhoami extends Command {
4
+ static description = 'Show current user info from server (verifies token)';
5
+ static enableJsonFlag = true;
6
+ static examples = ['<%= config.bin %> auth whoami'];
7
+ async run() {
8
+ await this.parse(AuthWhoami);
9
+ const client = await createAuthenticatedClient(this.config);
10
+ const me = await client.get('/me');
11
+ this.log(`Email: ${me.email}`);
12
+ this.log(`Name: ${me.name}`);
13
+ if (me.companies.length > 0) {
14
+ this.log('Companies:');
15
+ for (const company of me.companies) {
16
+ this.log(` ${company.title} (${company.id})`);
17
+ }
18
+ }
19
+ return me;
20
+ }
21
+ }
@@ -0,0 +1,17 @@
1
+ import { Command } from '@oclif/core';
2
+ interface PaywallResponse {
3
+ id: string;
4
+ name: string;
5
+ }
6
+ export default class PaywallsCreate extends Command {
7
+ static description: string;
8
+ static enableJsonFlag: boolean;
9
+ static examples: string[];
10
+ static flags: {
11
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
12
+ 'product-id': import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
13
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ };
15
+ run(): Promise<PaywallResponse>;
16
+ }
17
+ export {};
@@ -0,0 +1,31 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag } from '../../lib/flags.js';
4
+ export default class PaywallsCreate extends Command {
5
+ static description = 'Create a paywall with products';
6
+ static enableJsonFlag = true;
7
+ static examples = [
8
+ '<%= config.bin %> paywalls create --app UUID --name "Default Paywall" --product-id UUID1 --product-id UUID2',
9
+ ];
10
+ static flags = {
11
+ ...appFlag,
12
+ name: Flags.string({ description: 'Paywall name', required: true }),
13
+ 'product-id': Flags.string({
14
+ description: 'Product ID (UUID). Repeat for multiple.',
15
+ multiple: true,
16
+ required: true,
17
+ }),
18
+ };
19
+ async run() {
20
+ const { flags } = await this.parse(PaywallsCreate);
21
+ const client = await createAuthenticatedClient(this.config);
22
+ const result = await client.post(`/apps/${flags.app}/paywalls`, {
23
+ name: flags.name,
24
+ product_ids: flags['product-id'],
25
+ });
26
+ this.log('Paywall created!');
27
+ this.log(`ID: ${result.id}`);
28
+ this.log(`Name: ${result.name}`);
29
+ return result;
30
+ }
31
+ }
@@ -0,0 +1,19 @@
1
+ import { Command } from '@oclif/core';
2
+ interface PaywallDetailResponse {
3
+ id: string;
4
+ name: string;
5
+ product_ids: string[];
6
+ }
7
+ export default class PaywallsGet extends Command {
8
+ static args: {
9
+ paywall_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
10
+ };
11
+ static description: string;
12
+ static enableJsonFlag: boolean;
13
+ static examples: string[];
14
+ static flags: {
15
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ run(): Promise<PaywallDetailResponse>;
18
+ }
19
+ export {};
@@ -0,0 +1,26 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag, isValidUuid } from '../../lib/flags.js';
4
+ export default class PaywallsGet extends Command {
5
+ static args = {
6
+ paywall_id: Args.string({ description: 'Paywall ID (UUID)', required: true }),
7
+ };
8
+ static description = 'Get paywall details';
9
+ static enableJsonFlag = true;
10
+ static examples = ['<%= config.bin %> paywalls get --app UUID 550e8400-e29b-41d4-a716-446655440000'];
11
+ static flags = {
12
+ ...appFlag,
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(PaywallsGet);
16
+ if (!isValidUuid(args.paywall_id)) {
17
+ this.error('Invalid paywall ID format.', { exit: 2 });
18
+ }
19
+ const client = await createAuthenticatedClient(this.config);
20
+ const result = await client.get(`/apps/${flags.app}/paywalls/${args.paywall_id}`);
21
+ this.log(`ID: ${result.id}`);
22
+ this.log(`Name: ${result.name}`);
23
+ this.log(`Product IDs: ${result.product_ids.join(', ')}`);
24
+ return result;
25
+ }
26
+ }
@@ -0,0 +1,18 @@
1
+ import { Command } from '@oclif/core';
2
+ import { type PaginatedResponse } from '../../lib/flags.js';
3
+ interface PaywallItem {
4
+ id: string;
5
+ name: string;
6
+ }
7
+ export default class PaywallsList extends Command {
8
+ static description: string;
9
+ static enableJsonFlag: boolean;
10
+ static examples: string[];
11
+ static flags: {
12
+ page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
13
+ 'page-size': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
14
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ };
16
+ run(): Promise<PaginatedResponse<PaywallItem>>;
17
+ }
18
+ export {};
@@ -0,0 +1,20 @@
1
+ import { Command } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag, paginationFlags, paginationParams } from '../../lib/flags.js';
4
+ import { printList } from '../../lib/output.js';
5
+ export default class PaywallsList extends Command {
6
+ static description = 'List paywalls for an app';
7
+ static enableJsonFlag = true;
8
+ static examples = ['<%= config.bin %> paywalls list --app 550e8400-...'];
9
+ static flags = {
10
+ ...appFlag,
11
+ ...paginationFlags,
12
+ };
13
+ async run() {
14
+ const { flags } = await this.parse(PaywallsList);
15
+ const client = await createAuthenticatedClient(this.config);
16
+ const result = await client.get(`/apps/${flags.app}/paywalls`, paginationParams(flags));
17
+ printList(result.data.map((pw) => ({ ID: pw.id, Name: pw.name })), this.log.bind(this), result.meta.pagination);
18
+ return result;
19
+ }
20
+ }
@@ -0,0 +1,20 @@
1
+ import { Command } from '@oclif/core';
2
+ interface PaywallResponse {
3
+ id: string;
4
+ name: string;
5
+ }
6
+ export default class PaywallsUpdate extends Command {
7
+ static args: {
8
+ paywall_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
9
+ };
10
+ static description: string;
11
+ static enableJsonFlag: boolean;
12
+ static examples: string[];
13
+ static flags: {
14
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ 'product-id': import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
16
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<PaywallResponse>;
19
+ }
20
+ export {};
@@ -0,0 +1,37 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag, isValidUuid } from '../../lib/flags.js';
4
+ export default class PaywallsUpdate extends Command {
5
+ static args = {
6
+ paywall_id: Args.string({ description: 'Paywall ID (UUID)', required: true }),
7
+ };
8
+ static description = 'Update a paywall';
9
+ static enableJsonFlag = true;
10
+ static examples = [
11
+ '<%= config.bin %> paywalls update --app UUID 550e8400-... --name "Default Paywall" --product-id UUID1 --product-id UUID2',
12
+ ];
13
+ static flags = {
14
+ ...appFlag,
15
+ name: Flags.string({ description: 'Paywall name', required: true }),
16
+ 'product-id': Flags.string({
17
+ description: 'Product ID (UUID). Repeat for multiple.',
18
+ multiple: true,
19
+ required: true,
20
+ }),
21
+ };
22
+ async run() {
23
+ const { args, flags } = await this.parse(PaywallsUpdate);
24
+ if (!isValidUuid(args.paywall_id)) {
25
+ this.error('Invalid paywall ID format.', { exit: 2 });
26
+ }
27
+ const client = await createAuthenticatedClient(this.config);
28
+ const result = await client.put(`/apps/${flags.app}/paywalls/${args.paywall_id}`, {
29
+ name: flags.name,
30
+ product_ids: flags['product-id'],
31
+ });
32
+ this.log('Paywall updated!');
33
+ this.log(`ID: ${result.id}`);
34
+ this.log(`Name: ${result.name}`);
35
+ return result;
36
+ }
37
+ }
@@ -0,0 +1,19 @@
1
+ import { Command } from '@oclif/core';
2
+ interface PlacementResponse {
3
+ developer_id: string;
4
+ id: string;
5
+ name: string;
6
+ }
7
+ export default class PlacementsCreate extends Command {
8
+ static description: string;
9
+ static enableJsonFlag: boolean;
10
+ static examples: string[];
11
+ static flags: {
12
+ 'developer-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
13
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'paywall-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
15
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ run(): Promise<PlacementResponse>;
18
+ }
19
+ export {};
@@ -0,0 +1,30 @@
1
+ import { Command, Flags } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag } from '../../lib/flags.js';
4
+ export default class PlacementsCreate extends Command {
5
+ static description = 'Create a placement with a paywall';
6
+ static enableJsonFlag = true;
7
+ static examples = [
8
+ '<%= config.bin %> placements create --app UUID --name "Default" --developer-id default --paywall-id UUID',
9
+ ];
10
+ static flags = {
11
+ ...appFlag,
12
+ 'developer-id': Flags.string({ description: 'Developer ID for the placement', required: true }),
13
+ name: Flags.string({ description: 'Placement name', required: true }),
14
+ 'paywall-id': Flags.string({ description: 'Paywall ID (UUID)', required: true }),
15
+ };
16
+ async run() {
17
+ const { flags } = await this.parse(PlacementsCreate);
18
+ const client = await createAuthenticatedClient(this.config);
19
+ const result = await client.post(`/apps/${flags.app}/placements`, {
20
+ developer_id: flags['developer-id'],
21
+ name: flags.name,
22
+ paywall_id: flags['paywall-id'],
23
+ });
24
+ this.log('Placement created!');
25
+ this.log(`ID: ${result.id}`);
26
+ this.log(`Developer ID: ${result.developer_id}`);
27
+ this.log(`Name: ${result.name}`);
28
+ return result;
29
+ }
30
+ }
@@ -0,0 +1,20 @@
1
+ import { Command } from '@oclif/core';
2
+ interface PlacementDetailResponse {
3
+ developer_id: string;
4
+ id: string;
5
+ name: string;
6
+ paywall_id: string;
7
+ }
8
+ export default class PlacementsGet extends Command {
9
+ static args: {
10
+ placement_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
11
+ };
12
+ static description: string;
13
+ static enableJsonFlag: boolean;
14
+ static examples: string[];
15
+ static flags: {
16
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ };
18
+ run(): Promise<PlacementDetailResponse>;
19
+ }
20
+ export {};
@@ -0,0 +1,27 @@
1
+ import { Args, Command } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag, isValidUuid } from '../../lib/flags.js';
4
+ export default class PlacementsGet extends Command {
5
+ static args = {
6
+ placement_id: Args.string({ description: 'Placement ID (UUID)', required: true }),
7
+ };
8
+ static description = 'Get placement details';
9
+ static enableJsonFlag = true;
10
+ static examples = ['<%= config.bin %> placements get --app UUID 550e8400-e29b-41d4-a716-446655440000'];
11
+ static flags = {
12
+ ...appFlag,
13
+ };
14
+ async run() {
15
+ const { args, flags } = await this.parse(PlacementsGet);
16
+ if (!isValidUuid(args.placement_id)) {
17
+ this.error('Invalid placement ID format.', { exit: 2 });
18
+ }
19
+ const client = await createAuthenticatedClient(this.config);
20
+ const result = await client.get(`/apps/${flags.app}/placements/${args.placement_id}`);
21
+ this.log(`ID: ${result.id}`);
22
+ this.log(`Name: ${result.name}`);
23
+ this.log(`Developer ID: ${result.developer_id}`);
24
+ this.log(`Paywall ID: ${result.paywall_id}`);
25
+ return result;
26
+ }
27
+ }
@@ -0,0 +1,19 @@
1
+ import { Command } from '@oclif/core';
2
+ import { type PaginatedResponse } from '../../lib/flags.js';
3
+ interface PlacementItem {
4
+ developer_id: string;
5
+ id: string;
6
+ name: string;
7
+ }
8
+ export default class PlacementsList extends Command {
9
+ static description: string;
10
+ static enableJsonFlag: boolean;
11
+ static examples: string[];
12
+ static flags: {
13
+ page: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
14
+ 'page-size': import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
15
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ };
17
+ run(): Promise<PaginatedResponse<PlacementItem>>;
18
+ }
19
+ export {};
@@ -0,0 +1,20 @@
1
+ import { Command } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag, paginationFlags, paginationParams } from '../../lib/flags.js';
4
+ import { printList } from '../../lib/output.js';
5
+ export default class PlacementsList extends Command {
6
+ static description = 'List placements for an app';
7
+ static enableJsonFlag = true;
8
+ static examples = ['<%= config.bin %> placements list --app 550e8400-...'];
9
+ static flags = {
10
+ ...appFlag,
11
+ ...paginationFlags,
12
+ };
13
+ async run() {
14
+ const { flags } = await this.parse(PlacementsList);
15
+ const client = await createAuthenticatedClient(this.config);
16
+ const result = await client.get(`/apps/${flags.app}/placements`, paginationParams(flags));
17
+ printList(result.data.map((pl) => ({ 'Developer ID': pl.developer_id, ID: pl.id, Name: pl.name })), this.log.bind(this), result.meta.pagination);
18
+ return result;
19
+ }
20
+ }
@@ -0,0 +1,22 @@
1
+ import { Command } from '@oclif/core';
2
+ interface PlacementResponse {
3
+ developer_id: string;
4
+ id: string;
5
+ name: string;
6
+ }
7
+ export default class PlacementsUpdate extends Command {
8
+ static args: {
9
+ placement_id: import("@oclif/core/interfaces").Arg<string, Record<string, unknown>>;
10
+ };
11
+ static description: string;
12
+ static enableJsonFlag: boolean;
13
+ static examples: string[];
14
+ static flags: {
15
+ 'developer-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
16
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
17
+ 'paywall-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
18
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
19
+ };
20
+ run(): Promise<PlacementResponse>;
21
+ }
22
+ export {};
@@ -0,0 +1,36 @@
1
+ import { Args, Command, Flags } from '@oclif/core';
2
+ import { createAuthenticatedClient } from '../../lib/client-from-config.js';
3
+ import { appFlag, isValidUuid } from '../../lib/flags.js';
4
+ export default class PlacementsUpdate extends Command {
5
+ static args = {
6
+ placement_id: Args.string({ description: 'Placement ID (UUID)', required: true }),
7
+ };
8
+ static description = 'Update a placement';
9
+ static enableJsonFlag = true;
10
+ static examples = [
11
+ '<%= config.bin %> placements update --app UUID 550e8400-... --name "Default" --developer-id default --paywall-id UUID',
12
+ ];
13
+ static flags = {
14
+ ...appFlag,
15
+ 'developer-id': Flags.string({ description: 'Developer ID for the placement', required: true }),
16
+ name: Flags.string({ description: 'Placement name', required: true }),
17
+ 'paywall-id': Flags.string({ description: 'Paywall ID (UUID)', required: true }),
18
+ };
19
+ async run() {
20
+ const { args, flags } = await this.parse(PlacementsUpdate);
21
+ if (!isValidUuid(args.placement_id)) {
22
+ this.error('Invalid placement ID format.', { exit: 2 });
23
+ }
24
+ const client = await createAuthenticatedClient(this.config);
25
+ const result = await client.put(`/apps/${flags.app}/placements/${args.placement_id}`, {
26
+ developer_id: flags['developer-id'],
27
+ name: flags.name,
28
+ paywall_id: flags['paywall-id'],
29
+ });
30
+ this.log('Placement updated!');
31
+ this.log(`ID: ${result.id}`);
32
+ this.log(`Developer ID: ${result.developer_id}`);
33
+ this.log(`Name: ${result.name}`);
34
+ return result;
35
+ }
36
+ }
@@ -0,0 +1,33 @@
1
+ import { Command } from '@oclif/core';
2
+ interface VendorProducts {
3
+ android?: {
4
+ base_plan_id?: string;
5
+ id: string;
6
+ product_id: string;
7
+ };
8
+ ios?: {
9
+ id: string;
10
+ product_id: string;
11
+ };
12
+ }
13
+ interface ProductResponse {
14
+ id: string;
15
+ name: string;
16
+ vendor_products: VendorProducts;
17
+ }
18
+ export default class ProductsCreate extends Command {
19
+ static description: string;
20
+ static enableJsonFlag: boolean;
21
+ static examples: string[];
22
+ static flags: {
23
+ 'access-level-id': import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
24
+ 'android-base-plan-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
25
+ 'android-product-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
26
+ 'ios-product-id': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
27
+ name: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
28
+ period: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
29
+ app: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
30
+ };
31
+ run(): Promise<ProductResponse>;
32
+ }
33
+ export {};