@zapier/zapier-sdk 0.8.3 → 0.10.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 +18 -0
- package/README.md +17 -40
- package/dist/api/client.d.ts.map +1 -1
- package/dist/api/client.js +14 -0
- package/dist/api/debug.d.ts +1 -0
- package/dist/api/debug.d.ts.map +1 -1
- package/dist/api/debug.js +42 -1
- package/dist/api/debug.test.d.ts +2 -0
- package/dist/api/debug.test.d.ts.map +1 -0
- package/dist/api/debug.test.js +59 -0
- package/dist/api/schemas.d.ts +451 -251
- package/dist/api/schemas.d.ts.map +1 -1
- package/dist/api/schemas.js +51 -29
- package/dist/index.cjs +1149 -751
- package/dist/index.d.mts +2359 -2161
- package/dist/index.d.ts +3 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/index.mjs +1143 -743
- package/dist/plugins/apps/index.d.ts +4 -0
- package/dist/plugins/apps/index.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.d.ts +1 -1
- package/dist/plugins/findFirstAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findFirstAuthentication/index.js +9 -1
- package/dist/plugins/findFirstAuthentication/index.test.js +3 -4
- package/dist/plugins/findFirstAuthentication/schemas.d.ts +5 -3
- package/dist/plugins/findFirstAuthentication/schemas.d.ts.map +1 -1
- package/dist/plugins/findUniqueAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/findUniqueAuthentication/index.js +4 -0
- package/dist/plugins/findUniqueAuthentication/schemas.d.ts +5 -3
- package/dist/plugins/findUniqueAuthentication/schemas.d.ts.map +1 -1
- package/dist/plugins/getAction/index.d.ts.map +1 -1
- package/dist/plugins/getAction/index.js +10 -0
- package/dist/plugins/getAction/schemas.d.ts +5 -3
- package/dist/plugins/getAction/schemas.d.ts.map +1 -1
- package/dist/plugins/getApp/index.d.ts +2 -7
- package/dist/plugins/getApp/index.d.ts.map +1 -1
- package/dist/plugins/getApp/index.js +17 -9
- package/dist/plugins/getApp/index.test.js +3 -3
- package/dist/plugins/getApp/schemas.d.ts +3 -1
- package/dist/plugins/getApp/schemas.d.ts.map +1 -1
- package/dist/plugins/getApp/schemas.js +2 -4
- package/dist/plugins/getAuthentication/index.d.ts.map +1 -1
- package/dist/plugins/getAuthentication/index.js +8 -0
- package/dist/plugins/getAuthentication/index.test.js +1 -1
- package/dist/plugins/getProfile/index.d.ts.map +1 -1
- package/dist/plugins/getProfile/index.js +4 -0
- package/dist/plugins/getProfile/schemas.d.ts.map +1 -1
- package/dist/plugins/getProfile/schemas.js +4 -3
- package/dist/plugins/listActions/index.d.ts +2 -4
- package/dist/plugins/listActions/index.d.ts.map +1 -1
- package/dist/plugins/listActions/index.js +10 -1
- package/dist/plugins/listActions/index.test.js +4 -4
- package/dist/plugins/listActions/schemas.d.ts +5 -3
- package/dist/plugins/listActions/schemas.d.ts.map +1 -1
- package/dist/plugins/listActions/schemas.js +2 -4
- package/dist/plugins/listApps/index.d.ts +4 -7
- package/dist/plugins/listApps/index.d.ts.map +1 -1
- package/dist/plugins/listApps/index.js +37 -17
- package/dist/plugins/listApps/index.test.js +23 -3
- package/dist/plugins/listApps/schemas.d.ts.map +1 -1
- package/dist/plugins/listApps/schemas.js +3 -9
- package/dist/plugins/listAuthentications/index.d.ts +2 -4
- package/dist/plugins/listAuthentications/index.d.ts.map +1 -1
- package/dist/plugins/listAuthentications/index.js +12 -0
- package/dist/plugins/listAuthentications/index.test.js +39 -13
- package/dist/plugins/listAuthentications/schemas.d.ts +8 -3
- package/dist/plugins/listAuthentications/schemas.d.ts.map +1 -1
- package/dist/plugins/listAuthentications/schemas.js +4 -0
- package/dist/plugins/listInputFieldChoices/index.d.ts.map +1 -1
- package/dist/plugins/listInputFieldChoices/index.js +14 -2
- package/dist/plugins/listInputFieldChoices/schemas.d.ts +5 -3
- package/dist/plugins/listInputFieldChoices/schemas.d.ts.map +1 -1
- package/dist/plugins/listInputFieldChoices/schemas.js +10 -19
- package/dist/plugins/listInputFields/index.d.ts.map +1 -1
- package/dist/plugins/listInputFields/index.js +14 -2
- package/dist/plugins/listInputFields/index.test.js +5 -9
- package/dist/plugins/listInputFields/schemas.d.ts +5 -3
- package/dist/plugins/listInputFields/schemas.d.ts.map +1 -1
- package/dist/plugins/manifest/index.d.ts +25 -9
- package/dist/plugins/manifest/index.d.ts.map +1 -1
- package/dist/plugins/manifest/index.js +239 -67
- package/dist/plugins/manifest/index.test.js +426 -171
- package/dist/plugins/manifest/schemas.d.ts +5 -1
- package/dist/plugins/manifest/schemas.d.ts.map +1 -1
- package/dist/plugins/manifest/schemas.js +1 -0
- package/dist/plugins/registry/index.d.ts.map +1 -1
- package/dist/plugins/registry/index.js +8 -2
- package/dist/plugins/request/index.d.ts.map +1 -1
- package/dist/plugins/request/index.js +1 -0
- package/dist/plugins/runAction/index.d.ts.map +1 -1
- package/dist/plugins/runAction/index.js +12 -0
- package/dist/plugins/runAction/schemas.d.ts +5 -3
- package/dist/plugins/runAction/schemas.d.ts.map +1 -1
- package/dist/resolvers/actionKey.d.ts +13 -7
- package/dist/resolvers/actionKey.d.ts.map +1 -1
- package/dist/resolvers/actionType.d.ts +8 -7
- package/dist/resolvers/actionType.d.ts.map +1 -1
- package/dist/resolvers/appKey.d.ts +2 -6
- package/dist/resolvers/appKey.d.ts.map +1 -1
- package/dist/resolvers/authenticationId.d.ts +7 -7
- package/dist/resolvers/authenticationId.d.ts.map +1 -1
- package/dist/resolvers/authenticationId.js +16 -7
- package/dist/resolvers/index.d.ts +3 -35
- package/dist/resolvers/index.d.ts.map +1 -1
- package/dist/resolvers/index.js +4 -87
- package/dist/resolvers/inputFieldKey.d.ts +11 -0
- package/dist/resolvers/inputFieldKey.d.ts.map +1 -0
- package/dist/resolvers/inputFieldKey.js +23 -0
- package/dist/resolvers/inputs.d.ts +11 -6
- package/dist/resolvers/inputs.d.ts.map +1 -1
- package/dist/resolvers/inputs.js +17 -0
- package/dist/schemas/Action.d.ts +8 -8
- package/dist/schemas/Action.d.ts.map +1 -1
- package/dist/schemas/Action.js +8 -3
- package/dist/schemas/App.d.ts +183 -11
- package/dist/schemas/App.d.ts.map +1 -1
- package/dist/schemas/App.js +7 -9
- package/dist/schemas/Auth.d.ts +12 -12
- package/dist/schemas/Auth.js +1 -1
- package/dist/schemas/Field.d.ts +5 -98
- package/dist/schemas/Field.d.ts.map +1 -1
- package/dist/schemas/Field.js +24 -52
- package/dist/schemas/Run.d.ts +3 -0
- package/dist/schemas/Run.d.ts.map +1 -0
- package/dist/schemas/Run.js +31 -0
- package/dist/schemas/UserProfile.d.ts +11 -11
- package/dist/schemas/UserProfile.d.ts.map +1 -1
- package/dist/schemas/UserProfile.js +21 -7
- package/dist/sdk.d.ts +15 -14
- package/dist/sdk.d.ts.map +1 -1
- package/dist/sdk.js +1 -4
- package/dist/types/plugin.d.ts +6 -0
- package/dist/types/plugin.d.ts.map +1 -1
- package/dist/types/properties.d.ts +3 -1
- package/dist/types/properties.d.ts.map +1 -1
- package/dist/types/sdk.d.ts +11 -3
- package/dist/types/sdk.d.ts.map +1 -1
- package/dist/utils/domain-utils.d.ts +17 -16
- package/dist/utils/domain-utils.d.ts.map +1 -1
- package/dist/utils/domain-utils.js +53 -78
- package/dist/utils/domain-utils.test.js +157 -3
- package/dist/utils/file-utils.d.ts +4 -0
- package/dist/utils/file-utils.d.ts.map +1 -0
- package/dist/utils/file-utils.js +74 -0
- package/dist/utils/file-utils.test.d.ts +2 -0
- package/dist/utils/file-utils.test.d.ts.map +1 -0
- package/dist/utils/file-utils.test.js +51 -0
- package/dist/utils/schema-utils.d.ts +44 -21
- package/dist/utils/schema-utils.d.ts.map +1 -1
- package/dist/utils/schema-utils.js +17 -11
- package/package.json +1 -1
- package/src/api/client.ts +12 -0
- package/src/api/debug.test.ts +76 -0
- package/src/api/debug.ts +46 -2
- package/src/api/schemas.ts +51 -29
- package/src/index.ts +5 -6
- package/src/plugins/apps/index.ts +9 -2
- package/src/plugins/findFirstAuthentication/index.test.ts +8 -5
- package/src/plugins/findFirstAuthentication/index.ts +14 -2
- package/src/plugins/findUniqueAuthentication/index.ts +4 -0
- package/src/plugins/getAction/index.ts +14 -0
- package/src/plugins/getApp/index.test.ts +3 -3
- package/src/plugins/getApp/index.ts +20 -14
- package/src/plugins/getApp/schemas.ts +7 -12
- package/src/plugins/getAuthentication/index.test.ts +1 -1
- package/src/plugins/getAuthentication/index.ts +8 -0
- package/src/plugins/getProfile/index.ts +4 -0
- package/src/plugins/getProfile/schemas.ts +4 -6
- package/src/plugins/listActions/index.test.ts +8 -7
- package/src/plugins/listActions/index.ts +12 -3
- package/src/plugins/listActions/schemas.ts +20 -25
- package/src/plugins/listApps/index.test.ts +24 -3
- package/src/plugins/listApps/index.ts +50 -25
- package/src/plugins/listApps/schemas.ts +17 -26
- package/src/plugins/listAuthentications/index.test.ts +52 -15
- package/src/plugins/listAuthentications/index.ts +15 -2
- package/src/plugins/listAuthentications/schemas.ts +4 -0
- package/src/plugins/listInputFieldChoices/index.ts +21 -1
- package/src/plugins/listInputFieldChoices/schemas.ts +61 -76
- package/src/plugins/listInputFields/index.test.ts +5 -9
- package/src/plugins/listInputFields/index.ts +20 -2
- package/src/plugins/manifest/index.test.ts +503 -197
- package/src/plugins/manifest/index.ts +338 -82
- package/src/plugins/manifest/schemas.ts +9 -2
- package/src/plugins/registry/index.ts +8 -2
- package/src/plugins/request/index.ts +1 -0
- package/src/plugins/runAction/index.ts +18 -0
- package/src/resolvers/actionKey.ts +15 -13
- package/src/resolvers/actionType.ts +10 -12
- package/src/resolvers/appKey.ts +2 -6
- package/src/resolvers/authenticationId.ts +25 -19
- package/src/resolvers/index.ts +7 -113
- package/src/resolvers/inputFieldKey.ts +38 -0
- package/src/resolvers/inputs.ts +28 -10
- package/src/schemas/Action.ts +8 -3
- package/src/schemas/App.ts +7 -9
- package/src/schemas/Auth.ts +1 -1
- package/src/schemas/Field.ts +24 -57
- package/src/schemas/Run.ts +40 -0
- package/src/schemas/UserProfile.ts +24 -7
- package/src/sdk.ts +18 -12
- package/src/types/plugin.ts +8 -0
- package/src/types/sdk.ts +31 -21
- package/src/utils/domain-utils.test.ts +196 -2
- package/src/utils/domain-utils.ts +77 -102
- package/src/utils/file-utils.test.ts +73 -0
- package/src/utils/file-utils.ts +94 -0
- package/src/utils/schema-utils.ts +96 -44
- package/tsconfig.tsbuildinfo +1 -1
- package/dist/plugins/lockVersion/index.d.ts +0 -24
- package/dist/plugins/lockVersion/index.d.ts.map +0 -1
- package/dist/plugins/lockVersion/index.js +0 -72
- package/dist/plugins/lockVersion/index.test.d.ts +0 -2
- package/dist/plugins/lockVersion/index.test.d.ts.map +0 -1
- package/dist/plugins/lockVersion/index.test.js +0 -129
- package/dist/plugins/lockVersion/schemas.d.ts +0 -10
- package/dist/plugins/lockVersion/schemas.d.ts.map +0 -1
- package/dist/plugins/lockVersion/schemas.js +0 -6
- package/src/plugins/lockVersion/index.test.ts +0 -176
- package/src/plugins/lockVersion/index.ts +0 -112
- package/src/plugins/lockVersion/schemas.ts +0 -9
|
@@ -169,7 +169,7 @@ describe("listInputFields plugin", () => {
|
|
|
169
169
|
expect(result.data).toHaveLength(3);
|
|
170
170
|
// Check message field transformation
|
|
171
171
|
expect(result.data[0]).toEqual(expect.objectContaining({
|
|
172
|
-
|
|
172
|
+
key: "message",
|
|
173
173
|
title: "Message",
|
|
174
174
|
description: "The message to send",
|
|
175
175
|
is_required: true,
|
|
@@ -177,22 +177,18 @@ describe("listInputFields plugin", () => {
|
|
|
177
177
|
placeholder: "Enter your message",
|
|
178
178
|
default_value: "",
|
|
179
179
|
}));
|
|
180
|
-
// Check channel field with
|
|
180
|
+
// Check channel field with SELECT format
|
|
181
181
|
expect(result.data[1]).toEqual(expect.objectContaining({
|
|
182
|
-
|
|
182
|
+
key: "channel",
|
|
183
183
|
title: "Channel",
|
|
184
184
|
description: "The channel to send to",
|
|
185
185
|
is_required: true,
|
|
186
186
|
value_type: "STRING",
|
|
187
187
|
format: "SELECT",
|
|
188
|
-
choices: [
|
|
189
|
-
{ value: "#general", label: "General", sample: "#general" },
|
|
190
|
-
{ value: "#random", label: "Random", sample: "#random" },
|
|
191
|
-
],
|
|
192
188
|
}));
|
|
193
189
|
// Check array field
|
|
194
190
|
expect(result.data[2]).toEqual(expect.objectContaining({
|
|
195
|
-
|
|
191
|
+
key: "tags",
|
|
196
192
|
title: "Tags",
|
|
197
193
|
description: "List of tags",
|
|
198
194
|
value_type: "ARRAY",
|
|
@@ -321,7 +317,7 @@ describe("listInputFields plugin", () => {
|
|
|
321
317
|
items.push(item);
|
|
322
318
|
}
|
|
323
319
|
expect(items).toHaveLength(3);
|
|
324
|
-
expect(items[0].
|
|
320
|
+
expect(items[0].key).toBe("message");
|
|
325
321
|
});
|
|
326
322
|
});
|
|
327
323
|
});
|
|
@@ -3,7 +3,9 @@ import type { InputFieldItem } from "../../types/domain";
|
|
|
3
3
|
import type { PaginatedSdkFunction } from "../../types/functions";
|
|
4
4
|
import type { ZapierConfigurationError, ZapierApiError, ZapierAuthenticationError, ZapierAppNotFoundError, ZapierValidationError, ZapierUnknownError } from "../../types/errors";
|
|
5
5
|
export declare const ListInputFieldsSchema: z.ZodObject<{
|
|
6
|
-
appKey: z.ZodString
|
|
6
|
+
appKey: z.ZodString & {
|
|
7
|
+
_def: z.ZodStringDef & import("../..").PositionalMetadata;
|
|
8
|
+
};
|
|
7
9
|
actionType: z.ZodEnum<["read", "read_bulk", "write", "run", "search", "search_or_write", "search_and_write", "filter"]>;
|
|
8
10
|
actionKey: z.ZodString;
|
|
9
11
|
authenticationId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
@@ -12,7 +14,7 @@ export declare const ListInputFieldsSchema: z.ZodObject<{
|
|
|
12
14
|
maxItems: z.ZodOptional<z.ZodNumber>;
|
|
13
15
|
}, "strip", z.ZodTypeAny, {
|
|
14
16
|
appKey: string;
|
|
15
|
-
actionType: "filter" | "read" | "read_bulk" | "
|
|
17
|
+
actionType: "filter" | "read" | "read_bulk" | "write" | "run" | "search" | "search_or_write" | "search_and_write";
|
|
16
18
|
actionKey: string;
|
|
17
19
|
authenticationId?: number | null | undefined;
|
|
18
20
|
inputs?: Record<string, unknown> | undefined;
|
|
@@ -20,7 +22,7 @@ export declare const ListInputFieldsSchema: z.ZodObject<{
|
|
|
20
22
|
maxItems?: number | undefined;
|
|
21
23
|
}, {
|
|
22
24
|
appKey: string;
|
|
23
|
-
actionType: "filter" | "read" | "read_bulk" | "
|
|
25
|
+
actionType: "filter" | "read" | "read_bulk" | "write" | "run" | "search" | "search_or_write" | "search_and_write";
|
|
24
26
|
actionKey: string;
|
|
25
27
|
authenticationId?: number | null | undefined;
|
|
26
28
|
inputs?: Record<string, unknown> | undefined;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/listInputFields/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAG5B,eAAO,MAAM,qBAAqB
|
|
1
|
+
{"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../../../src/plugins/listInputFields/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAQxB,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,uBAAuB,CAAC;AAClE,OAAO,KAAK,EACV,wBAAwB,EACxB,cAAc,EACd,yBAAyB,EACzB,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EACnB,MAAM,oBAAoB,CAAC;AAG5B,eAAO,MAAM,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;EAoBgC,CAAC;AAGnE,MAAM,MAAM,sBAAsB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qBAAqB,CAAC,CAAC;AAG3E,MAAM,MAAM,oBAAoB,GAC5B,wBAAwB,GACxB,cAAc,GACd,yBAAyB,GACzB,sBAAsB,GACtB,qBAAqB,GACrB,kBAAkB,CAAC;AAGvB,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAGD,MAAM,WAAW,0BAA0B;IACzC,eAAe,EAAE,oBAAoB,CAAC,sBAAsB,EAAE,cAAc,CAAC,CAAC;CAC/E"}
|
|
@@ -1,22 +1,38 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
1
|
+
import type { GetVersionedImplementationId, Manifest, ManifestEntry, ManifestPluginOptionsSchema, ResolveAppKeys } from "./schemas";
|
|
2
|
+
import type { Plugin } from "../../types/plugin";
|
|
3
3
|
import type { z } from "zod";
|
|
4
4
|
import type { ApiClient } from "../../api";
|
|
5
|
-
import type { ListAppsPluginProvides } from "../listApps";
|
|
6
5
|
export type ManifestPluginOptions = z.infer<typeof ManifestPluginOptionsSchema>;
|
|
7
6
|
export interface ManifestPluginProvides {
|
|
8
7
|
context: {
|
|
9
8
|
getVersionedImplementationId: GetVersionedImplementationId;
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
resolveAppKeys: ResolveAppKeys;
|
|
10
|
+
updateManifestEntry: (appKey: string, entry: ManifestEntry, configPath?: string) => Promise<[string, ManifestEntry]>;
|
|
12
11
|
};
|
|
13
12
|
}
|
|
14
13
|
/**
|
|
15
|
-
*
|
|
16
|
-
* Supports local files (Node.js
|
|
14
|
+
* Read manifest from a file path asynchronously
|
|
15
|
+
* Supports local files (Node.js) and browser environments (fallback to global filesystem)
|
|
17
16
|
*/
|
|
18
|
-
export declare function
|
|
19
|
-
|
|
17
|
+
export declare function readManifestFromFile(filePath: string): Promise<Manifest | null>;
|
|
18
|
+
/**
|
|
19
|
+
* Get the preferred key for storing an app in the manifest
|
|
20
|
+
* Extracted from plugin to make it easier to test
|
|
21
|
+
*/
|
|
22
|
+
export declare function getPreferredManifestEntryKey({ appKey, api, }: {
|
|
23
|
+
appKey: string;
|
|
24
|
+
api: ApiClient;
|
|
25
|
+
}): Promise<string>;
|
|
26
|
+
/**
|
|
27
|
+
* Find a manifest entry by any app key (implementation name, slug, etc.).
|
|
28
|
+
*/
|
|
29
|
+
export declare function findManifestEntry({ appKey, manifest, }: {
|
|
30
|
+
appKey: string;
|
|
31
|
+
manifest: Manifest;
|
|
32
|
+
}): [string, ManifestEntry] | null;
|
|
33
|
+
export { DEFAULT_CONFIG_PATH } from "./schemas";
|
|
34
|
+
export declare const manifestPlugin: Plugin<{}, // no SDK dependencies
|
|
35
|
+
{
|
|
20
36
|
api: ApiClient;
|
|
21
37
|
}, ManifestPluginProvides>;
|
|
22
38
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/manifest/index.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/plugins/manifest/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,4BAA4B,EAC5B,QAAQ,EACR,aAAa,EACb,2BAA2B,EAC3B,cAAc,EACf,MAAM,WAAW,CAAC;AAEnB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAgB3C,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE;QACP,4BAA4B,EAAE,4BAA4B,CAAC;QAC3D,cAAc,EAAE,cAAc,CAAC;QAC/B,mBAAmB,EAAE,CACnB,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,aAAa,EACpB,UAAU,CAAC,EAAE,MAAM,KAChB,OAAO,CAAC,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;KACvC,CAAC;CACH;AA2BD;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,CAU1B;AAcD;;;GAGG;AACH,wBAAsB,4BAA4B,CAAC,EACjD,MAAM,EACN,GAAG,GACJ,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,SAAS,CAAC;CAChB,GAAG,OAAO,CAAC,MAAM,CAAC,CAkClB;AAoCD;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,MAAM,EACN,QAAQ,GACT,EAAE;IACD,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,QAAQ,CAAC;CACpB,GAAG,CAAC,MAAM,EAAE,aAAa,CAAC,GAAG,IAAI,CAyBjC;AA8GD,OAAO,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAEhD,eAAO,MAAM,cAAc,EAAE,MAAM,CACjC,EAAE,EAAE,sBAAsB;AAC1B;IAAE,GAAG,EAAE,SAAS,CAAA;CAAE,EAClB,sBAAsB,CA8GvB,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { readFile, writeFile, resolve } from "../../utils/file-utils";
|
|
2
|
+
import { ManifestSchema, DEFAULT_CONFIG_PATH } from "./schemas";
|
|
3
|
+
import { normalizeImplementationMetaToAppItem, splitVersionedKey, isSnakeCasedSlug, dashifySnakeCasedSlug, toAppLocator, isResolvedAppLocator, } from "../../utils/domain-utils";
|
|
4
|
+
import { extractCursor } from "../../utils/function-utils";
|
|
5
|
+
import { paginate } from "../../utils/pagination-utils";
|
|
6
|
+
import { toArrayFromAsync } from "../../utils/array-utils";
|
|
5
7
|
/**
|
|
6
8
|
* Parse manifest content from a string
|
|
7
9
|
*/
|
|
@@ -23,103 +25,273 @@ function parseManifestContent(content, source) {
|
|
|
23
25
|
}
|
|
24
26
|
}
|
|
25
27
|
/**
|
|
26
|
-
*
|
|
27
|
-
* Supports local files (Node.js
|
|
28
|
+
* Read manifest from a file path asynchronously
|
|
29
|
+
* Supports local files (Node.js) and browser environments (fallback to global filesystem)
|
|
28
30
|
*/
|
|
29
|
-
export function
|
|
31
|
+
export async function readManifestFromFile(filePath) {
|
|
30
32
|
try {
|
|
31
33
|
// Resolve relative paths relative to current working directory
|
|
32
|
-
const resolvedPath = resolve(filePath);
|
|
33
|
-
const content =
|
|
34
|
+
const resolvedPath = await resolve(filePath);
|
|
35
|
+
const content = await readFile(resolvedPath);
|
|
34
36
|
return parseManifestContent(content, resolvedPath);
|
|
35
37
|
}
|
|
36
38
|
catch {
|
|
37
|
-
console.warn(`⚠️ Failed to
|
|
39
|
+
console.warn(`⚠️ Failed to read manifest from ${filePath}`);
|
|
38
40
|
return null;
|
|
39
41
|
}
|
|
40
42
|
}
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
/**
|
|
44
|
+
* Write manifest to a file path asynchronously
|
|
45
|
+
* Supports local files (Node.js) and browser environments (fallback to global filesystem)
|
|
46
|
+
*/
|
|
47
|
+
async function writeManifestToFile(manifest, filePath) {
|
|
48
|
+
const resolvedPath = await resolve(filePath);
|
|
49
|
+
await writeFile(resolvedPath, JSON.stringify(manifest, null, 2));
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Get the preferred key for storing an app in the manifest
|
|
53
|
+
* Extracted from plugin to make it easier to test
|
|
54
|
+
*/
|
|
55
|
+
export async function getPreferredManifestEntryKey({ appKey, api, }) {
|
|
56
|
+
const locator = toAppLocator(appKey);
|
|
57
|
+
// If we have a slug, prefer it
|
|
58
|
+
if (locator.slug) {
|
|
59
|
+
return locator.slug;
|
|
60
|
+
}
|
|
61
|
+
// If we have implementation name, look up the latest to get the slug
|
|
62
|
+
if (locator.implementationName) {
|
|
63
|
+
try {
|
|
64
|
+
// API call to get app metadata by implementation name using selected_apis parameter
|
|
65
|
+
const implementationsEnvelope = await api.get(`/api/v4/implementations-meta/lookup/`, {
|
|
66
|
+
searchParams: {
|
|
67
|
+
selected_apis: locator.implementationName,
|
|
68
|
+
},
|
|
69
|
+
});
|
|
70
|
+
if (implementationsEnvelope.results.length > 0 &&
|
|
71
|
+
implementationsEnvelope.results[0].slug) {
|
|
72
|
+
return implementationsEnvelope.results[0].slug;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Fall back to implementation name if lookup fails
|
|
77
|
+
}
|
|
78
|
+
return locator.implementationName;
|
|
79
|
+
}
|
|
80
|
+
// Fall back to original key if we can't determine anything better
|
|
81
|
+
return locator.lookupAppKey;
|
|
82
|
+
}
|
|
83
|
+
async function listAppsForSlugsPage({ slugs, cursor, api, }) {
|
|
84
|
+
const searchParams = {};
|
|
85
|
+
if (slugs.length > 0) {
|
|
86
|
+
searchParams.slugs = slugs.join(",");
|
|
87
|
+
}
|
|
88
|
+
if (cursor) {
|
|
89
|
+
searchParams.offset = cursor;
|
|
90
|
+
}
|
|
91
|
+
const implementationsEnvelope = await api.get("/api/v4/implementations-meta/lookup/", {
|
|
92
|
+
searchParams,
|
|
93
|
+
});
|
|
94
|
+
return {
|
|
95
|
+
data: implementationsEnvelope.results.map(normalizeImplementationMetaToAppItem),
|
|
96
|
+
nextCursor: extractCursor(implementationsEnvelope),
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Find a manifest entry by any app key (implementation name, slug, etc.).
|
|
101
|
+
*/
|
|
102
|
+
export function findManifestEntry({ appKey, manifest, }) {
|
|
103
|
+
const [appKeyWithoutVersion] = splitVersionedKey(appKey);
|
|
104
|
+
// Direct match by key
|
|
105
|
+
if (manifest.apps[appKeyWithoutVersion]) {
|
|
106
|
+
return [appKeyWithoutVersion, manifest.apps[appKeyWithoutVersion]];
|
|
107
|
+
}
|
|
108
|
+
// Handle snake-cased slugs (convert to dashed)
|
|
109
|
+
if (isSnakeCasedSlug(appKey)) {
|
|
110
|
+
const slug = dashifySnakeCasedSlug(appKey);
|
|
111
|
+
if (manifest.apps[slug]) {
|
|
112
|
+
return [slug, manifest.apps[slug]];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
// Search by implementation name in manifest values
|
|
116
|
+
for (const [key, entry] of Object.entries(manifest.apps)) {
|
|
117
|
+
if (entry.implementationName === appKeyWithoutVersion) {
|
|
118
|
+
return [key, entry];
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// No match found
|
|
122
|
+
return null;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Turn any app keys (slugs, implementation names, etc.) into app locators, which are objects that will be guaranteed to
|
|
126
|
+
* have implementation names. Note that this function will not actually guarantee that implementation names are valid!
|
|
127
|
+
* It will attempt to find the app key in the manifest, or if it's a slug, actually do an API call, or otherwise just
|
|
128
|
+
* assume it's an implementation name that will be used for an API call.
|
|
129
|
+
*/
|
|
130
|
+
async function resolveAppKeys({ appKeys, api, manifest, }) {
|
|
131
|
+
// Step 1: Convert all app keys to locators
|
|
132
|
+
const locators = appKeys.map(toAppLocator);
|
|
133
|
+
// Step 2: Map to resolved/unresolved via manifest
|
|
134
|
+
const locatorsWithManifest = locators.map((locator) => {
|
|
135
|
+
const manifestEntryResult = findManifestEntry({
|
|
136
|
+
appKey: locator.lookupAppKey,
|
|
137
|
+
manifest,
|
|
138
|
+
});
|
|
139
|
+
if (manifestEntryResult) {
|
|
140
|
+
const [, manifestEntry] = manifestEntryResult;
|
|
141
|
+
// Use manifest entry to resolve implementation name
|
|
142
|
+
const resolvedVersion = locator.version || manifestEntry.version;
|
|
143
|
+
const resolvedLocator = {
|
|
144
|
+
...locator,
|
|
145
|
+
implementationName: manifestEntry.implementationName,
|
|
146
|
+
version: resolvedVersion,
|
|
147
|
+
};
|
|
148
|
+
return resolvedLocator;
|
|
149
|
+
}
|
|
150
|
+
// If these have an implementationName, they're already resolved.
|
|
151
|
+
return locator;
|
|
152
|
+
});
|
|
153
|
+
// Step 3: Separate resolved from unresolved
|
|
154
|
+
const unresolvedLocators = locatorsWithManifest.filter((locator) => !isResolvedAppLocator(locator));
|
|
155
|
+
// Step 4: Resolve slugs via API
|
|
156
|
+
const slugsToResolve = unresolvedLocators
|
|
157
|
+
.map((locator) => locator.slug)
|
|
158
|
+
.filter((slug) => !!slug)
|
|
159
|
+
.filter((slug, index, array) => array.indexOf(slug) === index); // dedupe
|
|
160
|
+
if (slugsToResolve.length === 0) {
|
|
161
|
+
return locatorsWithManifest.filter(isResolvedAppLocator);
|
|
162
|
+
}
|
|
163
|
+
const iterator = paginate(listAppsForSlugsPage, {
|
|
164
|
+
slugs: slugsToResolve,
|
|
165
|
+
api,
|
|
166
|
+
});
|
|
167
|
+
const pages = await toArrayFromAsync(iterator);
|
|
168
|
+
const apps = pages.flatMap((page) => page.data);
|
|
169
|
+
const slugToAppData = new Map();
|
|
170
|
+
for (const app of apps) {
|
|
171
|
+
if (app.slug) {
|
|
172
|
+
slugToAppData.set(app.slug, app);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
const slugResolvedLocators = locatorsWithManifest.map((locator) => {
|
|
176
|
+
if (isResolvedAppLocator(locator)) {
|
|
177
|
+
return locator;
|
|
178
|
+
}
|
|
179
|
+
if (locator.slug) {
|
|
180
|
+
const appData = slugToAppData.get(locator.slug);
|
|
181
|
+
if (appData) {
|
|
182
|
+
// After resolving from API, check if we have a manifest entry for this implementation name
|
|
183
|
+
const manifestEntryByImplementationName = findManifestEntry({
|
|
184
|
+
appKey: appData.key, // appData.key is the implementation name
|
|
185
|
+
manifest,
|
|
186
|
+
});
|
|
187
|
+
let version = locator.version;
|
|
188
|
+
if (!version) {
|
|
189
|
+
// Prefer manifest version if available, otherwise use API version
|
|
190
|
+
version = manifestEntryByImplementationName
|
|
191
|
+
? manifestEntryByImplementationName[1].version || appData.version
|
|
192
|
+
: appData.version;
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
...locator,
|
|
196
|
+
implementationName: appData.key,
|
|
197
|
+
version,
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return locator;
|
|
202
|
+
});
|
|
203
|
+
// Return all resolved locators.
|
|
204
|
+
return slugResolvedLocators.filter(isResolvedAppLocator);
|
|
205
|
+
}
|
|
206
|
+
export { DEFAULT_CONFIG_PATH } from "./schemas";
|
|
46
207
|
export const manifestPlugin = (params) => {
|
|
47
|
-
const {
|
|
208
|
+
const { context } = params;
|
|
48
209
|
const { api, options } = context;
|
|
49
|
-
const { manifestPath =
|
|
210
|
+
const { manifestPath = DEFAULT_CONFIG_PATH, manifest } = options || {};
|
|
50
211
|
let resolvedManifest;
|
|
51
|
-
function resolveManifest() {
|
|
212
|
+
async function resolveManifest() {
|
|
52
213
|
// If manifest is provided directly, use it
|
|
53
214
|
if (manifest) {
|
|
54
215
|
return manifest;
|
|
55
216
|
}
|
|
56
217
|
// If manifestPath is provided, load from file
|
|
57
218
|
if (manifestPath) {
|
|
58
|
-
return
|
|
219
|
+
return await readManifestFromFile(manifestPath);
|
|
59
220
|
}
|
|
60
221
|
return null;
|
|
61
222
|
}
|
|
62
|
-
const getResolvedManifest = () => {
|
|
223
|
+
const getResolvedManifest = async () => {
|
|
63
224
|
if (typeof resolvedManifest === "undefined") {
|
|
64
|
-
resolvedManifest = resolveManifest() ?? null;
|
|
225
|
+
resolvedManifest = (await resolveManifest()) ?? null;
|
|
65
226
|
}
|
|
66
227
|
return resolvedManifest;
|
|
67
228
|
};
|
|
68
|
-
const
|
|
69
|
-
|
|
229
|
+
const getVersionedImplementationId = async (appKey) => {
|
|
230
|
+
const resolvedApps = await resolveAppKeys({
|
|
231
|
+
appKeys: [appKey],
|
|
232
|
+
api,
|
|
233
|
+
manifest: (await getResolvedManifest()) ?? { apps: {} },
|
|
234
|
+
});
|
|
235
|
+
const resolvedApp = resolvedApps[0];
|
|
236
|
+
if (!resolvedApp)
|
|
237
|
+
return null;
|
|
238
|
+
return `${resolvedApp.implementationName}@${resolvedApp.version || "latest"}`;
|
|
70
239
|
};
|
|
71
|
-
const
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
240
|
+
const updateManifestEntry = async (appKey, entry, configPath = DEFAULT_CONFIG_PATH) => {
|
|
241
|
+
const manifest = (await readManifestFromFile(configPath)) || { apps: {} };
|
|
242
|
+
// Try to find existing entry by direct key first
|
|
243
|
+
let existingEntry = findManifestEntry({
|
|
244
|
+
appKey,
|
|
245
|
+
manifest,
|
|
246
|
+
});
|
|
247
|
+
// If not found directly, try to resolve the app key and search by implementation name
|
|
248
|
+
if (!existingEntry) {
|
|
249
|
+
try {
|
|
250
|
+
const resolvedApps = await resolveAppKeys({
|
|
251
|
+
appKeys: [appKey],
|
|
252
|
+
api,
|
|
253
|
+
manifest,
|
|
254
|
+
});
|
|
255
|
+
if (resolvedApps.length > 0) {
|
|
256
|
+
const resolvedImplementationName = resolvedApps[0].implementationName;
|
|
257
|
+
// Try to find entry using the resolved implementation name
|
|
258
|
+
existingEntry = findManifestEntry({
|
|
259
|
+
appKey: resolvedImplementationName,
|
|
260
|
+
manifest,
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
catch {
|
|
265
|
+
// If resolution fails, continue with original logic
|
|
266
|
+
}
|
|
79
267
|
}
|
|
80
|
-
|
|
81
|
-
|
|
268
|
+
let manifestKey;
|
|
269
|
+
if (existingEntry) {
|
|
270
|
+
// Use existing key to maintain consistency with types files
|
|
271
|
+
manifestKey = existingEntry[0];
|
|
82
272
|
}
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
searchParams,
|
|
273
|
+
else {
|
|
274
|
+
// Get preferred key for new entries
|
|
275
|
+
manifestKey = await getPreferredManifestEntryKey({
|
|
276
|
+
appKey,
|
|
277
|
+
api,
|
|
89
278
|
});
|
|
90
|
-
const implementationResults = implementationData.results[0];
|
|
91
|
-
if (!implementationResults)
|
|
92
|
-
return null;
|
|
93
|
-
return normalizeImplementationToAppItem(implementationResults);
|
|
94
|
-
}
|
|
95
|
-
emitWarning(appKey);
|
|
96
|
-
const appsIterator = sdk.listApps({ appKeys: [appKey] }).items();
|
|
97
|
-
const apps = [];
|
|
98
|
-
for await (const app of appsIterator) {
|
|
99
|
-
apps.push(app);
|
|
100
|
-
break; // Only need the first result
|
|
101
279
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return
|
|
107
|
-
};
|
|
108
|
-
const getVersionedImplementationId = async (appKey) => {
|
|
109
|
-
const manifestEntry = getManifestEntry(appKey);
|
|
110
|
-
if (manifestEntry) {
|
|
111
|
-
return `${manifestEntry.implementationName}@${manifestEntry.version || "latest"}`;
|
|
112
|
-
}
|
|
113
|
-
const implementation = await getImplementation(appKey);
|
|
114
|
-
if (!implementation)
|
|
115
|
-
return null;
|
|
116
|
-
return implementation.current_implementation_id;
|
|
280
|
+
manifest.apps[manifestKey] = entry;
|
|
281
|
+
await writeManifestToFile(manifest, configPath);
|
|
282
|
+
// Clear the cached manifest so it gets reloaded with the new data
|
|
283
|
+
resolvedManifest = undefined;
|
|
284
|
+
return [manifestKey, entry];
|
|
117
285
|
};
|
|
118
286
|
return {
|
|
119
287
|
context: {
|
|
120
288
|
getVersionedImplementationId,
|
|
121
|
-
|
|
122
|
-
|
|
289
|
+
resolveAppKeys: async ({ appKeys }) => resolveAppKeys({
|
|
290
|
+
appKeys,
|
|
291
|
+
api,
|
|
292
|
+
manifest: (await getResolvedManifest()) ?? { apps: {} },
|
|
293
|
+
}),
|
|
294
|
+
updateManifestEntry,
|
|
123
295
|
},
|
|
124
296
|
};
|
|
125
297
|
};
|