@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,25 @@
1
+ import { CommonArgs } from "..";
2
+ import { Metadata } from "../utils/get-context";
3
+ export interface SyncArgs extends CommonArgs {
4
+ projects: readonly string[];
5
+ forceOverwrite: boolean;
6
+ newComponentScheme?: "blackbox" | "direct";
7
+ appendJsxOnMissingBase?: boolean;
8
+ yes?: boolean;
9
+ force?: boolean;
10
+ nonRecursive?: boolean;
11
+ skipUpgradeCheck?: boolean;
12
+ ignorePostSync?: boolean;
13
+ quiet?: boolean;
14
+ metadata?: string;
15
+ allFiles?: boolean;
16
+ loaderConfig?: string;
17
+ }
18
+ /**
19
+ * Sync will always try to sync down a set of components that are version-consistent among specified projects.
20
+ * (we only allow 1 version per projectId).
21
+ * NOTE: the repo/plasmic.json might include projects with conflicting versions in its dependency tree.
22
+ * We leave it to the user to sync all projects if they want us to catch/prevent this.
23
+ * @param opts
24
+ */
25
+ export declare function sync(opts: SyncArgs, metadataDefaults?: Metadata): Promise<void>;
@@ -0,0 +1,417 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.sync = void 0;
35
+ const chalk_1 = __importDefault(require("chalk"));
36
+ const child_process_1 = require("child_process");
37
+ const lodash_1 = __importDefault(require("lodash"));
38
+ const upath_1 = __importDefault(require("upath"));
39
+ const deps_1 = require("../deps");
40
+ const checksum_1 = require("../utils/checksum");
41
+ const code_utils_1 = require("../utils/code-utils");
42
+ const config_utils_1 = require("../utils/config-utils");
43
+ const error_1 = require("../utils/error");
44
+ const file_utils_1 = require("../utils/file-utils");
45
+ const get_context_1 = require("../utils/get-context");
46
+ const help_1 = require("../utils/help");
47
+ const lang_utils_1 = require("../utils/lang-utils");
48
+ const npm_utils_1 = require("../utils/npm-utils");
49
+ const resolve_utils_1 = require("../utils/resolve-utils");
50
+ const semver = __importStar(require("../utils/semver"));
51
+ const user_utils_1 = require("../utils/user-utils");
52
+ const sync_components_1 = require("./sync-components");
53
+ const sync_global_variants_1 = require("./sync-global-variants");
54
+ const sync_icons_1 = require("./sync-icons");
55
+ const sync_images_1 = require("./sync-images");
56
+ const sync_styles_1 = require("./sync-styles");
57
+ function ensureRequiredPackages(context, baseDir, yes) {
58
+ return __awaiter(this, void 0, void 0, function* () {
59
+ const requireds = yield context.api.requiredPackages();
60
+ const confirmInstall = (pkg, requiredVersion, opts) => __awaiter(this, void 0, void 0, function* () {
61
+ let success = false;
62
+ const command = npm_utils_1.installCommand(pkg, baseDir, opts);
63
+ const upgrade = yield user_utils_1.confirmWithUser(`A more recent version of ${pkg} >=${requiredVersion} is required. Would you like to upgrade via "${command}"?`, yes);
64
+ if (upgrade) {
65
+ success = npm_utils_1.installUpgrade(pkg, baseDir, opts);
66
+ }
67
+ else {
68
+ success = false;
69
+ }
70
+ if (!success) {
71
+ throw new error_1.HandledError(`Upgrading ${pkg} is required to continue.`);
72
+ }
73
+ });
74
+ const cliVersion = npm_utils_1.getCliVersion();
75
+ if (!cliVersion || semver.gt(requireds["@plasmicapp/cli"], cliVersion)) {
76
+ const isGlobal = npm_utils_1.isCliGloballyInstalled(context.rootDir);
77
+ yield confirmInstall("@plasmicapp/cli", requireds["@plasmicapp/cli"], {
78
+ global: isGlobal,
79
+ dev: true,
80
+ });
81
+ deps_1.logger.info(chalk_1.default.bold("@plasmicapp/cli has been upgraded; please try again!"));
82
+ // Exit so the user can run again with the new cli
83
+ throw new error_1.HandledError();
84
+ }
85
+ const reactWebVersion = npm_utils_1.findInstalledVersion(context, "@plasmicapp/react-web");
86
+ if (!reactWebVersion ||
87
+ semver.gt(requireds["@plasmicapp/react-web"], reactWebVersion)) {
88
+ yield confirmInstall("@plasmicapp/react-web", requireds["@plasmicapp/react-web"], { global: false, dev: false });
89
+ }
90
+ if (context.config.code.reactRuntime === "automatic") {
91
+ // Using automatic runtime requires installing the @plasmicapp/react-web-runtime package
92
+ const runtimeVersion = npm_utils_1.findInstalledVersion(context, "@plasmicapp/react-web-runtime");
93
+ if (!runtimeVersion ||
94
+ semver.gt(requireds["@plasmicapp/react-web-runtime"], runtimeVersion)) {
95
+ yield confirmInstall("@plasmicapp/react-web-runtime", requireds["@plasmicapp/react-web-runtime"], { global: false, dev: false });
96
+ }
97
+ }
98
+ });
99
+ }
100
+ function getLoaderConfigPath(opts) {
101
+ return opts.loaderConfig || config_utils_1.LOADER_CONFIG_FILE_NAME;
102
+ }
103
+ function maybeReadLoaderConfig(opts) {
104
+ const path = getLoaderConfigPath(opts);
105
+ if (!file_utils_1.existsBuffered(path)) {
106
+ return {};
107
+ }
108
+ return JSON.parse(file_utils_1.readFileText(path));
109
+ }
110
+ function writeLoaderConfig(opts, config) {
111
+ const loaderConfigPath = getLoaderConfigPath(opts);
112
+ file_utils_1.writeFileText(loaderConfigPath, code_utils_1.formatAsLocal(JSON.stringify(config), loaderConfigPath, opts.baseDir));
113
+ }
114
+ /**
115
+ * Sync will always try to sync down a set of components that are version-consistent among specified projects.
116
+ * (we only allow 1 version per projectId).
117
+ * NOTE: the repo/plasmic.json might include projects with conflicting versions in its dependency tree.
118
+ * We leave it to the user to sync all projects if they want us to catch/prevent this.
119
+ * @param opts
120
+ */
121
+ function sync(opts, metadataDefaults) {
122
+ var _a;
123
+ return __awaiter(this, void 0, void 0, function* () {
124
+ // Initially allow for a missing auth. Only require an auth once we need to fetch new or updated API tokens for any
125
+ // projects.
126
+ if (!opts.baseDir)
127
+ opts.baseDir = process.cwd();
128
+ const baseDir = opts.baseDir;
129
+ let context = yield get_context_1.getContext(opts, { enableSkipAuth: true });
130
+ const isFirstRun = context.config.projects.length === 0;
131
+ if (!opts.skipUpgradeCheck) {
132
+ yield ensureRequiredPackages(context, opts.baseDir, opts.yes);
133
+ }
134
+ fixFileExtension(context);
135
+ file_utils_1.assertAllPathsInRootDir(context);
136
+ const loaderConfig = process.env.PLASMIC_LOADER
137
+ ? maybeReadLoaderConfig(opts)
138
+ : {};
139
+ const projectIdToToken = new Map([...context.config.projects, ...((_a = loaderConfig === null || loaderConfig === void 0 ? void 0 : loaderConfig.projects) !== null && _a !== void 0 ? _a : [])]
140
+ .filter((p) => p.projectApiToken)
141
+ .map((p) => lang_utils_1.tuple(p.projectId, p.projectApiToken)));
142
+ // Resolve what will be synced
143
+ const projectConfigMap = lodash_1.default.keyBy(context.config.projects, (p) => p.projectId);
144
+ const projectWithVersion = opts.projects.map((p) => {
145
+ var _a;
146
+ const [projectIdToken, versionRange] = p.split("@");
147
+ const [projectId, projectApiToken] = projectIdToken.split(":");
148
+ return {
149
+ projectId,
150
+ versionRange: versionRange || ((_a = projectConfigMap[projectId]) === null || _a === void 0 ? void 0 : _a.version) || "latest",
151
+ componentIdOrNames: undefined,
152
+ projectApiToken: projectApiToken || projectIdToToken.get(projectId),
153
+ };
154
+ });
155
+ const projectSyncParams = projectWithVersion.length
156
+ ? projectWithVersion
157
+ : context.config.projects.map((p) => ({
158
+ projectId: p.projectId,
159
+ versionRange: p.version,
160
+ componentIdOrNames: undefined,
161
+ projectApiToken: p.projectApiToken,
162
+ }));
163
+ // Short-circuit if nothing to sync
164
+ if (projectSyncParams.length === 0) {
165
+ throw new error_1.HandledError("Don't know which projects to sync. Please specify via --projects");
166
+ }
167
+ // If there are any missing projectApiTokens, reload the context, this time requiring auth, so that we can fetch the
168
+ // projectApiTokens from the server (as a user that has permission to do so).
169
+ if (projectSyncParams.some((p) => !p.projectApiToken)) {
170
+ try {
171
+ context = yield get_context_1.getContext(opts);
172
+ }
173
+ catch (e) {
174
+ if (e.message.includes("Unable to authenticate Plasmic")) {
175
+ const configFileName = process.env.PLASMIC_LOADER
176
+ ? config_utils_1.LOADER_CONFIG_FILE_NAME
177
+ : config_utils_1.CONFIG_FILE_NAME;
178
+ throw new error_1.HandledError(`Unable to authenticate Plasmic. Please run 'plasmic auth' or check the projectApiTokens in your ${configFileName}, and try again.`);
179
+ }
180
+ }
181
+ }
182
+ // Pass just the root IDs and tokens that we do have for the resolve call. (In reality it doesn't need any of this
183
+ // because it only consults the projectApiToken within projectSyncParams; we could just attach [].)
184
+ context.api.attachProjectIdsAndTokens(projectSyncParams.flatMap((p) => p.projectApiToken
185
+ ? [{ projectId: p.projectId, projectApiToken: p.projectApiToken }]
186
+ : []));
187
+ const versionResolution = yield context.api.resolveSync(projectSyncParams, true // we always want to get dependency data
188
+ );
189
+ // Make sure the resolution is compatible with plasmic.json and plasmic.lock
190
+ const projectsToSync = yield resolve_utils_1.checkVersionResolution(versionResolution, context, opts);
191
+ if (projectsToSync.length <= 0) {
192
+ deps_1.logger.info("Your projects are up-to-date with respect to your specified version ranges. Nothing to sync.");
193
+ return;
194
+ }
195
+ const summary = new Map();
196
+ const pendingMerge = new Array();
197
+ // The resolveSync call returns the project API tokens for all relevant projects (sources and dependencies).
198
+ // resolveSync is what does this because it's what is computing all concrete versions to sync, and the dependency
199
+ // graph can change with any version. Subsequent API calls require the exact API tokens, not to redo this work on each
200
+ // call. Only resolveSync accepts just the API tokens for the root projects.
201
+ //
202
+ // We shouldn't simply use projectsToSync, because this list excludes up-to-date projects, but syncing a dependent
203
+ // project still requires tokens to the dependencies.
204
+ const projectIdsAndTokens = [
205
+ ...versionResolution.projects,
206
+ ...versionResolution.dependencies,
207
+ ].map((p) => lodash_1.default.pick(p, "projectId", "projectApiToken"));
208
+ context.api.attachProjectIdsAndTokens(projectIdsAndTokens);
209
+ // Perform the actual sync
210
+ yield file_utils_1.withBufferedFs(() => __awaiter(this, void 0, void 0, function* () {
211
+ var _b;
212
+ // Sync in sequence (no parallelism)
213
+ // going in reverse to get leaves of the dependency tree first
214
+ for (const projectMeta of projectsToSync) {
215
+ yield syncProject(context, opts, projectIdsAndTokens, projectMeta.projectId, projectMeta.componentIds, projectMeta.version, projectMeta.dependencies, summary, pendingMerge, metadataDefaults);
216
+ }
217
+ // Materialize scheme into each component config.
218
+ context.config.projects.forEach((p) => p.components.forEach((c) => {
219
+ if (c.type === "managed" && !c.scheme) {
220
+ c.scheme = context.config.code.scheme;
221
+ }
222
+ }));
223
+ yield syncStyleConfig(context, yield context.api.genStyleConfig(context.config.style));
224
+ // Update project version if specified and successfully synced.
225
+ if (projectWithVersion.length) {
226
+ const versionMap = {};
227
+ projectWithVersion.forEach((p) => (versionMap[p.projectId] = p.versionRange));
228
+ context.config.projects.forEach((p) => (p.version = versionMap[p.projectId] || p.version));
229
+ }
230
+ // Fix imports
231
+ const fixImportContext = code_utils_1.mkFixImportContext(context.config);
232
+ for (const m of pendingMerge) {
233
+ const resolvedEditedFile = code_utils_1.replaceImports(context, m.editedSkeletonFile, m.skeletonModulePath, fixImportContext, true, baseDir);
234
+ const resolvedNewFile = code_utils_1.replaceImports(context, m.newSkeletonFile, m.skeletonModulePath, fixImportContext, true, baseDir);
235
+ yield m.merge(resolvedNewFile, resolvedEditedFile);
236
+ }
237
+ // Now we know config.components are all correct, so we can go ahead and fix up all the import statements
238
+ yield code_utils_1.fixAllImportStatements(context, opts.baseDir, summary);
239
+ if (process.env.PLASMIC_LOADER) {
240
+ const rootProjectIds = new Set(projectSyncParams.map((p) => p.projectId));
241
+ const freshIdsAndTokens = projectIdsAndTokens
242
+ .filter((p) => rootProjectIds.has(p.projectId))
243
+ .map((p) => lodash_1.default.pick(p, "projectId", "projectApiToken"));
244
+ const config = Object.assign(Object.assign({}, loaderConfig), { projects: lodash_1.default.sortBy(lodash_1.default.uniqBy([...freshIdsAndTokens, ...((_b = loaderConfig === null || loaderConfig === void 0 ? void 0 : loaderConfig.projects) !== null && _b !== void 0 ? _b : [])], (p) => p.projectId), (p) => p.projectId) });
245
+ writeLoaderConfig(opts, config);
246
+ }
247
+ // Write the new ComponentConfigs to disk
248
+ yield config_utils_1.updateConfig(context, context.config, baseDir);
249
+ }));
250
+ // Post-sync commands
251
+ if (!opts.ignorePostSync) {
252
+ for (const cmd of context.config.postSyncCommands || []) {
253
+ child_process_1.spawnSync(cmd, { shell: true, stdio: "inherit" });
254
+ }
255
+ }
256
+ if (isFirstRun) {
257
+ if (!process.env.QUIET) {
258
+ help_1.printFirstSyncInfo(context);
259
+ }
260
+ }
261
+ });
262
+ }
263
+ exports.sync = sync;
264
+ function maybeRenamePathExt(context, path, ext) {
265
+ if (!path) {
266
+ return path;
267
+ }
268
+ const correctPath = `${file_utils_1.stripExtension(path, true)}${ext}`;
269
+ if (path !== correctPath) {
270
+ file_utils_1.renameFile(context, path, correctPath);
271
+ }
272
+ return correctPath;
273
+ }
274
+ function fixFileExtension(context) {
275
+ const cssExt = context.config.style.scheme === "css-modules" ? ".module.css" : ".css";
276
+ context.config.style.defaultStyleCssFilePath = maybeRenamePathExt(context, context.config.style.defaultStyleCssFilePath, cssExt);
277
+ context.config.projects.forEach((project) => {
278
+ project.cssFilePath = maybeRenamePathExt(context, project.cssFilePath, cssExt);
279
+ project.components.forEach((component) => {
280
+ component.cssFilePath = maybeRenamePathExt(context, component.cssFilePath, cssExt);
281
+ });
282
+ });
283
+ }
284
+ function syncProject(context, opts, projectIdsAndTokens, projectId, componentIds, projectVersion, dependencies, summary, pendingMerge, metadataDefaults) {
285
+ var _a;
286
+ return __awaiter(this, void 0, void 0, function* () {
287
+ const newComponentScheme = opts.newComponentScheme || context.config.code.scheme;
288
+ const existingProject = context.config.projects.find((p) => p.projectId === projectId);
289
+ const existingCompScheme = ((existingProject === null || existingProject === void 0 ? void 0 : existingProject.components) || []).map((c) => [c.id, c.scheme]);
290
+ const projectApiToken = lang_utils_1.ensure((_a = projectIdsAndTokens.find((p) => p.projectId === projectId)) === null || _a === void 0 ? void 0 : _a.projectApiToken, `Could not find the API token for project ${projectId} in list: ${JSON.stringify(projectIdsAndTokens)}`);
291
+ const existingChecksums = checksum_1.getChecksums(context, opts, projectId, componentIds);
292
+ // Server-side code-gen
293
+ const projectBundle = yield context.api.projectComponents(projectId, {
294
+ platform: context.config.platform,
295
+ newCompScheme: newComponentScheme,
296
+ existingCompScheme,
297
+ componentIdOrNames: componentIds,
298
+ version: projectVersion,
299
+ imageOpts: context.config.images,
300
+ stylesOpts: context.config.style,
301
+ checksums: existingChecksums,
302
+ codeOpts: context.config.code,
303
+ metadata: get_context_1.generateMetadata(Object.assign(Object.assign({}, metadataDefaults), { platform: context.config.platform }), opts.metadata),
304
+ });
305
+ // Convert from TSX => JSX
306
+ if (context.config.code.lang === "js") {
307
+ projectBundle.components.forEach((c) => {
308
+ [c.renderModuleFileName, c.renderModule] = code_utils_1.maybeConvertTsxToJsx(c.renderModuleFileName, c.renderModule, opts.baseDir);
309
+ [c.skeletonModuleFileName, c.skeletonModule] = code_utils_1.maybeConvertTsxToJsx(c.skeletonModuleFileName, c.skeletonModule, opts.baseDir);
310
+ });
311
+ projectBundle.iconAssets.forEach((icon) => {
312
+ [icon.fileName, icon.module] = code_utils_1.maybeConvertTsxToJsx(icon.fileName, icon.module, opts.baseDir);
313
+ });
314
+ projectBundle.globalVariants.forEach((gv) => {
315
+ [gv.contextFileName, gv.contextModule] = code_utils_1.maybeConvertTsxToJsx(gv.contextFileName, gv.contextModule, opts.baseDir);
316
+ });
317
+ (projectBundle.projectConfig.jsBundleThemes || []).forEach((theme) => {
318
+ [theme.themeFileName, theme.themeModule] = code_utils_1.maybeConvertTsxToJsx(theme.themeFileName, theme.themeModule, opts.baseDir);
319
+ });
320
+ }
321
+ yield sync_global_variants_1.syncGlobalVariants(context, projectBundle.projectConfig, projectBundle.globalVariants, projectBundle.checksums, opts.baseDir);
322
+ syncCodeComponentsMeta(context, projectId, projectBundle.codeComponentMetas);
323
+ yield syncProjectConfig(context, projectBundle.projectConfig, projectApiToken, projectVersion, dependencies, projectBundle.components, opts.forceOverwrite, !!opts.appendJsxOnMissingBase, summary, pendingMerge, projectBundle.checksums, opts.baseDir);
324
+ yield sync_styles_1.upsertStyleTokens(context, projectBundle.usedTokens);
325
+ yield sync_icons_1.syncProjectIconAssets(context, projectId, projectVersion, projectBundle.iconAssets, projectBundle.checksums, opts.baseDir);
326
+ yield sync_images_1.syncProjectImageAssets(context, projectId, projectVersion, projectBundle.imageAssets, projectBundle.checksums);
327
+ });
328
+ }
329
+ function syncStyleConfig(context, response) {
330
+ return __awaiter(this, void 0, void 0, function* () {
331
+ const expectedPath = context.config.style.defaultStyleCssFilePath ||
332
+ upath_1.default.join(context.config.defaultPlasmicDir, response.defaultStyleCssFileName);
333
+ context.config.style.defaultStyleCssFilePath = expectedPath;
334
+ yield file_utils_1.writeFileContent(context, expectedPath, response.defaultStyleCssRules, {
335
+ force: true,
336
+ });
337
+ });
338
+ }
339
+ function syncProjectConfig(context, projectBundle, projectApiToken, version, dependencies, componentBundles, forceOverwrite, appendJsxOnMissingBase, summary, pendingMerge, checksums, baseDir) {
340
+ return __awaiter(this, void 0, void 0, function* () {
341
+ const defaultCssFilePath = file_utils_1.defaultResourcePath(context, projectBundle.projectName, projectBundle.cssFileName);
342
+ const isNew = !context.config.projects.find((p) => p.projectId === projectBundle.projectId);
343
+ // If latest, use that as the range, otherwise set to latest published (>=0.0.0)
344
+ const versionRange = semver.isLatest(version) ? version : ">=0.0.0";
345
+ const projectConfig = config_utils_1.getOrAddProjectConfig(context, projectBundle.projectId, config_utils_1.createProjectConfig({
346
+ projectId: projectBundle.projectId,
347
+ projectApiToken,
348
+ projectName: projectBundle.projectName,
349
+ version: versionRange,
350
+ cssFilePath: defaultCssFilePath,
351
+ }));
352
+ // Update missing/outdated props
353
+ projectConfig.projectName = projectBundle.projectName;
354
+ if (!projectConfig.cssFilePath) {
355
+ projectConfig.cssFilePath = defaultCssFilePath;
356
+ }
357
+ projectConfig.projectApiToken = projectApiToken;
358
+ // plasmic.lock
359
+ const projectLock = config_utils_1.getOrAddProjectLock(context, projectConfig.projectId);
360
+ projectLock.version = version;
361
+ projectLock.dependencies = dependencies;
362
+ projectLock.lang = context.config.code.lang;
363
+ if (projectBundle.cssRules) {
364
+ const formattedCssRules = code_utils_1.formatAsLocal(projectBundle.cssRules, projectConfig.cssFilePath, baseDir);
365
+ // Write out project css
366
+ yield file_utils_1.writeFileContent(context, projectConfig.cssFilePath, formattedCssRules, {
367
+ force: !isNew,
368
+ });
369
+ }
370
+ projectLock.fileLocks = projectLock.fileLocks.filter((fileLock) => fileLock.type !== "projectCss");
371
+ projectLock.fileLocks.push({
372
+ assetId: projectConfig.projectId,
373
+ type: "projectCss",
374
+ checksum: checksums.projectCssChecksum,
375
+ });
376
+ /*
377
+ for (const theme of projectBundle.jsBundleThemes) {
378
+ if (!projectConfig.jsBundleThemes) {
379
+ projectConfig.jsBundleThemes = [];
380
+ }
381
+ let themeConfig = projectConfig.jsBundleThemes.find(
382
+ (c) => c.bundleName === theme.bundleName
383
+ );
384
+ if (!themeConfig) {
385
+ const themeFilePath = defaultResourcePath(
386
+ context,
387
+ projectConfig,
388
+ theme.themeFileName
389
+ );
390
+ themeConfig = { themeFilePath, bundleName: theme.bundleName };
391
+ projectConfig.jsBundleThemes.push(themeConfig);
392
+ }
393
+ const formatted = formatAsLocal(
394
+ theme.themeModule,
395
+ themeConfig.themeFilePath
396
+ );
397
+ await writeFileContent(context, themeConfig.themeFilePath, formatted, {
398
+ force: true,
399
+ });
400
+ }
401
+ */
402
+ if (projectConfig.jsBundleThemes &&
403
+ projectConfig.jsBundleThemes.length === 0) {
404
+ delete projectConfig.jsBundleThemes;
405
+ }
406
+ // Write out components
407
+ yield sync_components_1.syncProjectComponents(context, projectConfig, version, componentBundles, forceOverwrite, appendJsxOnMissingBase, summary, pendingMerge, projectLock, checksums, baseDir);
408
+ });
409
+ }
410
+ function syncCodeComponentsMeta(context, projectId, codeComponentBundles) {
411
+ const projectConfig = config_utils_1.getOrAddProjectConfig(context, projectId);
412
+ projectConfig.codeComponents = codeComponentBundles.map((meta) => ({
413
+ id: meta.id,
414
+ name: meta.name,
415
+ componentImportPath: meta.importPath,
416
+ }));
417
+ }
@@ -0,0 +1,15 @@
1
+ import { CommonArgs } from "..";
2
+ export interface UploadBundleArgs extends CommonArgs {
3
+ project: string;
4
+ bundleName: string;
5
+ bundleJsFile: string;
6
+ cssFiles: readonly string[];
7
+ metaJsonFile: string;
8
+ genModulePath?: string;
9
+ genCssPaths: string[];
10
+ pkgVersion?: string;
11
+ extraPropMetaJsonFile?: string;
12
+ themeProviderWrapper?: string;
13
+ themeModuleFile?: string;
14
+ }
15
+ export declare function uploadJsBundle(opts: UploadBundleArgs): Promise<void>;
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.uploadJsBundle = void 0;
16
+ const pako_1 = __importDefault(require("pako"));
17
+ const file_utils_1 = require("../utils/file-utils");
18
+ const get_context_1 = require("../utils/get-context");
19
+ function uploadJsBundle(opts) {
20
+ return __awaiter(this, void 0, void 0, function* () {
21
+ const context = yield get_context_1.getContext(opts);
22
+ const api = context.api;
23
+ yield api.uploadBundle(opts.project, opts.bundleName, pako_1.default.deflate(file_utils_1.readFileText(opts.bundleJsFile), { to: "string" }), opts.cssFiles.map((f) => pako_1.default.deflate(file_utils_1.readFileText(f), { to: "string" })), pako_1.default.deflate(file_utils_1.readFileText(opts.metaJsonFile), { to: "string" }), opts.genModulePath, opts.genCssPaths, opts.pkgVersion, opts.extraPropMetaJsonFile
24
+ ? file_utils_1.readFileText(opts.extraPropMetaJsonFile)
25
+ : undefined, opts.themeProviderWrapper, opts.themeModuleFile ? file_utils_1.readFileText(opts.themeModuleFile) : undefined);
26
+ });
27
+ }
28
+ exports.uploadJsBundle = uploadJsBundle;
@@ -0,0 +1,14 @@
1
+ import { CommonArgs } from "..";
2
+ import { Metadata } from "../utils/get-context";
3
+ export interface WatchArgs extends CommonArgs {
4
+ projects: readonly string[];
5
+ forceOverwrite: boolean;
6
+ newComponentScheme?: "blackbox" | "direct";
7
+ appendJsxOnMissingBase?: boolean;
8
+ yes?: boolean;
9
+ force?: boolean;
10
+ nonRecursive?: boolean;
11
+ skipUpgradeCheck?: boolean;
12
+ metadata?: string;
13
+ }
14
+ export declare function watchProjects(opts: WatchArgs, metadataDefaults?: Metadata, onProjectUpdate?: () => void): Promise<void>;
@@ -0,0 +1,90 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
5
+ }) : (function(o, m, k, k2) {
6
+ if (k2 === undefined) k2 = k;
7
+ o[k2] = m[k];
8
+ }));
9
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
10
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
11
+ }) : function(o, v) {
12
+ o["default"] = v;
13
+ });
14
+ var __importStar = (this && this.__importStar) || function (mod) {
15
+ if (mod && mod.__esModule) return mod;
16
+ var result = {};
17
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
18
+ __setModuleDefault(result, mod);
19
+ return result;
20
+ };
21
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
22
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
23
+ return new (P || (P = Promise))(function (resolve, reject) {
24
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
25
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
26
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
27
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
28
+ });
29
+ };
30
+ var __importDefault = (this && this.__importDefault) || function (mod) {
31
+ return (mod && mod.__esModule) ? mod : { "default": mod };
32
+ };
33
+ Object.defineProperty(exports, "__esModule", { value: true });
34
+ exports.watchProjects = void 0;
35
+ const lodash_1 = __importDefault(require("lodash"));
36
+ const moment_1 = __importDefault(require("moment"));
37
+ const deps_1 = require("../deps");
38
+ const error_1 = require("../utils/error");
39
+ const get_context_1 = require("../utils/get-context");
40
+ const semver = __importStar(require("../utils/semver"));
41
+ const sync_1 = require("./sync");
42
+ function watchProjects(opts, metadataDefaults, onProjectUpdate) {
43
+ return __awaiter(this, void 0, void 0, function* () {
44
+ // Perform a sync before watch.
45
+ const syncOpts = Object.assign(Object.assign({}, opts), { quiet: true });
46
+ const syncMetadata = Object.assign(Object.assign({}, metadataDefaults), { command: "watch" });
47
+ yield sync_1.sync(syncOpts, syncMetadata);
48
+ const context = yield get_context_1.getContext(opts);
49
+ const config = context.config;
50
+ const socket = context.api.connectSocket();
51
+ const projectIds = lodash_1.default.uniq(opts.projects.length > 0
52
+ ? opts.projects
53
+ : config.projects.map((c) => c.projectId));
54
+ // Filter out projects that are not latest
55
+ const latestProjects = projectIds.filter((projectId) => {
56
+ const projectConfig = config.projects.find((p) => p.projectId === projectId);
57
+ return !projectConfig || semver.isLatest(projectConfig.version);
58
+ });
59
+ if (projectIds.length !== latestProjects.length) {
60
+ const filteredProjects = lodash_1.default.difference(projectIds, latestProjects);
61
+ deps_1.logger.warn(`Warning: watch only works for projects with version="latest". Ignoring ${filteredProjects}`);
62
+ }
63
+ if (latestProjects.length === 0) {
64
+ throw new error_1.HandledError("Don't know which projects to sync; please specify via --projects");
65
+ }
66
+ const promise = new Promise((resolve, reject) => {
67
+ socket.on("initServerInfo", () => {
68
+ // upon connection, subscribe to changes for argument projects
69
+ socket.emit("subscribe", {
70
+ namespace: "projects",
71
+ projectIds: latestProjects,
72
+ });
73
+ });
74
+ socket.on("error", (data) => {
75
+ reject(new error_1.HandledError(data));
76
+ });
77
+ socket.on("update", (data) => __awaiter(this, void 0, void 0, function* () {
78
+ // Just run syncProjects() for now when any project has been updated
79
+ // Note on the 'updated to revision' part: this is parsed by the
80
+ // loader package to know that we finished updating the components.
81
+ yield sync_1.sync(syncOpts, syncMetadata);
82
+ deps_1.logger.info(`[${moment_1.default().format("HH:mm:ss")}] Project ${data.projectId} updated to revision ${data.revisionNum}`);
83
+ onProjectUpdate === null || onProjectUpdate === void 0 ? void 0 : onProjectUpdate();
84
+ }));
85
+ });
86
+ deps_1.logger.info(`Watching projects ${latestProjects} ...`);
87
+ return promise;
88
+ });
89
+ }
90
+ exports.watchProjects = watchProjects;