@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,178 @@
1
+ import L from "lodash";
2
+ import { SyncArgs } from "../actions/sync";
3
+ import { PlasmicConfig, ProjectConfig } from "../utils/config-utils";
4
+ import { TempRepo } from "../utils/test-utils";
5
+ import { MockProject } from "../__mocks__/api";
6
+
7
+ jest.mock("../api");
8
+
9
+ export const mockApi = require("../api");
10
+ export let opts: SyncArgs; // Options to pass to sync
11
+ export let tmpRepo: TempRepo;
12
+
13
+ export const defaultPlasmicJson: PlasmicConfig = {
14
+ platform: "react",
15
+ code: {
16
+ lang: "ts",
17
+ scheme: "blackbox",
18
+ reactRuntime: "classic",
19
+ },
20
+ style: {
21
+ scheme: "css",
22
+ defaultStyleCssFilePath: "plasmic/PP__plasmic__default_style.css",
23
+ },
24
+ images: {
25
+ scheme: "inlined",
26
+ },
27
+ tokens: {
28
+ scheme: "theo",
29
+ tokensFilePath: "plasmic-tokens.theo.json",
30
+ },
31
+ srcDir: "src/",
32
+ defaultPlasmicDir: "./plasmic",
33
+ projects: [],
34
+ globalVariants: {
35
+ variantGroups: [],
36
+ },
37
+ cliVersion: "0.1.44",
38
+ };
39
+ export function standardTestSetup(includeDep = true) {
40
+ process.env.PLASMIC_DISABLE_AUTH_SEARCH = "1";
41
+
42
+ // Setup server-side mock data
43
+ const project1: MockProject = {
44
+ projectId: "projectId1",
45
+ projectApiToken: "abc",
46
+ version: "1.2.3",
47
+ projectName: "project1",
48
+ components: [
49
+ {
50
+ id: "buttonId",
51
+ name: "Button",
52
+ },
53
+ {
54
+ id: "containerId",
55
+ name: "Container",
56
+ },
57
+ ],
58
+ dependencies: includeDep
59
+ ? {
60
+ dependencyId1: "2.3.4",
61
+ }
62
+ : {},
63
+ };
64
+ const dependency: MockProject = {
65
+ projectId: "dependencyId1",
66
+ projectApiToken: "def",
67
+ version: "2.3.4",
68
+ projectName: "dependency1",
69
+ components: [
70
+ {
71
+ id: "depComponentId",
72
+ name: "DepComponent",
73
+ },
74
+ ],
75
+ dependencies: {},
76
+ };
77
+ [project1, dependency].forEach((p) => mockApi.addMockProject(p));
78
+
79
+ // Setup client-side directory
80
+ tmpRepo = new TempRepo();
81
+ tmpRepo.writePlasmicAuth({
82
+ host: "http://localhost:3003",
83
+ user: "yang@plasmic.app",
84
+ token: "faketoken",
85
+ });
86
+ tmpRepo.writePlasmicJson(defaultPlasmicJson);
87
+
88
+ // Default opts and config
89
+ opts = {
90
+ projects: [],
91
+ yes: true,
92
+ force: true,
93
+ nonRecursive: false,
94
+ skipUpgradeCheck: true,
95
+ forceOverwrite: true,
96
+ newComponentScheme: "blackbox",
97
+ appendJsxOnMissingBase: false,
98
+ config: tmpRepo.plasmicJsonPath(),
99
+ auth: tmpRepo.plasmicAuthPath(),
100
+ loaderConfig: tmpRepo.plasmicLoaderJsonPath(),
101
+ baseDir: process.cwd(),
102
+ };
103
+ }
104
+
105
+ export function standardTestTeardown() {
106
+ tmpRepo.destroy();
107
+ mockApi.clear();
108
+ delete process.env["PLASMIC_DISABLE_AUTH_SEARCH"];
109
+ }
110
+
111
+ export function expectProject1Components() {
112
+ // Check correct files exist
113
+ const button = mockApi.stringToMockComponent(
114
+ tmpRepo.getComponentFileContents("projectId1", "buttonId")
115
+ );
116
+ const container = mockApi.stringToMockComponent(
117
+ tmpRepo.getComponentFileContents("projectId1", "containerId")
118
+ );
119
+ expect(button).toBeTruthy();
120
+ expect(container).toBeTruthy();
121
+ expect(button?.name).toEqual("Button");
122
+ expect(button?.version).toEqual("1.2.3");
123
+ expect(container?.name).toEqual("Container");
124
+ expect(container?.version).toEqual("1.2.3");
125
+ }
126
+
127
+ export const project1Config: ProjectConfig = {
128
+ projectId: "projectId1",
129
+ projectName: "Project 1",
130
+ version: "latest",
131
+ cssFilePath: "plasmic/PP__demo.css",
132
+ components: [
133
+ {
134
+ id: "buttonId",
135
+ name: "Button",
136
+ type: "managed",
137
+ projectId: "projectId1",
138
+ renderModuleFilePath: "plasmic/project_id_1/PlasmicButton.tsx",
139
+ importSpec: {
140
+ modulePath: "Button.tsx",
141
+ },
142
+ cssFilePath: "plasmic/PlasmicButton.css",
143
+ scheme: "blackbox",
144
+ componentType: "component",
145
+ },
146
+ ],
147
+ icons: [],
148
+ images: [],
149
+ jsBundleThemes: [],
150
+ };
151
+
152
+ export function expectProject1PlasmicJson() {
153
+ const plasmicJson = tmpRepo.readPlasmicJson();
154
+ expect(plasmicJson.projects.length).toEqual(1);
155
+ const projectConfig = plasmicJson.projects[0];
156
+ expect(projectConfig.projectApiToken).toBe("abc");
157
+ expect(projectConfig.components.length).toEqual(2);
158
+ const componentNames = projectConfig.components.map((c) => c.name);
159
+ expect(componentNames).toContain("Button");
160
+ expect(componentNames).toContain("Container");
161
+ }
162
+
163
+ export function expectProjectAndDepPlasmicJson() {
164
+ const plasmicJson = tmpRepo.readPlasmicJson();
165
+ expect(plasmicJson.projects.length).toEqual(2);
166
+ const projectConfigMap = L.keyBy(plasmicJson.projects, (p) => p.projectId);
167
+ expect(projectConfigMap["projectId1"]).toBeTruthy();
168
+ expect(projectConfigMap["dependencyId1"]).toBeTruthy();
169
+ const projectComponentNames = projectConfigMap["projectId1"].components.map(
170
+ (c) => c.name
171
+ );
172
+ const depComponentNames = projectConfigMap["dependencyId1"].components.map(
173
+ (c) => c.name
174
+ );
175
+ expect(projectComponentNames).toContain("Button");
176
+ expect(projectComponentNames).toContain("Container");
177
+ expect(depComponentNames).toContain("DepComponent");
178
+ }
@@ -0,0 +1,276 @@
1
+ import fs from "fs";
2
+ import inquirer from "inquirer";
3
+ import open from "open";
4
+ import os from "os";
5
+ import socketio from "socket.io-client";
6
+ import path from "upath";
7
+ import { v4 as uuidv4 } from "uuid";
8
+ import { PlasmicApi } from "../api";
9
+ import { logger } from "../deps";
10
+ import { CommonArgs } from "../index";
11
+ import { HandledError } from "../utils/error";
12
+ import {
13
+ AuthConfig,
14
+ AUTH_FILE_NAME,
15
+ DEFAULT_HOST,
16
+ ENV_AUTH_HOST,
17
+ ENV_AUTH_TOKEN,
18
+ ENV_AUTH_USER,
19
+ } from "./config-utils";
20
+ import {
21
+ existsBuffered,
22
+ findFile,
23
+ readFileText,
24
+ writeFileContentRaw,
25
+ } from "./file-utils";
26
+
27
+ export type AuthData = {
28
+ user: string;
29
+ token: string;
30
+ };
31
+
32
+ export type CancellablePromise<T> = {
33
+ promise: Promise<T>;
34
+ cancel: () => void;
35
+ };
36
+
37
+ export function authByPolling(
38
+ host: string,
39
+ initToken: string
40
+ ): CancellablePromise<AuthData> {
41
+ const socket = socketio.connect(host, {
42
+ path: `/api/v1/init-token`,
43
+ transportOptions: {
44
+ polling: {
45
+ extraHeaders: {
46
+ "x-plasmic-init-token": initToken,
47
+ },
48
+ },
49
+ },
50
+ });
51
+
52
+ const promise = new Promise<AuthData>((resolve, reject) => {
53
+ socket.on("connect", (reason: string) => {
54
+ logger.info("Waiting for token...");
55
+ });
56
+
57
+ socket.on("token", (data: AuthData) => {
58
+ resolve(data);
59
+ socket.close();
60
+ });
61
+
62
+ socket.on("error", (error: {}) => {
63
+ logger.warn(error);
64
+ reject(error);
65
+ });
66
+ });
67
+
68
+ const cancel = () => {
69
+ socket.close();
70
+ };
71
+
72
+ return { promise, cancel };
73
+ }
74
+
75
+ function authByPrompt(host: string) {
76
+ const promise = inquirer.prompt([
77
+ {
78
+ name: "user",
79
+ message: "Your Plasmic user email",
80
+ },
81
+ {
82
+ name: "token",
83
+ message: `Your personal access token (create one at ${host}/self/settings)`,
84
+ },
85
+ ]);
86
+
87
+ const cancel = () => {
88
+ logger.info("Cancelling prompt...");
89
+ process.stdin.pause();
90
+ };
91
+
92
+ return { promise, cancel };
93
+ }
94
+
95
+ export async function startAuth(opts: Partial<CommonArgs> & { host: string }) {
96
+ if (opts.yes) {
97
+ throw new HandledError("Plasmic credentials could not be found.");
98
+ }
99
+
100
+ const auth = await new Promise<AuthData>((resolve, reject) => {
101
+ let prompt: CancellablePromise<AuthData>;
102
+
103
+ const initToken = uuidv4();
104
+ const url = `${opts.host}/auth/plasmic-init/${initToken}`;
105
+ open(url);
106
+ logger.info(
107
+ `\nIf your browser doesn't automatically open, enter the following URL:\n${url}\n`
108
+ );
109
+
110
+ logger.info(`Please log in and authorize Plasmic CLI.`);
111
+ const polling = authByPolling(opts.host, initToken);
112
+ polling.promise.then((auth) => {
113
+ if (prompt) {
114
+ prompt.cancel();
115
+ } else {
116
+ clearTimeout(timeout);
117
+ }
118
+ resolve(auth);
119
+ });
120
+
121
+ // Default to 1 minute.
122
+ const authPollTimeout =
123
+ Number(process.env.PLASMIC_AUTH_POLL_TIMEOUT) || 60 * 1000;
124
+ if (authPollTimeout === -1) {
125
+ return;
126
+ }
127
+ const timeout = setTimeout(() => {
128
+ logger.info(`We haven't received an auth token from Plasmic yet.`);
129
+ prompt = authByPrompt(opts.host);
130
+ prompt.promise
131
+ .then((auth) => {
132
+ polling.cancel();
133
+ resolve(auth);
134
+ })
135
+ .catch(reject);
136
+ }, authPollTimeout);
137
+ });
138
+
139
+ if (!auth.user || !auth.token) {
140
+ logger.error(`Could not get auth token.`);
141
+ return;
142
+ }
143
+
144
+ const newAuthFile = opts.auth || path.join(os.homedir(), AUTH_FILE_NAME);
145
+
146
+ await writeAuth(newAuthFile, {
147
+ host: opts.host,
148
+ user: auth.user,
149
+ token: auth.token,
150
+ });
151
+
152
+ logger.info(
153
+ `Successfully created Plasmic credentials file at ${newAuthFile}`
154
+ );
155
+ }
156
+
157
+ export function readAuth(authFile: string) {
158
+ if (!existsBuffered(authFile)) {
159
+ throw new HandledError(`No Plasmic auth file found at ${authFile}`);
160
+ }
161
+ try {
162
+ const parsed = JSON.parse(readFileText(authFile)) as AuthConfig;
163
+ // Strip trailing slashes.
164
+ return {
165
+ ...parsed,
166
+ host: parsed.host.replace(/\/+$/, ""),
167
+ };
168
+ } catch (e) {
169
+ logger.error(
170
+ `Error encountered reading plasmic credentials at ${authFile}: ${e}`
171
+ );
172
+ throw e;
173
+ }
174
+ }
175
+
176
+ export function getEnvAuth(): AuthConfig | undefined {
177
+ const host = process.env[ENV_AUTH_HOST];
178
+ const user = process.env[ENV_AUTH_USER];
179
+ const token = process.env[ENV_AUTH_TOKEN];
180
+
181
+ // both user and token are required
182
+ if (!user || !token) {
183
+ // Try to give a hint if they partially entered a credential
184
+ if (user || token) {
185
+ logger.warn(
186
+ `Your Plasmic credentials were only partially set via environment variables. Try both ${ENV_AUTH_USER} and ${ENV_AUTH_TOKEN}`
187
+ );
188
+ }
189
+ return;
190
+ }
191
+
192
+ return {
193
+ host: host ?? DEFAULT_HOST,
194
+ user,
195
+ token,
196
+ };
197
+ }
198
+
199
+ function readCurrentAuth(authPath?: string) {
200
+ const authFromEnv = getEnvAuth();
201
+ if (authFromEnv) return authFromEnv;
202
+
203
+ if (!authPath && !process.env.PLASMIC_DISABLE_AUTH_SEARCH) {
204
+ authPath = findAuthFile(process.cwd(), { traverseParents: true });
205
+ }
206
+ if (!authPath) {
207
+ return undefined;
208
+ }
209
+ return readAuth(authPath);
210
+ }
211
+
212
+ export async function getCurrentAuth(authPath?: string) {
213
+ const auth = readCurrentAuth(authPath);
214
+ if (!auth) {
215
+ return undefined;
216
+ }
217
+ const api = new PlasmicApi(auth);
218
+ try {
219
+ await api.getCurrentUser();
220
+ return auth;
221
+ } catch (e) {
222
+ if (e.response?.status === 401) {
223
+ logger.error(`The current credentials expired or are not valid.`);
224
+ return undefined;
225
+ }
226
+ throw e;
227
+ }
228
+ }
229
+
230
+ function failAuth() {
231
+ throw new HandledError(
232
+ `Unable to authenticate Plasmic. Please run 'plasmic auth'.`
233
+ );
234
+ }
235
+
236
+ export async function getOrStartAuth(
237
+ opts: CommonArgs & { host: string; enableSkipAuth?: boolean }
238
+ ) {
239
+ let auth = await getCurrentAuth(opts.auth);
240
+ if (!auth && opts.enableSkipAuth) {
241
+ return;
242
+ }
243
+ if (!auth && opts.yes) {
244
+ failAuth();
245
+ }
246
+ if (!auth) {
247
+ await startAuth(opts);
248
+ auth = await getCurrentAuth(opts.auth);
249
+ }
250
+ if (!auth) {
251
+ failAuth();
252
+ }
253
+ return auth;
254
+ }
255
+
256
+ export function findAuthFile(
257
+ dir: string,
258
+ opts: {
259
+ traverseParents?: boolean;
260
+ }
261
+ ) {
262
+ let file = findFile(dir, (f) => f === AUTH_FILE_NAME, opts);
263
+ if (!file) {
264
+ file = findFile(os.homedir(), (f) => f === AUTH_FILE_NAME, {
265
+ traverseParents: false,
266
+ });
267
+ }
268
+ return file;
269
+ }
270
+
271
+ export async function writeAuth(authFile: string, config: AuthConfig) {
272
+ await writeFileContentRaw(authFile, JSON.stringify(config, undefined, 2), {
273
+ force: true,
274
+ });
275
+ fs.chmodSync(authFile, "600");
276
+ }
@@ -0,0 +1,106 @@
1
+ import { SyncArgs } from "../actions/sync";
2
+ import { ChecksumBundle } from "../api";
3
+ import { PlasmicContext } from "./config-utils";
4
+ import { assert } from "./lang-utils";
5
+
6
+ export function getChecksums(
7
+ context: PlasmicContext,
8
+ opts: SyncArgs,
9
+ projectId: string,
10
+ componentIds: string[]
11
+ ): ChecksumBundle {
12
+ const projectConfig = context.config.projects.find(
13
+ (p) => p.projectId === projectId
14
+ );
15
+
16
+ const projectLock = context.lock.projects.find(
17
+ (projectLock) => projectLock.projectId === projectId
18
+ );
19
+
20
+ if (!projectConfig || !projectLock || opts.allFiles) {
21
+ return {
22
+ imageChecksums: [],
23
+ iconChecksums: [],
24
+ renderModuleChecksums: [],
25
+ cssRulesChecksums: [],
26
+ globalVariantChecksums: [],
27
+ projectCssChecksum: "",
28
+ };
29
+ }
30
+
31
+ const fileLocks = projectLock.fileLocks;
32
+
33
+ const knownImages = new Set(projectConfig.images.map((i) => i.id));
34
+ const knownIcons = new Set(projectConfig.icons.map((i) => i.id));
35
+ const knownComponents = new Set(projectConfig.components.map((c) => c.id));
36
+ const knownGlobalVariants = new Set(
37
+ context.config.globalVariants.variantGroups
38
+ .filter((vg) => vg.projectId === projectId)
39
+ .map((vg) => vg.id)
40
+ );
41
+ const knownThemes = new Set(
42
+ (projectConfig.jsBundleThemes || []).map((theme) => theme.bundleName)
43
+ );
44
+
45
+ const toBeSyncedComponents = new Set(componentIds);
46
+
47
+ const imageChecksums = fileLocks
48
+ .filter(
49
+ (fileLock) =>
50
+ fileLock.type === "image" && knownImages.has(fileLock.assetId)
51
+ )
52
+ .map((fileLock): [string, string] => [fileLock.assetId, fileLock.checksum]);
53
+
54
+ const iconChecksums = fileLocks
55
+ .filter(
56
+ (fileLock) =>
57
+ projectLock.lang === context.config.code.lang &&
58
+ fileLock.type === "icon" &&
59
+ knownIcons.has(fileLock.assetId)
60
+ )
61
+ .map((fileLock): [string, string] => [fileLock.assetId, fileLock.checksum]);
62
+
63
+ const renderModuleChecksums = fileLocks
64
+ .filter(
65
+ (fileLock) =>
66
+ projectLock.lang === context.config.code.lang &&
67
+ fileLock.type === "renderModule" &&
68
+ toBeSyncedComponents.has(fileLock.assetId) &&
69
+ knownComponents.has(fileLock.assetId)
70
+ )
71
+ .map((fileLock): [string, string] => [fileLock.assetId, fileLock.checksum]);
72
+
73
+ const cssRulesChecksums = fileLocks
74
+ .filter(
75
+ (fileLock) =>
76
+ fileLock.type === "cssRules" &&
77
+ toBeSyncedComponents.has(fileLock.assetId) &&
78
+ knownComponents.has(fileLock.assetId)
79
+ )
80
+ .map((fileLock): [string, string] => [fileLock.assetId, fileLock.checksum]);
81
+
82
+ const globalVariantChecksums = fileLocks
83
+ .filter(
84
+ (fileLock) =>
85
+ projectLock.lang === context.config.code.lang &&
86
+ fileLock.type === "globalVariant" &&
87
+ knownGlobalVariants.has(fileLock.assetId)
88
+ )
89
+ .map((fileLock): [string, string] => [fileLock.assetId, fileLock.checksum]);
90
+
91
+ const projectCssChecksums = fileLocks.filter(
92
+ (fileLock) => fileLock.type === "projectCss"
93
+ );
94
+ assert(projectCssChecksums.length < 2);
95
+ const projectCssChecksum =
96
+ projectCssChecksums.length > 0 ? projectCssChecksums[0].checksum : "";
97
+
98
+ return {
99
+ imageChecksums,
100
+ iconChecksums,
101
+ renderModuleChecksums,
102
+ cssRulesChecksums,
103
+ globalVariantChecksums,
104
+ projectCssChecksum,
105
+ };
106
+ }