@plasmicapp/cli 0.1.162

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 (162) hide show
  1. package/.eslintrc.js +61 -0
  2. package/.idea/cli.iml +11 -0
  3. package/.idea/misc.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/README +16 -0
  7. package/README.internal +46 -0
  8. package/README.md +17 -0
  9. package/build.sh +8 -0
  10. package/dist/__mocks__/api.d.ts +16 -0
  11. package/dist/__mocks__/api.js +297 -0
  12. package/dist/__tests__/code-utils-spec.d.ts +1 -0
  13. package/dist/__tests__/code-utils-spec.js +838 -0
  14. package/dist/__tests__/ftue-spec.d.ts +1 -0
  15. package/dist/__tests__/ftue-spec.js +39 -0
  16. package/dist/__tests__/project-api-token-spec.d.ts +1 -0
  17. package/dist/__tests__/project-api-token-spec.js +147 -0
  18. package/dist/__tests__/versioned-sync-spec.d.ts +1 -0
  19. package/dist/__tests__/versioned-sync-spec.js +145 -0
  20. package/dist/actions/auth.d.ts +8 -0
  21. package/dist/actions/auth.js +47 -0
  22. package/dist/actions/fix-imports.d.ts +4 -0
  23. package/dist/actions/fix-imports.js +25 -0
  24. package/dist/actions/init.d.ts +62 -0
  25. package/dist/actions/init.js +460 -0
  26. package/dist/actions/project-token.d.ts +6 -0
  27. package/dist/actions/project-token.js +42 -0
  28. package/dist/actions/sync-components.d.ts +10 -0
  29. package/dist/actions/sync-components.js +242 -0
  30. package/dist/actions/sync-global-variants.d.ts +3 -0
  31. package/dist/actions/sync-global-variants.js +89 -0
  32. package/dist/actions/sync-icons.d.ts +7 -0
  33. package/dist/actions/sync-icons.js +92 -0
  34. package/dist/actions/sync-images.d.ts +6 -0
  35. package/dist/actions/sync-images.js +137 -0
  36. package/dist/actions/sync-styles.d.ts +3 -0
  37. package/dist/actions/sync-styles.js +58 -0
  38. package/dist/actions/sync.d.ts +25 -0
  39. package/dist/actions/sync.js +417 -0
  40. package/dist/actions/upload-bundle.d.ts +15 -0
  41. package/dist/actions/upload-bundle.js +28 -0
  42. package/dist/actions/watch.d.ts +14 -0
  43. package/dist/actions/watch.js +90 -0
  44. package/dist/api.d.ts +182 -0
  45. package/dist/api.js +202 -0
  46. package/dist/deps.d.ts +2 -0
  47. package/dist/deps.js +20 -0
  48. package/dist/index.d.ts +7 -0
  49. package/dist/index.js +247 -0
  50. package/dist/lib.d.ts +10 -0
  51. package/dist/lib.js +23 -0
  52. package/dist/migrations/0.1.110-fileLocks.d.ts +2 -0
  53. package/dist/migrations/0.1.110-fileLocks.js +15 -0
  54. package/dist/migrations/0.1.143-ensureImportModuleType.d.ts +2 -0
  55. package/dist/migrations/0.1.143-ensureImportModuleType.js +12 -0
  56. package/dist/migrations/0.1.146-addReactRuntime.d.ts +2 -0
  57. package/dist/migrations/0.1.146-addReactRuntime.js +10 -0
  58. package/dist/migrations/0.1.27-migrateInit.d.ts +1 -0
  59. package/dist/migrations/0.1.27-migrateInit.js +8 -0
  60. package/dist/migrations/0.1.28-tsToTsx.d.ts +3 -0
  61. package/dist/migrations/0.1.28-tsToTsx.js +33 -0
  62. package/dist/migrations/0.1.31-ensureProjectIcons.d.ts +2 -0
  63. package/dist/migrations/0.1.31-ensureProjectIcons.js +12 -0
  64. package/dist/migrations/0.1.42-ensureVersion.d.ts +2 -0
  65. package/dist/migrations/0.1.42-ensureVersion.js +12 -0
  66. package/dist/migrations/0.1.57-ensureJsBundleThemes.d.ts +2 -0
  67. package/dist/migrations/0.1.57-ensureJsBundleThemes.js +12 -0
  68. package/dist/migrations/0.1.64-imageFiles.d.ts +2 -0
  69. package/dist/migrations/0.1.64-imageFiles.js +17 -0
  70. package/dist/migrations/0.1.95-componentType.d.ts +2 -0
  71. package/dist/migrations/0.1.95-componentType.js +16 -0
  72. package/dist/migrations/migrations.d.ts +10 -0
  73. package/dist/migrations/migrations.js +119 -0
  74. package/dist/plasmic.schema.json +463 -0
  75. package/dist/test-common/fixtures.d.ts +13 -0
  76. package/dist/test-common/fixtures.js +165 -0
  77. package/dist/tsconfig-transform.json +68 -0
  78. package/dist/utils/auth-utils.d.ts +31 -0
  79. package/dist/utils/auth-utils.js +236 -0
  80. package/dist/utils/checksum.d.ts +4 -0
  81. package/dist/utils/checksum.js +63 -0
  82. package/dist/utils/code-utils.d.ts +46 -0
  83. package/dist/utils/code-utils.js +457 -0
  84. package/dist/utils/config-utils.d.ts +271 -0
  85. package/dist/utils/config-utils.js +178 -0
  86. package/dist/utils/envdetect.d.ts +4 -0
  87. package/dist/utils/envdetect.js +42 -0
  88. package/dist/utils/error.d.ts +14 -0
  89. package/dist/utils/error.js +42 -0
  90. package/dist/utils/file-utils.d.ts +71 -0
  91. package/dist/utils/file-utils.js +433 -0
  92. package/dist/utils/get-context.d.ts +40 -0
  93. package/dist/utils/get-context.js +339 -0
  94. package/dist/utils/help.d.ts +2 -0
  95. package/dist/utils/help.js +56 -0
  96. package/dist/utils/lang-utils.d.ts +10 -0
  97. package/dist/utils/lang-utils.js +52 -0
  98. package/dist/utils/npm-utils.d.ts +28 -0
  99. package/dist/utils/npm-utils.js +215 -0
  100. package/dist/utils/prompts.d.ts +6 -0
  101. package/dist/utils/prompts.js +23 -0
  102. package/dist/utils/resolve-utils.d.ts +13 -0
  103. package/dist/utils/resolve-utils.js +198 -0
  104. package/dist/utils/semver.d.ts +34 -0
  105. package/dist/utils/semver.js +61 -0
  106. package/dist/utils/test-utils.d.ts +22 -0
  107. package/dist/utils/test-utils.js +106 -0
  108. package/dist/utils/user-utils.d.ts +7 -0
  109. package/dist/utils/user-utils.js +48 -0
  110. package/jest.config.js +6 -0
  111. package/package.json +80 -0
  112. package/src/__mocks__/api.ts +394 -0
  113. package/src/__tests__/code-utils-spec.ts +881 -0
  114. package/src/__tests__/ftue-spec.ts +43 -0
  115. package/src/__tests__/project-api-token-spec.ts +208 -0
  116. package/src/__tests__/versioned-sync-spec.ts +176 -0
  117. package/src/actions/auth.ts +43 -0
  118. package/src/actions/fix-imports.ts +13 -0
  119. package/src/actions/init.ts +638 -0
  120. package/src/actions/project-token.ts +36 -0
  121. package/src/actions/sync-components.ts +405 -0
  122. package/src/actions/sync-global-variants.ts +129 -0
  123. package/src/actions/sync-icons.ts +135 -0
  124. package/src/actions/sync-images.ts +191 -0
  125. package/src/actions/sync-styles.ts +71 -0
  126. package/src/actions/sync.ts +747 -0
  127. package/src/actions/upload-bundle.ts +38 -0
  128. package/src/actions/watch.ts +95 -0
  129. package/src/api.ts +407 -0
  130. package/src/deps.ts +18 -0
  131. package/src/index.ts +300 -0
  132. package/src/lib.ts +10 -0
  133. package/src/migrations/0.1.110-fileLocks.ts +16 -0
  134. package/src/migrations/0.1.146-addReactRuntime.ts +8 -0
  135. package/src/migrations/0.1.27-migrateInit.ts +4 -0
  136. package/src/migrations/0.1.28-tsToTsx.ts +37 -0
  137. package/src/migrations/0.1.31-ensureProjectIcons.ts +10 -0
  138. package/src/migrations/0.1.42-ensureVersion.ts +10 -0
  139. package/src/migrations/0.1.57-ensureJsBundleThemes.ts +10 -0
  140. package/src/migrations/0.1.64-imageFiles.ts +15 -0
  141. package/src/migrations/0.1.95-componentType.ts +14 -0
  142. package/src/migrations/migrations.ts +147 -0
  143. package/src/test-common/fixtures.ts +178 -0
  144. package/src/utils/auth-utils.ts +276 -0
  145. package/src/utils/checksum.ts +106 -0
  146. package/src/utils/code-utils.ts +656 -0
  147. package/src/utils/config-utils.ts +551 -0
  148. package/src/utils/envdetect.ts +39 -0
  149. package/src/utils/error.ts +36 -0
  150. package/src/utils/file-utils.ts +526 -0
  151. package/src/utils/get-context.ts +451 -0
  152. package/src/utils/help.ts +75 -0
  153. package/src/utils/lang-utils.ts +52 -0
  154. package/src/utils/npm-utils.ts +223 -0
  155. package/src/utils/prompts.ts +22 -0
  156. package/src/utils/resolve-utils.ts +245 -0
  157. package/src/utils/semver.ts +67 -0
  158. package/src/utils/test-utils.ts +116 -0
  159. package/src/utils/user-utils.ts +37 -0
  160. package/testData/fixImports_plasmic.json +66 -0
  161. package/tsconfig-transform.json +68 -0
  162. package/tsconfig.json +67 -0
