@zapier/zapier-sdk 0.5.1 → 0.6.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.
- package/CHANGELOG.md +19 -0
- package/README.md +107 -83
- package/dist/api/index.d.ts +1 -1
- package/dist/api/index.d.ts.map +1 -1
- package/dist/api/schemas.d.ts +6 -6
- package/dist/api/types.d.ts +7 -7
- package/dist/api/types.d.ts.map +1 -1
- package/dist/index.cjs +343 -67
- package/dist/index.d.mts +416 -347
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.mjs +343 -67
- package/dist/plugins/api/index.js +1 -1
- package/dist/plugins/apps/types.d.ts +1 -1
- package/dist/plugins/apps/types.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.js +1 -0
- package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findUniqueAuthentication/index.js +1 -0
- package/dist/plugins/getAction/index.d.ts.map +1 -1
- package/dist/plugins/getAction/index.js +1 -0
- package/dist/plugins/getAction/index.test.js +1 -1
- package/dist/plugins/getApp/index.d.ts +6 -3
- package/dist/plugins/getApp/index.d.ts.map +1 -1
- package/dist/plugins/getApp/index.js +8 -18
- package/dist/plugins/getApp/index.test.js +2 -0
- package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/getAuthentication/index.js +1 -0
- package/dist/plugins/getAuthentication/index.test.js +12 -1
- package/dist/plugins/getProfile/index.d.ts.map +1 -1
- package/dist/plugins/getProfile/index.js +1 -0
- package/dist/plugins/listActions/index.d.ts +5 -3
- package/dist/plugins/listActions/index.d.ts.map +1 -1
- package/dist/plugins/listActions/index.js +6 -6
- package/dist/plugins/listActions/index.test.js +26 -74
- package/dist/plugins/listActions/schemas.d.ts +4 -4
- package/dist/plugins/listApps/index.d.ts.map +1 -1
- package/dist/plugins/listApps/index.js +1 -0
- package/dist/plugins/listApps/schemas.d.ts +2 -2
- package/dist/plugins/listAuthentications/index.d.ts +4 -2
- package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
- package/dist/plugins/listAuthentications/index.js +9 -12
- package/dist/plugins/listAuthentications/index.test.js +33 -40
- package/dist/plugins/listAuthentications/schemas.d.ts +4 -4
- package/dist/plugins/listInputFields/index.d.ts +3 -1
- package/dist/plugins/listInputFields/index.d.ts.map +1 -1
- package/dist/plugins/listInputFields/index.js +5 -5
- package/dist/plugins/listInputFields/index.test.js +10 -8
- package/dist/plugins/listInputFields/schemas.d.ts +4 -4
- package/dist/plugins/lockVersion/index.d.ts +24 -0
- package/dist/plugins/lockVersion/index.d.ts.map +1 -0
- package/dist/plugins/lockVersion/index.js +72 -0
- package/dist/plugins/lockVersion/index.test.d.ts +2 -0
- package/dist/plugins/lockVersion/index.test.d.ts.map +1 -0
- package/dist/plugins/lockVersion/index.test.js +129 -0
- package/dist/plugins/lockVersion/schemas.d.ts +10 -0
- package/dist/plugins/lockVersion/schemas.d.ts.map +1 -0
- package/dist/plugins/lockVersion/schemas.js +6 -0
- package/dist/plugins/manifest/index.d.ts +24 -0
- package/dist/plugins/manifest/index.d.ts.map +1 -0
- package/dist/plugins/manifest/index.js +119 -0
- package/dist/plugins/manifest/index.test.d.ts +2 -0
- package/dist/plugins/manifest/index.test.d.ts.map +1 -0
- package/dist/plugins/manifest/index.test.js +331 -0
- package/dist/plugins/manifest/schemas.d.ts +64 -0
- package/dist/plugins/manifest/schemas.d.ts.map +1 -0
- package/dist/plugins/manifest/schemas.js +25 -0
- package/dist/plugins/registry/index.d.ts +9 -1
- package/dist/plugins/registry/index.d.ts.map +1 -1
- package/dist/plugins/registry/index.js +68 -3
- package/dist/plugins/request/index.d.ts.map +1 -1
- package/dist/plugins/request/index.js +1 -0
- package/dist/plugins/request/index.test.js +6 -1
- package/dist/plugins/request/schemas.d.ts +4 -4
- package/dist/plugins/runAction/index.d.ts +2 -0
- package/dist/plugins/runAction/index.d.ts.map +1 -1
- package/dist/plugins/runAction/index.js +5 -5
- package/dist/plugins/runAction/index.test.js +9 -8
- package/dist/plugins/runAction/schemas.d.ts +4 -4
- package/dist/schemas/Auth.d.ts +4 -4
- package/dist/schemas/Field.d.ts.map +1 -1
- package/dist/sdk.d.ts +3 -3
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +18 -7
- package/dist/sdk.test.js +1 -1
- package/dist/types/errors.d.ts +6 -6
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/events.d.ts +1 -1
- package/dist/types/events.d.ts.map +1 -1
- package/dist/types/plugin.d.ts +10 -2
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/sdk.d.ts +13 -2
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/utils/validation.test.js +2 -1
- package/package.json +2 -2
- package/src/api/client.ts +3 -3
- package/src/api/index.ts +2 -0
- package/src/api/types.ts +15 -7
- package/src/index.ts +0 -2
- package/src/plugins/api/index.ts +1 -1
- package/src/plugins/apps/types.ts +1 -1
- package/src/plugins/findFirstAuthentication/index.ts +1 -0
- package/src/plugins/findUniqueAuthentication/index.ts +1 -0
- package/src/plugins/getAction/index.test.ts +1 -1
- package/src/plugins/getAction/index.ts +1 -0
- package/src/plugins/getApp/index.test.ts +2 -0
- package/src/plugins/getApp/index.ts +12 -24
- package/src/plugins/getAuthentication/index.test.ts +13 -3
- package/src/plugins/getAuthentication/index.ts +1 -0
- package/src/plugins/getProfile/index.ts +1 -0
- package/src/plugins/listActions/index.test.ts +30 -89
- package/src/plugins/listActions/index.ts +34 -27
- package/src/plugins/listApps/index.ts +1 -0
- package/src/plugins/listAuthentications/index.test.ts +38 -47
- package/src/plugins/listAuthentications/index.ts +21 -18
- package/src/plugins/listInputFields/index.test.ts +12 -9
- package/src/plugins/listInputFields/index.ts +10 -6
- package/src/plugins/lockVersion/index.test.ts +176 -0
- package/src/plugins/lockVersion/index.ts +112 -0
- package/src/plugins/lockVersion/schemas.ts +9 -0
- package/src/plugins/manifest/index.test.ts +439 -0
- package/src/plugins/manifest/index.ts +171 -0
- package/src/plugins/manifest/schemas.ts +53 -0
- package/src/plugins/registry/index.ts +89 -8
- package/src/plugins/request/index.test.ts +8 -4
- package/src/plugins/request/index.ts +1 -0
- package/src/plugins/runAction/index.test.ts +9 -8
- package/src/plugins/runAction/index.ts +18 -9
- package/src/schemas/Field.ts +5 -2
- package/src/sdk.test.ts +1 -1
- package/src/sdk.ts +22 -7
- package/src/types/errors.ts +9 -6
- package/src/types/events.ts +1 -1
- package/src/types/plugin.ts +14 -2
- package/src/types/sdk.ts +15 -1
- package/src/utils/validation.test.ts +2 -1
- package/tsconfig.tsbuildinfo +1 -1
|
@@ -36,37 +36,46 @@ const mockAuthenticationsResponse = {
|
|
|
36
36
|
previous: null,
|
|
37
37
|
};
|
|
38
38
|
const mockSlackApp = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
api_docs_url: "https://slack.com/api-docs",
|
|
46
|
-
app_profile_url: "https://slack.com",
|
|
47
|
-
banner: "https://slack.com/banner.png",
|
|
48
|
-
categories: [],
|
|
49
|
-
canonical_id: "slack",
|
|
50
|
-
zap_usage_count: 100,
|
|
51
|
-
zap_usage_count_last_updated: "2021-01-01",
|
|
52
|
-
zap_usage_count_last_updated_by: "user1",
|
|
53
|
-
zap_usage_count_last_updated_by_id: 123,
|
|
54
|
-
current_implementation_id: "SlackCLIAPI@1.21.1",
|
|
55
|
-
},
|
|
39
|
+
title: "Slack",
|
|
40
|
+
key: "SlackCLIAPI",
|
|
41
|
+
current_implementation_id: "SlackCLIAPI@1.21.1",
|
|
42
|
+
version: "1.21.1",
|
|
43
|
+
description: "Team communication platform",
|
|
44
|
+
slug: "slack",
|
|
56
45
|
};
|
|
57
46
|
describe("listAuthentications plugin", () => {
|
|
58
47
|
let mockApiClient;
|
|
59
|
-
let
|
|
48
|
+
let mockGetVersionedImplementationId;
|
|
60
49
|
beforeEach(() => {
|
|
61
50
|
vi.clearAllMocks();
|
|
62
51
|
mockApiClient = {
|
|
63
52
|
get: vi.fn().mockResolvedValue(mockAuthenticationsResponse),
|
|
64
53
|
};
|
|
65
|
-
|
|
54
|
+
mockGetVersionedImplementationId = vi
|
|
55
|
+
.fn()
|
|
56
|
+
.mockResolvedValue("SlackCLIAPI@1.21.1");
|
|
57
|
+
});
|
|
58
|
+
const apiPlugin = () => ({
|
|
59
|
+
context: {
|
|
60
|
+
api: mockApiClient,
|
|
61
|
+
},
|
|
62
|
+
});
|
|
63
|
+
const manifestPlugin = () => ({
|
|
64
|
+
context: {
|
|
65
|
+
manifest: null,
|
|
66
|
+
getVersionedImplementationId: mockGetVersionedImplementationId,
|
|
67
|
+
getManifestEntry: () => ({
|
|
68
|
+
implementationName: "SlackCLIAPI",
|
|
69
|
+
version: "1.21.1",
|
|
70
|
+
}),
|
|
71
|
+
getImplementation: vi.fn().mockResolvedValue(mockSlackApp),
|
|
72
|
+
},
|
|
66
73
|
});
|
|
67
74
|
function createTestSdk() {
|
|
68
|
-
return createSdk(
|
|
69
|
-
|
|
75
|
+
return createSdk()
|
|
76
|
+
.addPlugin(apiPlugin)
|
|
77
|
+
.addPlugin(manifestPlugin)
|
|
78
|
+
.addPlugin(listAuthenticationsPlugin);
|
|
70
79
|
}
|
|
71
80
|
describe("schema validation", () => {
|
|
72
81
|
it("should pass validation with empty options", async () => {
|
|
@@ -165,7 +174,7 @@ describe("listAuthentications plugin", () => {
|
|
|
165
174
|
describe("data mapping", () => {
|
|
166
175
|
it("should map is_stale to is_expired and marked_stale_at to expired_at", async () => {
|
|
167
176
|
const sdk = createTestSdk();
|
|
168
|
-
const result = await sdk.listAuthentications(
|
|
177
|
+
const result = await sdk.listAuthentications();
|
|
169
178
|
expect(result.data[0].is_expired).toBe("false");
|
|
170
179
|
expect(result.data[0].expired_at).toBe(null);
|
|
171
180
|
expect(result.data[1].is_expired).toBe("true");
|
|
@@ -459,15 +468,7 @@ describe("listAuthentications plugin", () => {
|
|
|
459
468
|
});
|
|
460
469
|
describe("app key integration", () => {
|
|
461
470
|
it("should handle app without current_implementation_id", async () => {
|
|
462
|
-
|
|
463
|
-
data: {
|
|
464
|
-
id: 123,
|
|
465
|
-
key: "slack",
|
|
466
|
-
title: "Slack",
|
|
467
|
-
current_implementation_id: undefined,
|
|
468
|
-
},
|
|
469
|
-
};
|
|
470
|
-
mockGetApp.mockResolvedValue(appWithoutImplementation);
|
|
471
|
+
mockGetVersionedImplementationId.mockResolvedValue(null);
|
|
471
472
|
const sdk = createTestSdk();
|
|
472
473
|
await sdk.listAuthentications({ appKey: "slack" });
|
|
473
474
|
// Should not add versionless_selected_api parameter
|
|
@@ -478,15 +479,7 @@ describe("listAuthentications plugin", () => {
|
|
|
478
479
|
}));
|
|
479
480
|
});
|
|
480
481
|
it("should extract versionless API from versioned implementation ID", async () => {
|
|
481
|
-
|
|
482
|
-
data: {
|
|
483
|
-
id: 123,
|
|
484
|
-
key: "slack",
|
|
485
|
-
title: "Slack",
|
|
486
|
-
current_implementation_id: "SlackCLIAPI@2.1.3",
|
|
487
|
-
},
|
|
488
|
-
};
|
|
489
|
-
mockGetApp.mockResolvedValue(appWithVersionedApi);
|
|
482
|
+
mockGetVersionedImplementationId.mockResolvedValue("SlackCLIAPI@2.1.3");
|
|
490
483
|
const sdk = createTestSdk();
|
|
491
484
|
await sdk.listAuthentications({ appKey: "slack" });
|
|
492
485
|
expect(mockApiClient.get).toHaveBeenCalledWith("/api/v4/authentications/", expect.objectContaining({
|
|
@@ -13,17 +13,17 @@ export declare const ListAuthenticationsSchema: z.ZodObject<{
|
|
|
13
13
|
title?: string | undefined;
|
|
14
14
|
search?: string | undefined;
|
|
15
15
|
account_id?: string | undefined;
|
|
16
|
-
maxItems?: number | undefined;
|
|
17
|
-
pageSize?: number | undefined;
|
|
18
16
|
appKey?: string | undefined;
|
|
17
|
+
pageSize?: number | undefined;
|
|
18
|
+
maxItems?: number | undefined;
|
|
19
19
|
owner?: string | undefined;
|
|
20
20
|
}, {
|
|
21
21
|
title?: string | undefined;
|
|
22
22
|
search?: string | undefined;
|
|
23
23
|
account_id?: string | undefined;
|
|
24
|
-
maxItems?: number | undefined;
|
|
25
|
-
pageSize?: number | undefined;
|
|
26
24
|
appKey?: string | undefined;
|
|
25
|
+
pageSize?: number | undefined;
|
|
26
|
+
maxItems?: number | undefined;
|
|
27
27
|
owner?: string | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
export type ListAuthenticationsOptions = z.infer<typeof ListAuthenticationsSchema>;
|
|
@@ -3,6 +3,7 @@ import type { ApiClient } from "../../api";
|
|
|
3
3
|
import type { InputFieldItem } from "../../types/domain";
|
|
4
4
|
import { ListInputFieldsSchema, type ListInputFieldsOptions } from "./schemas";
|
|
5
5
|
import type { GetAppPluginProvides } from "../getApp";
|
|
6
|
+
import { GetVersionedImplementationId } from "../manifest/schemas";
|
|
6
7
|
export interface ListInputFieldsPluginProvides {
|
|
7
8
|
listInputFields: (options?: ListInputFieldsOptions) => Promise<{
|
|
8
9
|
data: InputFieldItem[];
|
|
@@ -23,6 +24,7 @@ export interface ListInputFieldsPluginProvides {
|
|
|
23
24
|
export declare const listInputFieldsPlugin: Plugin<GetSdkType<GetAppPluginProvides>, // requires getApp in SDK
|
|
24
25
|
{
|
|
25
26
|
api: ApiClient;
|
|
26
|
-
|
|
27
|
+
getVersionedImplementationId: GetVersionedImplementationId;
|
|
28
|
+
}, // requires api and getVersionedImplementationId in context
|
|
27
29
|
ListInputFieldsPluginProvides>;
|
|
28
30
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/listInputFields/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EACL,qBAAqB,EACrB,KAAK,sBAAsB,EAE5B,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/listInputFields/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAE3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,EACL,qBAAqB,EACrB,KAAK,sBAAsB,EAE5B,MAAM,WAAW,CAAC;AAGnB,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACtD,OAAO,EAAE,4BAA4B,EAAE,MAAM,qBAAqB,CAAC;AAkGnE,MAAM,WAAW,6BAA6B;IAC5C,eAAe,EAAE,CAAC,OAAO,CAAC,EAAE,sBAAsB,KAAK,OAAO,CAAC;QAC7D,IAAI,EAAE,cAAc,EAAE,CAAC;KACxB,CAAC,GACA,aAAa,CAAC;QAAE,IAAI,EAAE,cAAc,EAAE,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,GAAG;QAC/D,KAAK,IAAI,aAAa,CAAC,cAAc,CAAC,CAAC;KACxC,CAAC;IACJ,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,eAAe,EAAE;gBACf,WAAW,EAAE,OAAO,qBAAqB,CAAC;aAC3C,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,qBAAqB,EAAE,MAAM,CACxC,UAAU,CAAC,oBAAoB,CAAC,EAAE,yBAAyB;AAC3D;IACE,GAAG,EAAE,SAAS,CAAC;IACf,4BAA4B,EAAE,4BAA4B,CAAC;CAC5D,EAAE,2DAA2D;AAC9D,6BAA6B,CA2E9B,CAAC"}
|
|
@@ -86,15 +86,14 @@ function transformNeedToInputFieldItem(need) {
|
|
|
86
86
|
items: itemsType ? { type: itemsType } : undefined,
|
|
87
87
|
};
|
|
88
88
|
}
|
|
89
|
-
export const listInputFieldsPlugin = ({
|
|
89
|
+
export const listInputFieldsPlugin = ({ context }) => {
|
|
90
90
|
const listInputFields = createPaginatedFunction(async function listInputFieldsPage(options) {
|
|
91
91
|
// Note: This function ignores pageSize and cursor since it's not actually paginated internally
|
|
92
|
-
const { api } = context;
|
|
92
|
+
const { api, getVersionedImplementationId } = context;
|
|
93
93
|
// Extract parameters
|
|
94
94
|
const { appKey, actionKey, actionType, authenticationId, inputs } = options;
|
|
95
|
-
// Use the
|
|
96
|
-
const
|
|
97
|
-
const selectedApi = appData.data.current_implementation_id;
|
|
95
|
+
// Use the manifest plugin
|
|
96
|
+
const selectedApi = await getVersionedImplementationId(appKey);
|
|
98
97
|
if (!selectedApi) {
|
|
99
98
|
throw new ZapierConfigurationError("No current_implementation_id found for app", { configType: "current_implementation_id" });
|
|
100
99
|
}
|
|
@@ -125,6 +124,7 @@ export const listInputFieldsPlugin = ({ sdk, context }) => {
|
|
|
125
124
|
context: {
|
|
126
125
|
meta: {
|
|
127
126
|
listInputFields: {
|
|
127
|
+
categories: ["action"],
|
|
128
128
|
inputSchema: ListInputFieldsSchema,
|
|
129
129
|
},
|
|
130
130
|
},
|
|
@@ -37,18 +37,22 @@ const mockNeedsResponse = {
|
|
|
37
37
|
};
|
|
38
38
|
describe("listInputFields plugin", () => {
|
|
39
39
|
let mockApiClient;
|
|
40
|
-
let
|
|
40
|
+
let mockGetVersionedImplementationId;
|
|
41
41
|
beforeEach(() => {
|
|
42
42
|
vi.clearAllMocks();
|
|
43
43
|
mockApiClient = {
|
|
44
44
|
post: vi.fn().mockResolvedValue(mockNeedsResponse),
|
|
45
45
|
};
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
mockGetVersionedImplementationId = vi
|
|
47
|
+
.fn()
|
|
48
|
+
.mockResolvedValue("SlackCLIAPI@1.21.1");
|
|
49
49
|
});
|
|
50
50
|
function createTestSdk() {
|
|
51
|
-
return createSdk({
|
|
51
|
+
return createSdk({}, {}, {
|
|
52
|
+
api: mockApiClient,
|
|
53
|
+
meta: {},
|
|
54
|
+
getVersionedImplementationId: mockGetVersionedImplementationId,
|
|
55
|
+
}).addPlugin(listInputFieldsPlugin);
|
|
52
56
|
}
|
|
53
57
|
describe("schema validation", () => {
|
|
54
58
|
it("should throw validation error for missing required fields", () => {
|
|
@@ -244,9 +248,7 @@ describe("listInputFields plugin", () => {
|
|
|
244
248
|
});
|
|
245
249
|
describe("error handling", () => {
|
|
246
250
|
it("should throw ZapierConfigurationError when app has no current_implementation_id", async () => {
|
|
247
|
-
|
|
248
|
-
data: { current_implementation_id: undefined },
|
|
249
|
-
});
|
|
251
|
+
mockGetVersionedImplementationId.mockResolvedValue(null);
|
|
250
252
|
const sdk = createTestSdk();
|
|
251
253
|
await expect(sdk.listInputFields({
|
|
252
254
|
appKey: "invalid",
|
|
@@ -14,17 +14,17 @@ export declare const ListInputFieldsSchema: z.ZodObject<{
|
|
|
14
14
|
actionType: "filter" | "read" | "read_bulk" | "run" | "search" | "search_and_write" | "search_or_write" | "write";
|
|
15
15
|
actionKey: string;
|
|
16
16
|
authenticationId?: number | null | undefined;
|
|
17
|
-
maxItems?: number | undefined;
|
|
18
|
-
pageSize?: number | undefined;
|
|
19
17
|
inputs?: Record<string, any> | undefined;
|
|
18
|
+
pageSize?: number | undefined;
|
|
19
|
+
maxItems?: number | undefined;
|
|
20
20
|
}, {
|
|
21
21
|
appKey: string;
|
|
22
22
|
actionType: "filter" | "read" | "read_bulk" | "run" | "search" | "search_and_write" | "search_or_write" | "write";
|
|
23
23
|
actionKey: string;
|
|
24
24
|
authenticationId?: number | null | undefined;
|
|
25
|
-
maxItems?: number | undefined;
|
|
26
|
-
pageSize?: number | undefined;
|
|
27
25
|
inputs?: Record<string, any> | undefined;
|
|
26
|
+
pageSize?: number | undefined;
|
|
27
|
+
maxItems?: number | undefined;
|
|
28
28
|
}>;
|
|
29
29
|
export type ListInputFieldsOptions = z.infer<typeof ListInputFieldsSchema>;
|
|
30
30
|
export type ListInputFieldsError = import("../../types/errors").ZapierConfigurationError | import("../../types/errors").ZapierApiError | import("../../types/errors").ZapierAuthenticationError | import("../../types/errors").ZapierAppNotFoundError | import("../../types/errors").ZapierValidationError | import("../../types/errors").ZapierUnknownError;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { Plugin, GetSdkType } from "../../types/plugin";
|
|
2
|
+
import { LockVersionSchema } from "./schemas";
|
|
3
|
+
import type { LockVersionOptions } from "./schemas";
|
|
4
|
+
import type { AppItem } from "../../types/domain";
|
|
5
|
+
import { ListAppsPluginProvides } from "../listApps";
|
|
6
|
+
export interface LockVersionPluginProvides {
|
|
7
|
+
lockVersion: (options: LockVersionOptions & {
|
|
8
|
+
configPath?: string;
|
|
9
|
+
}) => Promise<{
|
|
10
|
+
data: AppItem;
|
|
11
|
+
configPath: string;
|
|
12
|
+
}>;
|
|
13
|
+
context: {
|
|
14
|
+
meta: {
|
|
15
|
+
lockVersion: {
|
|
16
|
+
inputSchema: typeof LockVersionSchema;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare const lockVersionPlugin: Plugin<GetSdkType<ListAppsPluginProvides>, // requires getApp in SDK
|
|
22
|
+
{}, // requires manifest context
|
|
23
|
+
LockVersionPluginProvides>;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/lockVersion/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAE7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AACpD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,oBAAoB,CAAC;AAIlD,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAErD,MAAM,WAAW,yBAAyB;IACxC,WAAW,EAAE,CACX,OAAO,EAAE,kBAAkB,GAAG;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,KAClD,OAAO,CAAC;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpD,OAAO,EAAE;QACP,IAAI,EAAE;YACJ,WAAW,EAAE;gBACX,WAAW,EAAE,OAAO,iBAAiB,CAAC;aACvC,CAAC;SACH,CAAC;KACH,CAAC;CACH;AAED,eAAO,MAAM,iBAAiB,EAAE,MAAM,CACpC,UAAU,CAAC,sBAAsB,CAAC,EAAE,yBAAyB;AAC7D,EAAE,EAAE,4BAA4B;AAChC,yBAAyB,CAqF1B,CAAC"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { createFunction } from "../../utils/function-utils";
|
|
2
|
+
import { LockVersionSchema } from "./schemas";
|
|
3
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
import { z } from "zod";
|
|
6
|
+
export const lockVersionPlugin = ({ sdk }) => {
|
|
7
|
+
const lockVersion = createFunction(async function lockVersion(options) {
|
|
8
|
+
const { appKey, configPath = ".zapierrc" } = options;
|
|
9
|
+
const resolvedPath = resolve(configPath);
|
|
10
|
+
// Get the current app information
|
|
11
|
+
const appsIterator = sdk.listApps({ appKeys: [appKey] }).items();
|
|
12
|
+
const apps = [];
|
|
13
|
+
for await (const app of appsIterator) {
|
|
14
|
+
apps.push(app);
|
|
15
|
+
break; // Only need the first result
|
|
16
|
+
}
|
|
17
|
+
const app = apps[0];
|
|
18
|
+
// Extract implementation name and version from current_implementation_id
|
|
19
|
+
const currentImplementationId = app.current_implementation_id;
|
|
20
|
+
const [implementationName, version] = currentImplementationId.split("@");
|
|
21
|
+
if (!implementationName || !version) {
|
|
22
|
+
throw new Error(`Invalid implementation ID format: ${currentImplementationId}. Expected format: <implementationName>@<version>`);
|
|
23
|
+
}
|
|
24
|
+
// Read existing config or create new one
|
|
25
|
+
let config = { apps: {} };
|
|
26
|
+
if (existsSync(resolvedPath)) {
|
|
27
|
+
try {
|
|
28
|
+
const configContent = readFileSync(resolvedPath, "utf8");
|
|
29
|
+
config = JSON.parse(configContent);
|
|
30
|
+
// Ensure apps property exists
|
|
31
|
+
if (!config.apps) {
|
|
32
|
+
config.apps = {};
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
catch (error) {
|
|
36
|
+
console.warn(`⚠️ Failed to parse existing config file, creating new one: ${error}`);
|
|
37
|
+
config = { apps: {} };
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// Update the apps section
|
|
41
|
+
config.apps[appKey] = {
|
|
42
|
+
implementationName,
|
|
43
|
+
version,
|
|
44
|
+
};
|
|
45
|
+
// Write the updated config
|
|
46
|
+
writeFileSync(resolvedPath, JSON.stringify(config, null, 2));
|
|
47
|
+
return {
|
|
48
|
+
data: {
|
|
49
|
+
...app,
|
|
50
|
+
implementationName,
|
|
51
|
+
version,
|
|
52
|
+
},
|
|
53
|
+
configPath: resolvedPath,
|
|
54
|
+
};
|
|
55
|
+
}, LockVersionSchema.extend({
|
|
56
|
+
configPath: z
|
|
57
|
+
.string()
|
|
58
|
+
.optional()
|
|
59
|
+
.describe("Path to .zapierrc file (defaults to '.zapierrc')"),
|
|
60
|
+
}));
|
|
61
|
+
return {
|
|
62
|
+
lockVersion,
|
|
63
|
+
context: {
|
|
64
|
+
meta: {
|
|
65
|
+
lockVersion: {
|
|
66
|
+
categories: ["utility"],
|
|
67
|
+
inputSchema: LockVersionSchema,
|
|
68
|
+
},
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
};
|
|
72
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.test.d.ts","sourceRoot":"","sources":["../../../src/plugins/lockVersion/index.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { describe, it, expect, vi, beforeEach } from "vitest";
|
|
2
|
+
import { lockVersionPlugin } from "./index";
|
|
3
|
+
import { createSdk } from "../../sdk";
|
|
4
|
+
// Mock fs module
|
|
5
|
+
vi.mock("fs", () => ({
|
|
6
|
+
readFileSync: vi.fn(),
|
|
7
|
+
writeFileSync: vi.fn(),
|
|
8
|
+
existsSync: vi.fn(),
|
|
9
|
+
}));
|
|
10
|
+
// Mock path module
|
|
11
|
+
vi.mock("path", () => ({
|
|
12
|
+
resolve: vi.fn((path) => `/resolved/${path}`),
|
|
13
|
+
}));
|
|
14
|
+
import { readFileSync, writeFileSync, existsSync } from "fs";
|
|
15
|
+
import { resolve } from "path";
|
|
16
|
+
import { apiPlugin } from "../api";
|
|
17
|
+
const mockReadFileSync = vi.mocked(readFileSync);
|
|
18
|
+
const mockWriteFileSync = vi.mocked(writeFileSync);
|
|
19
|
+
const mockExistsSync = vi.mocked(existsSync);
|
|
20
|
+
const mockResolve = vi.mocked(resolve);
|
|
21
|
+
describe("lockVersion plugin", () => {
|
|
22
|
+
let mockSdk;
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vi.clearAllMocks();
|
|
25
|
+
mockSdk = {
|
|
26
|
+
listApps: vi.fn().mockReturnValue({
|
|
27
|
+
items: vi.fn().mockReturnValue([
|
|
28
|
+
{
|
|
29
|
+
title: "Gmail",
|
|
30
|
+
key: "GmailCLIAPI",
|
|
31
|
+
current_implementation_id: "GmailCLIAPI@2.1.0",
|
|
32
|
+
description: "Email service",
|
|
33
|
+
},
|
|
34
|
+
][Symbol.iterator]()),
|
|
35
|
+
}),
|
|
36
|
+
};
|
|
37
|
+
});
|
|
38
|
+
const listAppsPlugin = () => ({
|
|
39
|
+
listApps: mockSdk.listApps,
|
|
40
|
+
context: {
|
|
41
|
+
meta: {
|
|
42
|
+
listApps: {
|
|
43
|
+
inputSchema: {},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
});
|
|
48
|
+
function createTestSdk() {
|
|
49
|
+
return createSdk()
|
|
50
|
+
.addPlugin(apiPlugin)
|
|
51
|
+
.addPlugin(listAppsPlugin)
|
|
52
|
+
.addPlugin(lockVersionPlugin);
|
|
53
|
+
}
|
|
54
|
+
describe("version locking", () => {
|
|
55
|
+
it("should extract implementation name and version and write to file", async () => {
|
|
56
|
+
mockExistsSync.mockReturnValue(false);
|
|
57
|
+
mockResolve.mockReturnValue("/resolved/.zapierrc");
|
|
58
|
+
const sdk = createTestSdk();
|
|
59
|
+
const result = await sdk.lockVersion({ appKey: "gmail" });
|
|
60
|
+
expect(result.data.implementationName).toBe("GmailCLIAPI");
|
|
61
|
+
expect(result.data.version).toBe("2.1.0");
|
|
62
|
+
expect(result.data.current_implementation_id).toBe("GmailCLIAPI@2.1.0");
|
|
63
|
+
expect(result.configPath).toBe("/resolved/.zapierrc");
|
|
64
|
+
// Verify file was written
|
|
65
|
+
expect(mockWriteFileSync).toHaveBeenCalledWith("/resolved/.zapierrc", JSON.stringify({
|
|
66
|
+
apps: {
|
|
67
|
+
gmail: {
|
|
68
|
+
implementationName: "GmailCLIAPI",
|
|
69
|
+
version: "2.1.0",
|
|
70
|
+
},
|
|
71
|
+
},
|
|
72
|
+
}, null, 2));
|
|
73
|
+
});
|
|
74
|
+
it("should update existing .zapierrc file", async () => {
|
|
75
|
+
const existingConfig = {
|
|
76
|
+
apps: {
|
|
77
|
+
slack: {
|
|
78
|
+
implementationName: "SlackCLIAPI",
|
|
79
|
+
version: "1.27.1",
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
mockExistsSync.mockReturnValue(true);
|
|
84
|
+
mockReadFileSync.mockReturnValue(JSON.stringify(existingConfig));
|
|
85
|
+
mockResolve.mockReturnValue("/resolved/.zapierrc");
|
|
86
|
+
const sdk = createTestSdk();
|
|
87
|
+
const result = await sdk.lockVersion({ appKey: "gmail" });
|
|
88
|
+
expect(mockReadFileSync).toHaveBeenCalledWith("/resolved/.zapierrc", "utf8");
|
|
89
|
+
expect(result.configPath).toBe("/resolved/.zapierrc");
|
|
90
|
+
// Verify file was updated with both apps
|
|
91
|
+
expect(mockWriteFileSync).toHaveBeenCalledWith("/resolved/.zapierrc", JSON.stringify({
|
|
92
|
+
apps: {
|
|
93
|
+
slack: {
|
|
94
|
+
implementationName: "SlackCLIAPI",
|
|
95
|
+
version: "1.27.1",
|
|
96
|
+
},
|
|
97
|
+
gmail: {
|
|
98
|
+
implementationName: "GmailCLIAPI",
|
|
99
|
+
version: "2.1.0",
|
|
100
|
+
},
|
|
101
|
+
},
|
|
102
|
+
}, null, 2));
|
|
103
|
+
});
|
|
104
|
+
it("should handle invalid implementation ID format", async () => {
|
|
105
|
+
mockSdk.listApps = vi.fn().mockReturnValue({
|
|
106
|
+
items: vi.fn().mockReturnValue([
|
|
107
|
+
{
|
|
108
|
+
title: "Invalid App",
|
|
109
|
+
key: "InvalidApp",
|
|
110
|
+
current_implementation_id: "InvalidFormat",
|
|
111
|
+
},
|
|
112
|
+
][Symbol.iterator]()),
|
|
113
|
+
});
|
|
114
|
+
const sdk = createTestSdk();
|
|
115
|
+
await expect(sdk.lockVersion({ appKey: "invalid" })).rejects.toThrow("Invalid implementation ID format: InvalidFormat. Expected format: <implementationName>@<version>");
|
|
116
|
+
});
|
|
117
|
+
it("should use custom config path when provided", async () => {
|
|
118
|
+
mockExistsSync.mockReturnValue(false);
|
|
119
|
+
mockResolve.mockReturnValue("/resolved/custom-config.json");
|
|
120
|
+
const sdk = createTestSdk();
|
|
121
|
+
const result = await sdk.lockVersion({
|
|
122
|
+
appKey: "gmail",
|
|
123
|
+
configPath: "custom-config.json",
|
|
124
|
+
});
|
|
125
|
+
expect(mockResolve).toHaveBeenCalledWith("custom-config.json");
|
|
126
|
+
expect(result.configPath).toBe("/resolved/custom-config.json");
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
export declare const LockVersionSchema: z.ZodObject<{
|
|
3
|
+
appKey: z.ZodString;
|
|
4
|
+
}, "strip", z.ZodTypeAny, {
|
|
5
|
+
appKey: string;
|
|
6
|
+
}, {
|
|
7
|
+
appKey: string;
|
|
8
|
+
}>;
|
|
9
|
+
export type LockVersionOptions = z.infer<typeof LockVersionSchema>;
|
|
10
|
+
//# sourceMappingURL=schemas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/lockVersion/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,iBAAiB;;;;;;EAI5B,CAAC;AAEH,MAAM,MAAM,kBAAkB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { GetImplementation, GetManifestEntry, GetVersionedImplementationId, Manifest } from "./schemas";
|
|
2
|
+
import { ManifestPluginOptionsSchema } from "./schemas";
|
|
3
|
+
import type { GetSdkType, Plugin } from "../../types/plugin";
|
|
4
|
+
import { z } from "zod";
|
|
5
|
+
import { ApiClient } from "../../api";
|
|
6
|
+
import { ListAppsPluginProvides } from "../listApps";
|
|
7
|
+
export type ManifestPluginOptions = z.infer<typeof ManifestPluginOptionsSchema>;
|
|
8
|
+
export interface ManifestPluginProvides {
|
|
9
|
+
context: {
|
|
10
|
+
manifest: Manifest | null;
|
|
11
|
+
getVersionedImplementationId: GetVersionedImplementationId;
|
|
12
|
+
getManifestEntry: GetManifestEntry;
|
|
13
|
+
getImplementation: GetImplementation;
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Load manifest from a file path synchronously
|
|
18
|
+
* Supports local files (Node.js only)
|
|
19
|
+
*/
|
|
20
|
+
export declare function loadManifestFromFile(filePath: string): Manifest | null;
|
|
21
|
+
export declare const manifestPlugin: Plugin<GetSdkType<ListAppsPluginProvides>, {
|
|
22
|
+
api: ApiClient;
|
|
23
|
+
}, ManifestPluginProvides>;
|
|
24
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/manifest/index.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,4BAA4B,EAC5B,QAAQ,EACT,MAAM,WAAW,CAAC;AACnB,OAAO,EAAkB,2BAA2B,EAAE,MAAM,WAAW,CAAC;AACxE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAC7D,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAOrD,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE;QACP,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAAC;QAC1B,4BAA4B,EAAE,4BAA4B,CAAC;QAC3D,gBAAgB,EAAE,gBAAgB,CAAC;QACnC,iBAAiB,EAAE,iBAAiB,CAAC;KACtC,CAAC;CACH;AA2BD;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI,CAUtE;AAcD,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,UAAU,CAAC,sBAAsB,CAAC,EAClC;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,EAClB,sBAAsB,CAoFvB,CAAC"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { readFileSync } from "fs";
|
|
2
|
+
import { resolve } from "path";
|
|
3
|
+
import { ManifestSchema } from "./schemas";
|
|
4
|
+
import { normalizeImplementationToAppItem, splitVersionedKey, } from "../../utils/domain-utils";
|
|
5
|
+
/**
|
|
6
|
+
* Parse manifest content from a string
|
|
7
|
+
*/
|
|
8
|
+
function parseManifestContent(content, source) {
|
|
9
|
+
try {
|
|
10
|
+
const parsed = JSON.parse(content);
|
|
11
|
+
if (parsed?.apps && typeof parsed?.apps === "object") {
|
|
12
|
+
const result = ManifestSchema.safeParse(parsed);
|
|
13
|
+
if (result.success) {
|
|
14
|
+
return result.data;
|
|
15
|
+
}
|
|
16
|
+
console.warn(`⚠️ Invalid manifest format in ${source}: ${result.error}`);
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
catch (error) {
|
|
21
|
+
console.warn(`⚠️ Failed to parse manifest from ${source}:`, error);
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Load manifest from a file path synchronously
|
|
27
|
+
* Supports local files (Node.js only)
|
|
28
|
+
*/
|
|
29
|
+
export function loadManifestFromFile(filePath) {
|
|
30
|
+
try {
|
|
31
|
+
// Resolve relative paths relative to current working directory
|
|
32
|
+
const resolvedPath = resolve(filePath);
|
|
33
|
+
const content = readFileSync(resolvedPath, "utf8");
|
|
34
|
+
return parseManifestContent(content, resolvedPath);
|
|
35
|
+
}
|
|
36
|
+
catch (error) {
|
|
37
|
+
console.warn(`⚠️ Failed to load manifest from ${filePath}:`, error);
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const emitWarning = (appKey) => {
|
|
42
|
+
console.warn(`\n${"⚠️".padEnd(3)} ${"WARNING".padEnd(8)} No manifest version found for '${appKey}'`);
|
|
43
|
+
console.warn(` ${"↳".padEnd(3)} Using a manifest ensures version locking and prevents unexpected behavior due to version changes.`);
|
|
44
|
+
console.warn(` ${"↳".padEnd(3)} Generate/update the manifest with: \`zapier-sdk update-manifest ${appKey}\`\n`);
|
|
45
|
+
};
|
|
46
|
+
export const manifestPlugin = (params) => {
|
|
47
|
+
const { sdk, context } = params;
|
|
48
|
+
const { api, options } = context;
|
|
49
|
+
const { manifestPath = ".zapierrc", manifest } = options || {};
|
|
50
|
+
const resolvedManifest = (() => {
|
|
51
|
+
// If manifest is provided directly, use it
|
|
52
|
+
if (manifest) {
|
|
53
|
+
return manifest;
|
|
54
|
+
}
|
|
55
|
+
// If manifestPath is provided, load from file
|
|
56
|
+
if (manifestPath) {
|
|
57
|
+
return loadManifestFromFile(manifestPath);
|
|
58
|
+
}
|
|
59
|
+
return null;
|
|
60
|
+
})();
|
|
61
|
+
const getManifestEntry = (appKey) => {
|
|
62
|
+
return resolvedManifest?.apps?.[appKey] || null;
|
|
63
|
+
};
|
|
64
|
+
const getImplementation = async (appKey) => {
|
|
65
|
+
let selectedApi = null;
|
|
66
|
+
const manifestImplementation = resolvedManifest?.apps?.[appKey];
|
|
67
|
+
const [versionlessAppKey, version] = splitVersionedKey(appKey);
|
|
68
|
+
// Use versioned app key if provided
|
|
69
|
+
if (version) {
|
|
70
|
+
selectedApi = `${versionlessAppKey}@${version}`;
|
|
71
|
+
// Otherwise, use manifest entry if available
|
|
72
|
+
}
|
|
73
|
+
else if (manifestImplementation) {
|
|
74
|
+
selectedApi = `${manifestImplementation.implementationName}@${manifestImplementation.version || "latest"}`;
|
|
75
|
+
}
|
|
76
|
+
if (selectedApi) {
|
|
77
|
+
const searchParams = {
|
|
78
|
+
selected_apis: selectedApi,
|
|
79
|
+
};
|
|
80
|
+
const implementationData = await api.get("/api/v4/implementations/", {
|
|
81
|
+
searchParams,
|
|
82
|
+
});
|
|
83
|
+
const implementationResults = implementationData.results[0];
|
|
84
|
+
if (!implementationResults)
|
|
85
|
+
return null;
|
|
86
|
+
return normalizeImplementationToAppItem(implementationResults);
|
|
87
|
+
}
|
|
88
|
+
emitWarning(appKey);
|
|
89
|
+
const appsIterator = sdk.listApps({ appKeys: [appKey] }).items();
|
|
90
|
+
const apps = [];
|
|
91
|
+
for await (const app of appsIterator) {
|
|
92
|
+
apps.push(app);
|
|
93
|
+
break; // Only need the first result
|
|
94
|
+
}
|
|
95
|
+
if (apps.length === 0) {
|
|
96
|
+
return null;
|
|
97
|
+
}
|
|
98
|
+
const app = apps[0];
|
|
99
|
+
return app;
|
|
100
|
+
};
|
|
101
|
+
const getVersionedImplementationId = async (appKey) => {
|
|
102
|
+
const manifestEntry = getManifestEntry(appKey);
|
|
103
|
+
if (manifestEntry) {
|
|
104
|
+
return `${manifestEntry.implementationName}@${manifestEntry.version || "latest"}`;
|
|
105
|
+
}
|
|
106
|
+
const implementation = await getImplementation(appKey);
|
|
107
|
+
if (!implementation)
|
|
108
|
+
return null;
|
|
109
|
+
return implementation.current_implementation_id;
|
|
110
|
+
};
|
|
111
|
+
return {
|
|
112
|
+
context: {
|
|
113
|
+
manifest: resolvedManifest,
|
|
114
|
+
getVersionedImplementationId,
|
|
115
|
+
getManifestEntry,
|
|
116
|
+
getImplementation,
|
|
117
|
+
},
|
|
118
|
+
};
|
|
119
|
+
};
|