@@ -0,0 +1,38 @@
1
+ import pako from "pako";
2
+ import { CommonArgs } from "..";
3
+ import { readFileText } from "../utils/file-utils";
4
+ import { getContext } from "../utils/get-context";
5
+
6
+ export interface UploadBundleArgs extends CommonArgs {
7
+ project: string;
8
+ bundleName: string;
9
+ bundleJsFile: string;
10
+ cssFiles: readonly string[];
11
+ metaJsonFile: string;
12
+ genModulePath?: string;
13
+ genCssPaths: string[];
14
+ pkgVersion?: string;
15
+ extraPropMetaJsonFile?: string;
16
+ themeProviderWrapper?: string;
17
+ themeModuleFile?: string;
18
+ }
19
+
20
+ export async function uploadJsBundle(opts: UploadBundleArgs) {
21
+ const context = await getContext(opts);
22
+ const api = context.api;
23
+ await api.uploadBundle(
24
+ opts.project,
25
+ opts.bundleName,
26
+ pako.deflate(readFileText(opts.bundleJsFile), { to: "string" }),
27
+ opts.cssFiles.map((f) => pako.deflate(readFileText(f), { to: "string" })),
28
+ pako.deflate(readFileText(opts.metaJsonFile), { to: "string" }),
29
+ opts.genModulePath,
30
+ opts.genCssPaths,
31
+ opts.pkgVersion,
32
+ opts.extraPropMetaJsonFile
33
+ ? readFileText(opts.extraPropMetaJsonFile)
34
+ : undefined,
35
+ opts.themeProviderWrapper,
36
+ opts.themeModuleFile ? readFileText(opts.themeModuleFile) : undefined
37
+ );
38
+ }
@@ -0,0 +1,95 @@
1
+ import L from "lodash";
2
+ import moment from "moment";
3
+ import { CommonArgs } from "..";
4
+ import { logger } from "../deps";
5
+ import { HandledError } from "../utils/error";
6
+ import { getContext, Metadata } from "../utils/get-context";
7
+ import * as semver from "../utils/semver";
8
+ import { sync } from "./sync";
9
+
10
+ export interface WatchArgs extends CommonArgs {
11
+ projects: readonly string[];
12
+ forceOverwrite: boolean;
13
+ newComponentScheme?: "blackbox" | "direct";
14
+ appendJsxOnMissingBase?: boolean;
15
+ yes?: boolean;
16
+ force?: boolean;
17
+ nonRecursive?: boolean;
18
+ skipUpgradeCheck?: boolean;
19
+ metadata?: string;
20
+ }
21
+ export async function watchProjects(
22
+ opts: WatchArgs,
23
+ metadataDefaults?: Metadata,
24
+ onProjectUpdate?: () => void
25
+ ): Promise<void> {
26
+ // Perform a sync before watch.
27
+ const syncOpts = {
28
+ ...opts,
29
+ quiet: true,
30
+ };
31
+ const syncMetadata: Metadata = {
32
+ ...metadataDefaults,
33
+ command: "watch", // force this to be set
34
+ };
35
+ await sync(syncOpts, syncMetadata);
36
+
37
+ const context = await getContext(opts);
38
+ const config = context.config;
39
+ const socket = context.api.connectSocket();
40
+ const projectIds = L.uniq(
41
+ opts.projects.length > 0
42
+ ? opts.projects
43
+ : config.projects.map((c) => c.projectId)
44
+ );
45
+
46
+ // Filter out projects that are not latest
47
+ const latestProjects = projectIds.filter((projectId) => {
48
+ const projectConfig = config.projects.find(
49
+ (p) => p.projectId === projectId
50
+ );
51
+ return !projectConfig || semver.isLatest(projectConfig.version);
52
+ });
53
+
54
+ if (projectIds.length !== latestProjects.length) {
55
+ const filteredProjects = L.difference(projectIds, latestProjects);
56
+ logger.warn(
57
+ `Warning: watch only works for projects with version="latest". Ignoring ${filteredProjects}`
58
+ );
59
+ }
60
+
61
+ if (latestProjects.length === 0) {
62
+ throw new HandledError(
63
+ "Don't know which projects to sync; please specify via --projects"
64
+ );
65
+ }
66
+
67
+ const promise = new Promise<void>((resolve, reject) => {
68
+ socket.on("initServerInfo", () => {
69
+ // upon connection, subscribe to changes for argument projects
70
+ socket.emit("subscribe", {
71
+ namespace: "projects",
72
+ projectIds: latestProjects,
73
+ });
74
+ });
75
+ socket.on("error", (data: any) => {
76
+ reject(new HandledError(data));
77
+ });
78
+ socket.on("update", async (data: any) => {
79
+ // Just run syncProjects() for now when any project has been updated
80
+ // Note on the 'updated to revision' part: this is parsed by the
81
+ // loader package to know that we finished updating the components.
82
+ await sync(syncOpts, syncMetadata);
83
+ logger.info(
84
+ `[${moment().format("HH:mm:ss")}] Project ${
85
+ data.projectId
86
+ } updated to revision ${data.revisionNum}`
87
+ );
88
+
89
+ onProjectUpdate?.();
90
+ });
91
+ });
92
+
93
+ logger.info(`Watching projects ${latestProjects} ...`);
94
+ return promise;
95
+ }
package/src/api.ts ADDED
@@ -0,0 +1,407 @@
1
+ import { ProjectSyncMetadataModel } from "@plasmicapp/code-merger";
2
+ import axios, { AxiosError } from "axios";
3
+ import socketio from "socket.io-client";
4
+ import {
5
+ AuthConfig,
6
+ CodeConfig,
7
+ DEFAULT_HOST,
8
+ ImagesConfig,
9
+ StyleConfig,
10
+ } from "./utils/config-utils";
11
+ import { HandledError } from "./utils/error";
12
+ import { Metadata } from "./utils/get-context";
13
+
14
+ export class AppServerError extends Error {
15
+ constructor(message: string) {
16
+ super(message);
17
+ }
18
+ }
19
+
20
+ export interface ComponentBundle {
21
+ renderModule: string;
22
+ skeletonModule: string;
23
+ cssRules: string;
24
+ renderModuleFileName: string;
25
+ skeletonModuleFileName: string;
26
+ cssFileName: string;
27
+ componentName: string;
28
+ id: string;
29
+ scheme: string;
30
+ nameInIdToUuid: Array<[string, string]>;
31
+ isPage: boolean;
32
+ plumeType?: string;
33
+ }
34
+
35
+ export interface GlobalVariantBundle {
36
+ id: string;
37
+ name: string;
38
+ contextModule: string;
39
+ contextFileName: string;
40
+ }
41
+
42
+ export interface JsBundleTheme {
43
+ themeFileName: string;
44
+ themeModule: string;
45
+ bundleName: string;
46
+ }
47
+
48
+ export interface ProjectMetaBundle {
49
+ projectId: string;
50
+ projectName: string;
51
+ cssFileName: string;
52
+ cssRules: string;
53
+ jsBundleThemes?: JsBundleTheme[];
54
+ }
55
+
56
+ export interface IconBundle {
57
+ id: string;
58
+ name: string;
59
+ module: string;
60
+ fileName: string;
61
+ }
62
+
63
+ export interface ImageBundle {
64
+ id: string;
65
+ name: string;
66
+ blob: string;
67
+ fileName: string;
68
+ }
69
+
70
+ export interface ProjectVersionMeta {
71
+ projectId: string;
72
+ projectApiToken: string;
73
+ version: string;
74
+ projectName: string;
75
+ componentIds: string[];
76
+ dependencies: {
77
+ [projectId: string]: string;
78
+ };
79
+ }
80
+
81
+ export interface VersionResolution {
82
+ projects: ProjectVersionMeta[];
83
+ dependencies: ProjectVersionMeta[];
84
+ conflicts: ProjectVersionMeta[];
85
+ }
86
+
87
+ export interface RequiredPackages {
88
+ "@plasmicapp/loader": string;
89
+ "@plasmicapp/cli": string;
90
+ "@plasmicapp/react-web": string;
91
+ "@plasmicapp/react-web-runtime": string;
92
+ }
93
+
94
+ export interface ProjectBundle {
95
+ components: ComponentBundle[];
96
+ codeComponentMetas: CodeComponentMeta[];
97
+ projectConfig: ProjectMetaBundle;
98
+ globalVariants: GlobalVariantBundle[];
99
+ usedTokens: StyleTokensMap;
100
+ iconAssets: IconBundle[];
101
+ imageAssets: ImageBundle[];
102
+ checksums: ChecksumBundle;
103
+ }
104
+
105
+ export type ProjectMeta = Omit<ProjectBundle, "projectConfig">;
106
+
107
+ export interface StyleConfigResponse {
108
+ defaultStyleCssFileName: string;
109
+ defaultStyleCssRules: string;
110
+ }
111
+
112
+ export interface StyleTokensMap {
113
+ props: {
114
+ name: string;
115
+ type: string;
116
+ value: string | number;
117
+ meta: {
118
+ projectId: string;
119
+ id: string;
120
+ };
121
+ }[];
122
+ global: {
123
+ meta: {
124
+ source: "plasmic.app";
125
+ };
126
+ };
127
+ }
128
+
129
+ export interface ChecksumBundle {
130
+ // List of checksums as [ComponentBundle.id, checksum]
131
+ renderModuleChecksums: Array<[string, string]>;
132
+ // List of checksums as [ComponentBundle.id, checksum]
133
+ cssRulesChecksums: Array<[string, string]>;
134
+ // List of checksums as [imageBundle.id, checksum]
135
+ imageChecksums: Array<[string, string]>;
136
+ // List of checksums as [IconBundle.id, checksum]
137
+ iconChecksums: Array<[string, string]>;
138
+ // List of checksums as [GlobalVariant.id, checksum]
139
+ globalVariantChecksums: Array<[string, string]>;
140
+ // Checksum of projectCss file
141
+ projectCssChecksum: string;
142
+ }
143
+
144
+ export interface CodeComponentMeta {
145
+ id: string; // component uuid
146
+ name: string;
147
+ importPath: string;
148
+ }
149
+
150
+ export interface ProjectIconsResponse {
151
+ version: string;
152
+ icons: IconBundle[];
153
+ }
154
+
155
+ export interface ProjectIdAndToken {
156
+ projectId: string;
157
+ projectApiToken?: string;
158
+ }
159
+
160
+ export class PlasmicApi {
161
+ constructor(private auth: AuthConfig) {}
162
+
163
+ async genStyleConfig(styleOpts?: StyleConfig): Promise<StyleConfigResponse> {
164
+ const result = await this.post(
165
+ `${this.codegenHost}/api/v1/code/style-config`,
166
+ styleOpts
167
+ );
168
+ return result.data as StyleConfigResponse;
169
+ }
170
+
171
+ /**
172
+ * Sync resolution - Given a fuzzy idea of what the user wants,
173
+ * (i.e. a versionRange and component names),
174
+ * ask the server for the exact references for a later call to `projectComponents`
175
+ * - For components specified in the parameters - the server will return the latest version that satisfies the versionRange
176
+ * - Any conflicting versions will be returned in `conflicts`, and should cause the client's sync to abort
177
+ * @param projects
178
+ * @param recursive
179
+ */
180
+ async resolveSync(
181
+ projects: {
182
+ projectId: string;
183
+ versionRange?: string;
184
+ componentIdOrNames: readonly string[] | undefined;
185
+ projectApiToken?: string;
186
+ }[],
187
+ recursive?: boolean
188
+ ): Promise<VersionResolution> {
189
+ const resp: any = await this.post(
190
+ `${this.codegenHost}/api/v1/code/resolve-sync`,
191
+ {
192
+ projects,
193
+ recursive,
194
+ }
195
+ );
196
+ const versionResolution = resp.data as VersionResolution;
197
+ return { ...versionResolution };
198
+ }
199
+
200
+ async getCurrentUser() {
201
+ return await axios.get(`${this.studioHost}/api/v1/auth/self`, {
202
+ headers: this.makeHeaders(),
203
+ });
204
+ }
205
+
206
+ async requiredPackages(): Promise<RequiredPackages> {
207
+ const resp = await this.post(
208
+ `${this.codegenHost}/api/v1/code/required-packages`
209
+ );
210
+ return { ...resp.data } as RequiredPackages;
211
+ }
212
+
213
+ /**
214
+ * Code-gen endpoint.
215
+ * This will fetch components at an exact specified version.
216
+ * If you don't know what version should be used, call `resolveSync` first.
217
+ * @param projectId
218
+ * @param cliVersion
219
+ * @param reactWebVersion
220
+ * @param newCompScheme
221
+ * @param existingCompScheme
222
+ * @param componentIdOrNames
223
+ * @param version
224
+ */
225
+ async projectComponents(
226
+ projectId: string,
227
+ opts: {
228
+ platform: string;
229
+ newCompScheme: "blackbox" | "direct";
230
+ // The list of existing components as [componentUuid, codeScheme]
231
+ existingCompScheme: Array<[string, "blackbox" | "direct"]>;
232
+ componentIdOrNames: readonly string[] | undefined;
233
+ version: string;
234
+ imageOpts: ImagesConfig;
235
+ stylesOpts: StyleConfig;
236
+ codeOpts: CodeConfig;
237
+ checksums: ChecksumBundle;
238
+ metadata?: Metadata;
239
+ }
240
+ ): Promise<ProjectBundle> {
241
+ const result = await this.post(
242
+ `${this.codegenHost}/api/v1/projects/${projectId}/code/components`,
243
+ {
244
+ ...opts,
245
+ }
246
+ );
247
+ return result.data as ProjectBundle;
248
+ }
249
+
250
+ async uploadBundle(
251
+ projectId: string,
252
+ bundleName: string,
253
+ bundleJs: string,
254
+ css: string[],
255
+ metaJson: string,
256
+ genModulePath: string | undefined,
257
+ genCssPaths: string[],
258
+ pkgVersion: string | undefined,
259
+ extraPropMetaJson: string | undefined,
260
+ themeProviderWrapper: string | undefined,
261
+ themeModule: string | undefined
262
+ ): Promise<StyleTokensMap> {
263
+ const result = await this.post(
264
+ `${this.codegenHost}/api/v1/projects/${projectId}/jsbundle/upload`,
265
+ {
266
+ projectId,
267
+ bundleName,
268
+ bundleJs,
269
+ css,
270
+ metaJson,
271
+ genModulePath,
272
+ genCssPaths,
273
+ pkgVersion,
274
+ extraPropMetaJson,
275
+ themeProviderWrapper,
276
+ themeModule,
277
+ }
278
+ );
279
+ return result.data as StyleTokensMap;
280
+ }
281
+
282
+ async projectStyleTokens(
283
+ projectId: string,
284
+ versionRange?: string
285
+ ): Promise<StyleTokensMap> {
286
+ const result = await this.post(
287
+ `${this.codegenHost}/api/v1/projects/${projectId}/code/tokens`,
288
+ { versionRange }
289
+ );
290
+ return result.data as StyleTokensMap;
291
+ }
292
+
293
+ async projectIcons(
294
+ projectId: string,
295
+ versionRange?: string,
296
+ iconIds?: string[]
297
+ ): Promise<ProjectIconsResponse> {
298
+ const result = await this.post(
299
+ `${this.codegenHost}/api/v1/projects/${projectId}/code/icons`,
300
+ { versionRange, iconIds }
301
+ );
302
+ return result.data as ProjectIconsResponse;
303
+ }
304
+
305
+ async projectSyncMetadata(
306
+ projectId: string,
307
+ revision: number,
308
+ rethrowAppError: boolean
309
+ ): Promise<ProjectSyncMetadataModel> {
310
+ const result = await this.post(
311
+ `${this.codegenHost}/api/v1/projects/${projectId}/code/project-sync-metadata`,
312
+ { revision },
313
+ rethrowAppError
314
+ );
315
+ return ProjectSyncMetadataModel.fromJson(result.data);
316
+ }
317
+
318
+ connectSocket(): SocketIOClient.Socket {
319
+ const socket = socketio.connect(this.studioHost, {
320
+ path: `/api/v1/socket`,
321
+ transportOptions: {
322
+ polling: {
323
+ extraHeaders: this.makeHeaders(),
324
+ },
325
+ },
326
+ });
327
+ return socket;
328
+ }
329
+
330
+ // If rethrowAppError is true, we will throw an exception with the error
331
+ // message
332
+ private async post(url: string, data?: any, rethrowAppError?: boolean) {
333
+ try {
334
+ return await axios.post(
335
+ url,
336
+ { projectIdsAndTokens: this.projectIdsAndTokens, ...data },
337
+ {
338
+ headers: this.makeHeaders(),
339
+ }
340
+ );
341
+ } catch (e) {
342
+ const error = e as AxiosError;
343
+ const errorMsg = this.makeErrorMessage(error);
344
+
345
+ if (rethrowAppError) {
346
+ throw new AppServerError(errorMsg);
347
+ }
348
+
349
+ if (!errorMsg) {
350
+ throw e;
351
+ }
352
+
353
+ throw new HandledError(errorMsg);
354
+ }
355
+ }
356
+
357
+ private makeErrorMessage(error: AxiosError) {
358
+ const response = error.response;
359
+ if (!response) {
360
+ return undefined;
361
+ }
362
+ if (response.status === 403) {
363
+ return `Incorrect Plasmic credentials; please check your .plasmic.auth file or your project API tokens.`;
364
+ }
365
+ if (response.data?.error?.message) {
366
+ return response.data.error.message;
367
+ } else if (response.data) {
368
+ return `Error: request failed with status code ${response.status}. The response is
369
+ ${response.data}`;
370
+ } else {
371
+ return undefined;
372
+ }
373
+ }
374
+
375
+ private makeHeaders() {
376
+ const headers: Record<string, string> = {
377
+ "x-plasmic-api-user": this.auth.user,
378
+ "x-plasmic-api-token": this.auth.token,
379
+ };
380
+
381
+ if (this.auth.basicAuthUser && this.auth.basicAuthPassword) {
382
+ const authString = Buffer.from(
383
+ `${this.auth.basicAuthUser}:${this.auth.basicAuthPassword}`
384
+ ).toString("base64");
385
+ headers["Authorization"] = `Basic ${authString}`;
386
+ }
387
+
388
+ return headers;
389
+ }
390
+
391
+ private projectIdsAndTokens?: ProjectIdAndToken[];
392
+ attachProjectIdsAndTokens(idsAndTokens: ProjectIdAndToken[]) {
393
+ this.projectIdsAndTokens = idsAndTokens;
394
+ }
395
+
396
+ private get studioHost() {
397
+ return this.auth.host;
398
+ }
399
+
400
+ private get codegenHost() {
401
+ if (!this.auth.host || this.auth.host === DEFAULT_HOST) {
402
+ return "https://codegen.plasmic.app";
403
+ } else {
404
+ return this.auth.host;
405
+ }
406
+ }
407
+ }
package/src/deps.ts ADDED
@@ -0,0 +1,18 @@
1
+ import winston from "winston";
2
+
3
+ export const logger = winston.createLogger({
4
+ level: "info",
5
+ format: winston.format.json(),
6
+ defaultMeta: {},
7
+ transports: [
8
+ new winston.transports.Console({
9
+ format: winston.format.printf(
10
+ (info) => `${info.message}`
11
+ //info => `${moment().format("HH:mm:ss")}:${info.level}\t${info.message}`
12
+ ),
13
+ stderrLevels: ["error"],
14
+ }),
15
+ //new winston.transports.File({ filename: "error.log", level: "error" }),
16
+ //new winston.transports.File({ filename: "combined.log", level: "info" }),
17
+ ],
18
+ });