@plasmicapp/cli 0.1.165 → 0.1.166

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.
@@ -50,7 +50,7 @@ function mockProjectToProjectVersionMeta(mock, componentIdOrNames) {
50
50
  .filter((c) => !componentIdOrNames ||
51
51
  componentIdOrNames.includes(c.name) ||
52
52
  componentIdOrNames.includes(c.id))
53
- .map((c) => c.id) });
53
+ .map((c) => c.id), indirect: false });
54
54
  }
55
55
  /**
56
56
  * Call this in test to setup the data model
@@ -150,6 +150,7 @@ function sync(opts, metadataDefaults) {
150
150
  versionRange: versionRange || ((_a = projectConfigMap[projectId]) === null || _a === void 0 ? void 0 : _a.version) || "latest",
151
151
  componentIdOrNames: undefined,
152
152
  projectApiToken: projectApiToken || projectIdToToken.get(projectId),
153
+ indirect: false,
153
154
  };
154
155
  });
155
156
  const projectSyncParams = projectWithVersion.length
@@ -159,6 +160,7 @@ function sync(opts, metadataDefaults) {
159
160
  versionRange: p.version,
160
161
  componentIdOrNames: undefined,
161
162
  projectApiToken: p.projectApiToken,
163
+ indirect: !!p.indirect,
162
164
  }));
163
165
  // Short-circuit if nothing to sync
164
166
  if (projectSyncParams.length === 0) {
@@ -212,7 +214,7 @@ function sync(opts, metadataDefaults) {
212
214
  // Sync in sequence (no parallelism)
213
215
  // going in reverse to get leaves of the dependency tree first
214
216
  for (const projectMeta of projectsToSync) {
215
- yield syncProject(context, opts, projectIdsAndTokens, projectMeta.projectId, projectMeta.componentIds, projectMeta.version, projectMeta.dependencies, summary, pendingMerge, metadataDefaults);
217
+ yield syncProject(context, opts, projectIdsAndTokens, projectMeta.projectId, projectMeta.componentIds, projectMeta.version, projectMeta.dependencies, summary, pendingMerge, projectMeta.indirect, metadataDefaults);
216
218
  }
217
219
  // Materialize scheme into each component config.
218
220
  context.config.projects.forEach((p) => p.components.forEach((c) => {
@@ -221,11 +223,20 @@ function sync(opts, metadataDefaults) {
221
223
  }
222
224
  }));
223
225
  yield syncStyleConfig(context, yield context.api.genStyleConfig(context.config.style));
224
- // Update project version if specified and successfully synced.
226
+ // Update project version and indirect status if specified and
227
+ // successfully synced.
225
228
  if (projectWithVersion.length) {
226
229
  const versionMap = {};
227
230
  projectWithVersion.forEach((p) => (versionMap[p.projectId] = p.versionRange));
228
- context.config.projects.forEach((p) => (p.version = versionMap[p.projectId] || p.version));
231
+ const indirectMap = {};
232
+ projectsToSync.forEach((p) => (indirectMap[p.projectId] = p.indirect));
233
+ context.config.projects.forEach((p) => {
234
+ p.version = versionMap[p.projectId] || p.version;
235
+ // Only update `indirect` if it is set in current config.
236
+ if (p.projectId in indirectMap && p.indirect) {
237
+ p.indirect = indirectMap[p.projectId];
238
+ }
239
+ });
229
240
  }
230
241
  // Fix imports
231
242
  const fixImportContext = code_utils_1.mkFixImportContext(context.config);
@@ -281,7 +292,7 @@ function fixFileExtension(context) {
281
292
  });
282
293
  });
283
294
  }
284
- function syncProject(context, opts, projectIdsAndTokens, projectId, componentIds, projectVersion, dependencies, summary, pendingMerge, metadataDefaults) {
295
+ function syncProject(context, opts, projectIdsAndTokens, projectId, componentIds, projectVersion, dependencies, summary, pendingMerge, indirect, metadataDefaults) {
285
296
  var _a;
286
297
  return __awaiter(this, void 0, void 0, function* () {
287
298
  const newComponentScheme = opts.newComponentScheme || context.config.code.scheme;
@@ -301,6 +312,7 @@ function syncProject(context, opts, projectIdsAndTokens, projectId, componentIds
301
312
  checksums: existingChecksums,
302
313
  codeOpts: context.config.code,
303
314
  metadata: get_context_1.generateMetadata(Object.assign(Object.assign({}, metadataDefaults), { platform: context.config.platform }), opts.metadata),
315
+ indirect,
304
316
  });
305
317
  // Convert from TSX => JSX
306
318
  if (context.config.code.lang === "js") {
@@ -319,7 +331,7 @@ function syncProject(context, opts, projectIdsAndTokens, projectId, componentIds
319
331
  });
320
332
  }
321
333
  yield sync_global_variants_1.syncGlobalVariants(context, projectBundle.projectConfig, projectBundle.globalVariants, projectBundle.checksums, opts.baseDir);
322
- yield syncProjectConfig(context, projectBundle.projectConfig, projectApiToken, projectVersion, dependencies, projectBundle.components, opts.forceOverwrite, !!opts.appendJsxOnMissingBase, summary, pendingMerge, projectBundle.checksums, opts.baseDir);
334
+ yield syncProjectConfig(context, projectBundle.projectConfig, projectApiToken, projectVersion, dependencies, projectBundle.components, opts.forceOverwrite, !!opts.appendJsxOnMissingBase, summary, pendingMerge, projectBundle.checksums, opts.baseDir, indirect);
323
335
  syncCodeComponentsMeta(context, projectId, projectBundle.codeComponentMetas);
324
336
  yield sync_styles_1.upsertStyleTokens(context, projectBundle.usedTokens);
325
337
  yield sync_icons_1.syncProjectIconAssets(context, projectId, projectVersion, projectBundle.iconAssets, projectBundle.checksums, opts.baseDir);
@@ -336,7 +348,7 @@ function syncStyleConfig(context, response) {
336
348
  });
337
349
  });
338
350
  }
339
- function syncProjectConfig(context, projectBundle, projectApiToken, version, dependencies, componentBundles, forceOverwrite, appendJsxOnMissingBase, summary, pendingMerge, checksums, baseDir) {
351
+ function syncProjectConfig(context, projectBundle, projectApiToken, version, dependencies, componentBundles, forceOverwrite, appendJsxOnMissingBase, summary, pendingMerge, checksums, baseDir, indirect) {
340
352
  return __awaiter(this, void 0, void 0, function* () {
341
353
  const defaultCssFilePath = file_utils_1.defaultResourcePath(context, projectBundle.projectName, projectBundle.cssFileName);
342
354
  const isNew = !context.config.projects.find((p) => p.projectId === projectBundle.projectId);
@@ -346,6 +358,7 @@ function syncProjectConfig(context, projectBundle, projectApiToken, version, dep
346
358
  projectName: projectBundle.projectName,
347
359
  version,
348
360
  cssFilePath: defaultCssFilePath,
361
+ indirect,
349
362
  }));
350
363
  // Update missing/outdated props
351
364
  projectConfig.projectName = projectBundle.projectName;
package/dist/api.d.ts CHANGED
@@ -58,6 +58,7 @@ export interface ProjectVersionMeta {
58
58
  dependencies: {
59
59
  [projectId: string]: string;
60
60
  };
61
+ indirect: boolean;
61
62
  }
62
63
  export interface VersionResolution {
63
64
  projects: ProjectVersionMeta[];
@@ -165,6 +166,7 @@ export declare class PlasmicApi {
165
166
  stylesOpts: StyleConfig;
166
167
  codeOpts: CodeConfig;
167
168
  checksums: ChecksumBundle;
169
+ indirect: boolean;
168
170
  metadata?: Metadata;
169
171
  }): Promise<ProjectBundle>;
170
172
  uploadBundle(projectId: string, bundleName: string, bundleJs: string, css: string[], metaJson: string, genModulePath: string | undefined, genCssPaths: string[], pkgVersion: string | undefined, extraPropMetaJson: string | undefined, themeProviderWrapper: string | undefined, themeModule: string | undefined): Promise<StyleTokensMap>;
@@ -0,0 +1,2 @@
1
+ import { PlasmicConfig } from "../utils/config-utils";
2
+ export declare function ensureIndirect(config: PlasmicConfig): PlasmicConfig;
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ensureIndirect = void 0;
4
+ function ensureIndirect(config) {
5
+ for (const p of config.projects) {
6
+ if (p.indirect === undefined) {
7
+ p.indirect = false;
8
+ }
9
+ }
10
+ return config;
11
+ }
12
+ exports.ensureIndirect = ensureIndirect;
@@ -40,6 +40,7 @@ const npm_utils_1 = require("../utils/npm-utils");
40
40
  const user_utils_1 = require("../utils/user-utils");
41
41
  const _0_1_110_fileLocks_1 = require("./0.1.110-fileLocks");
42
42
  const _0_1_146_addReactRuntime_1 = require("./0.1.146-addReactRuntime");
43
+ const _0_1_166_indirect_1 = require("./0.1.166-indirect");
43
44
  const _0_1_27_migrateInit_1 = require("./0.1.27-migrateInit");
44
45
  const _0_1_28_tsToTsx_1 = require("./0.1.28-tsToTsx");
45
46
  const _0_1_31_ensureProjectIcons_1 = require("./0.1.31-ensureProjectIcons");
@@ -56,6 +57,7 @@ exports.MIGRATIONS = {
56
57
  "0.1.64": _0_1_64_imageFiles_1.ensureImageFiles,
57
58
  "0.1.95": _0_1_95_componentType_1.ensureComponentType,
58
59
  "0.1.146": _0_1_146_addReactRuntime_1.ensureReactRuntime,
60
+ "0.1.166": _0_1_166_indirect_1.ensureIndirect,
59
61
  };
60
62
  exports.LOCK_MIGRATIONS = {
61
63
  "0.1.110": _0_1_110_fileLocks_1.ensureFileLocks,
@@ -296,6 +296,10 @@
296
296
  },
297
297
  "type": "array"
298
298
  },
299
+ "indirect": {
300
+ "description": "True if the project was installed indirectly (as a dependency); if set,\ncodegen will not generate pages.",
301
+ "type": "boolean"
302
+ },
299
303
  "jsBundleThemes": {
300
304
  "items": {
301
305
  "$ref": "#/definitions/JsBundleThemeConfig"
@@ -324,6 +328,7 @@
324
328
  "cssFilePath",
325
329
  "icons",
326
330
  "images",
331
+ "indirect",
327
332
  "projectId",
328
333
  "projectName",
329
334
  "version"
@@ -138,6 +138,7 @@ exports.project1Config = {
138
138
  icons: [],
139
139
  images: [],
140
140
  jsBundleThemes: [],
141
+ indirect: false,
141
142
  };
142
143
  function expectProject1PlasmicJson() {
143
144
  const plasmicJson = exports.tmpRepo.readPlasmicJson();
@@ -126,6 +126,11 @@ export interface ProjectConfig {
126
126
  icons: IconConfig[];
127
127
  /** Metadata for each synced image in this project */
128
128
  images: ImageConfig[];
129
+ /**
130
+ * True if the project was installed indirectly (as a dependency); if set,
131
+ * codegen will not generate pages.
132
+ */
133
+ indirect: boolean;
129
134
  }
130
135
  export declare function createProjectConfig(base: {
131
136
  projectId: string;
@@ -133,6 +138,7 @@ export declare function createProjectConfig(base: {
133
138
  projectName: string;
134
139
  version: string;
135
140
  cssFilePath: string;
141
+ indirect: boolean;
136
142
  }): ProjectConfig;
137
143
  export interface TokensConfig {
138
144
  scheme: "theo";
@@ -39,6 +39,7 @@ function createProjectConfig(base) {
39
39
  components: [],
40
40
  icons: [],
41
41
  images: [],
42
+ indirect: base.indirect,
42
43
  };
43
44
  }
44
45
  exports.createProjectConfig = createProjectConfig;
@@ -148,6 +149,7 @@ function getOrAddProjectConfig(context, projectId, base // if one doesn't exist,
148
149
  icons: [],
149
150
  images: [],
150
151
  jsBundleThemes: [],
152
+ indirect: false,
151
153
  };
152
154
  context.config.projects.push(project);
153
155
  }
@@ -47,6 +47,7 @@ const user_utils_1 = require("./user-utils");
47
47
  * @param versionResolution
48
48
  */
49
49
  function walkDependencyTree(root, available) {
50
+ root.indirect = false;
50
51
  const queue = [root];
51
52
  const result = [];
52
53
  const getMeta = (projectId, version) => {
@@ -54,7 +55,7 @@ function walkDependencyTree(root, available) {
54
55
  if (!meta) {
55
56
  throw new Error(`Cannot find projectId=${projectId}, version=${version} in the sync resolution results.`);
56
57
  }
57
- return meta;
58
+ return Object.assign(Object.assign({}, meta), { indirect: meta.projectId !== root.projectId });
58
59
  };
59
60
  while (queue.length > 0) {
60
61
  const curr = lang_utils_1.ensure(queue.shift());
@@ -73,6 +74,7 @@ function checkProjectMeta(meta, root, context, opts) {
73
74
  const projectId = meta.projectId;
74
75
  const projectName = meta.projectName;
75
76
  const newVersion = meta.version;
77
+ const indirect = meta.indirect;
76
78
  // Checks newVersion against plasmic.lock
77
79
  const checkVersionLock = () => __awaiter(this, void 0, void 0, function* () {
78
80
  const projectLock = context.lock.projects.find((p) => p.projectId === projectId);
@@ -145,6 +147,15 @@ function checkProjectMeta(meta, root, context, opts) {
145
147
  deps_1.logger.warn(`${projectName}@${newVersion} falls outside the range specified in ${config_utils_1.CONFIG_FILE_NAME} (${versionRange})\nTip: To avoid this warning in the future, update your ${config_utils_1.CONFIG_FILE_NAME}.`);
146
148
  return yield user_utils_1.confirmWithUser("Do you want to force it?", opts.force || opts.yes, "n");
147
149
  });
150
+ const checkIndirect = () => __awaiter(this, void 0, void 0, function* () {
151
+ const projectConfig = context.config.projects.find((p) => p.projectId === projectId);
152
+ const configIndirect = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.indirect;
153
+ if (configIndirect && !indirect) {
154
+ deps_1.logger.warn(`'${projectName}' was synced indirectly before, but a direct sync was requested. If it has page components, they will be synced and saved to plasmic.json.`);
155
+ return yield user_utils_1.confirmWithUser("Do you want to confirm it?", opts.force || opts.yes, "n");
156
+ }
157
+ return true;
158
+ });
148
159
  const projectIds = opts.projects.length > 0
149
160
  ? opts.projects
150
161
  : context.config.projects.map((p) => p.projectId);
@@ -153,7 +164,9 @@ function checkProjectMeta(meta, root, context, opts) {
153
164
  // we should always sync it, even if nothing has changed
154
165
  return true;
155
166
  }
156
- return (yield checkVersionLock()) && (yield checkVersionRange());
167
+ return ((yield checkVersionLock()) &&
168
+ (yield checkVersionRange()) &&
169
+ (yield checkIndirect()));
157
170
  });
158
171
  }
159
172
  /**
@@ -175,13 +188,18 @@ function checkVersionResolution(versionResolution, context, opts) {
175
188
  ? [root]
176
189
  : walkDependencyTree(root, versionResolution.dependencies).reverse();
177
190
  for (const m of queue) {
178
- // If we haven't seen this yet
179
191
  if (!seen.find((p) => p.projectId === m.projectId)) {
180
192
  if (yield checkProjectMeta(m, root, context, opts)) {
181
193
  result.push(m);
182
194
  }
183
195
  seen.push(m);
184
196
  }
197
+ else if (root.projectId === m.projectId) {
198
+ // If m is the root project and it was already seen (maybe as a dep
199
+ // for another project), set indirect = false.
200
+ const project = lang_utils_1.ensure(seen.find((p) => p.projectId === m.projectId));
201
+ project.indirect = false;
202
+ }
185
203
  }
186
204
  }
187
205
  // Ignore repeats
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasmicapp/cli",
3
- "version": "0.1.165",
3
+ "version": "0.1.166",
4
4
  "description": "plasmic cli for syncing local code with Plasmic designs",
5
5
  "engines": {
6
6
  "node": ">=12"
@@ -61,6 +61,7 @@ function mockProjectToProjectVersionMeta(
61
61
  componentIdOrNames.includes(c.id)
62
62
  )
63
63
  .map((c) => c.id),
64
+ indirect: false,
64
65
  };
65
66
  }
66
67
 
@@ -234,6 +234,7 @@ export async function sync(
234
234
  versionRange || projectConfigMap[projectId]?.version || "latest",
235
235
  componentIdOrNames: undefined, // Get all components!
236
236
  projectApiToken: projectApiToken || projectIdToToken.get(projectId),
237
+ indirect: false,
237
238
  };
238
239
  });
239
240
 
@@ -244,6 +245,7 @@ export async function sync(
244
245
  versionRange: p.version,
245
246
  componentIdOrNames: undefined, // Get all components!
246
247
  projectApiToken: p.projectApiToken,
248
+ indirect: !!p.indirect,
247
249
  }));
248
250
 
249
251
  // Short-circuit if nothing to sync
@@ -259,7 +261,7 @@ export async function sync(
259
261
  try {
260
262
  context = await getContext(opts);
261
263
  } catch (e) {
262
- if (e.message.includes("Unable to authenticate Plasmic")) {
264
+ if ((e as any).message.includes("Unable to authenticate Plasmic")) {
263
265
  const configFileName = process.env.PLASMIC_LOADER
264
266
  ? LOADER_CONFIG_FILE_NAME
265
267
  : CONFIG_FILE_NAME;
@@ -329,6 +331,7 @@ export async function sync(
329
331
  projectMeta.dependencies,
330
332
  summary,
331
333
  pendingMerge,
334
+ projectMeta.indirect,
332
335
  metadataDefaults
333
336
  );
334
337
  }
@@ -347,15 +350,22 @@ export async function sync(
347
350
  await context.api.genStyleConfig(context.config.style)
348
351
  );
349
352
 
350
- // Update project version if specified and successfully synced.
353
+ // Update project version and indirect status if specified and
354
+ // successfully synced.
351
355
  if (projectWithVersion.length) {
352
356
  const versionMap: Record<string, string> = {};
353
357
  projectWithVersion.forEach(
354
358
  (p) => (versionMap[p.projectId] = p.versionRange)
355
359
  );
356
- context.config.projects.forEach(
357
- (p) => (p.version = versionMap[p.projectId] || p.version)
358
- );
360
+ const indirectMap: Record<string, boolean> = {};
361
+ projectsToSync.forEach((p) => (indirectMap[p.projectId] = p.indirect));
362
+ context.config.projects.forEach((p) => {
363
+ p.version = versionMap[p.projectId] || p.version;
364
+ // Only update `indirect` if it is set in current config.
365
+ if (p.projectId in indirectMap && p.indirect) {
366
+ p.indirect = indirectMap[p.projectId];
367
+ }
368
+ });
359
369
  }
360
370
 
361
371
  // Fix imports
@@ -469,6 +479,7 @@ async function syncProject(
469
479
  dependencies: { [projectId: string]: string },
470
480
  summary: Map<string, ComponentUpdateSummary>,
471
481
  pendingMerge: ComponentPendingMerge[],
482
+ indirect: boolean,
472
483
  metadataDefaults?: Metadata
473
484
  ): Promise<void> {
474
485
  const newComponentScheme =
@@ -512,6 +523,7 @@ async function syncProject(
512
523
  },
513
524
  opts.metadata
514
525
  ),
526
+ indirect,
515
527
  });
516
528
 
517
529
  // Convert from TSX => JSX
@@ -570,7 +582,8 @@ async function syncProject(
570
582
  summary,
571
583
  pendingMerge,
572
584
  projectBundle.checksums,
573
- opts.baseDir
585
+ opts.baseDir,
586
+ indirect
574
587
  );
575
588
  syncCodeComponentsMeta(context, projectId, projectBundle.codeComponentMetas);
576
589
  await upsertStyleTokens(context, projectBundle.usedTokens);
@@ -619,7 +632,8 @@ async function syncProjectConfig(
619
632
  summary: Map<string, ComponentUpdateSummary>,
620
633
  pendingMerge: ComponentPendingMerge[],
621
634
  checksums: ChecksumBundle,
622
- baseDir: string
635
+ baseDir: string,
636
+ indirect: boolean
623
637
  ) {
624
638
  const defaultCssFilePath = defaultResourcePath(
625
639
  context,
@@ -639,6 +653,7 @@ async function syncProjectConfig(
639
653
  projectName: projectBundle.projectName,
640
654
  version,
641
655
  cssFilePath: defaultCssFilePath,
656
+ indirect,
642
657
  })
643
658
  );
644
659
 
package/src/api.ts CHANGED
@@ -76,6 +76,7 @@ export interface ProjectVersionMeta {
76
76
  dependencies: {
77
77
  [projectId: string]: string;
78
78
  };
79
+ indirect: boolean;
79
80
  }
80
81
 
81
82
  export interface VersionResolution {
@@ -235,6 +236,7 @@ export class PlasmicApi {
235
236
  stylesOpts: StyleConfig;
236
237
  codeOpts: CodeConfig;
237
238
  checksums: ChecksumBundle;
239
+ indirect: boolean;
238
240
  metadata?: Metadata;
239
241
  }
240
242
  ): Promise<ProjectBundle> {
@@ -0,0 +1,10 @@
1
+ import { PlasmicConfig } from "../utils/config-utils";
2
+
3
+ export function ensureIndirect(config: PlasmicConfig) {
4
+ for (const p of config.projects) {
5
+ if (p.indirect === undefined) {
6
+ p.indirect = false;
7
+ }
8
+ }
9
+ return config;
10
+ }
@@ -35,6 +35,7 @@ import {
35
35
  import { confirmWithUser } from "../utils/user-utils";
36
36
  import { ensureFileLocks } from "./0.1.110-fileLocks";
37
37
  import { ensureReactRuntime } from "./0.1.146-addReactRuntime";
38
+ import { ensureIndirect } from "./0.1.166-indirect";
38
39
  import { migrateInit } from "./0.1.27-migrateInit";
39
40
  import { tsToTsx } from "./0.1.28-tsToTsx";
40
41
  import { ensureProjectIcons } from "./0.1.31-ensureProjectIcons";
@@ -64,6 +65,7 @@ export const MIGRATIONS: Record<string, MigrateConfigFunc> = {
64
65
  "0.1.64": ensureImageFiles,
65
66
  "0.1.95": ensureComponentType,
66
67
  "0.1.146": ensureReactRuntime,
68
+ "0.1.166": ensureIndirect,
67
69
  };
68
70
 
69
71
  export const LOCK_MIGRATIONS: Record<string, MigrateLockFunc> = {
@@ -147,6 +147,7 @@ export const project1Config: ProjectConfig = {
147
147
  icons: [],
148
148
  images: [],
149
149
  jsBundleThemes: [],
150
+ indirect: false,
150
151
  };
151
152
 
152
153
  export function expectProject1PlasmicJson() {
@@ -171,6 +171,12 @@ export interface ProjectConfig {
171
171
  icons: IconConfig[];
172
172
  /** Metadata for each synced image in this project */
173
173
  images: ImageConfig[];
174
+
175
+ /**
176
+ * True if the project was installed indirectly (as a dependency); if set,
177
+ * codegen will not generate pages.
178
+ */
179
+ indirect: boolean;
174
180
  }
175
181
 
176
182
  export function createProjectConfig(base: {
@@ -179,6 +185,7 @@ export function createProjectConfig(base: {
179
185
  projectName: string;
180
186
  version: string;
181
187
  cssFilePath: string;
188
+ indirect: boolean;
182
189
  }): ProjectConfig {
183
190
  return {
184
191
  projectId: base.projectId,
@@ -189,6 +196,7 @@ export function createProjectConfig(base: {
189
196
  components: [],
190
197
  icons: [],
191
198
  images: [],
199
+ indirect: base.indirect,
192
200
  };
193
201
  }
194
202
 
@@ -519,6 +527,7 @@ export function getOrAddProjectConfig(
519
527
  icons: [],
520
528
  images: [],
521
529
  jsBundleThemes: [],
530
+ indirect: false,
522
531
  };
523
532
  context.config.projects.push(project);
524
533
  }
@@ -1,4 +1,4 @@
1
- import { exec, execSync, spawnSync } from "child_process";
1
+ import { execSync, spawnSync } from "child_process";
2
2
  import glob from "fast-glob";
3
3
  import findupSync from "findup-sync";
4
4
  import latest from "latest-version";
@@ -1,4 +1,5 @@
1
1
  import L from "lodash";
2
+ import { InvalidatedProjectKind } from "typescript";
2
3
  import { SyncArgs } from "../actions/sync";
3
4
  import { ProjectVersionMeta, VersionResolution } from "../api";
4
5
  import { logger } from "../deps";
@@ -19,6 +20,7 @@ function walkDependencyTree(
19
20
  root: ProjectVersionMeta,
20
21
  available: ProjectVersionMeta[]
21
22
  ): ProjectVersionMeta[] {
23
+ root.indirect = false;
22
24
  const queue: ProjectVersionMeta[] = [root];
23
25
  const result: ProjectVersionMeta[] = [];
24
26
 
@@ -31,7 +33,10 @@ function walkDependencyTree(
31
33
  `Cannot find projectId=${projectId}, version=${version} in the sync resolution results.`
32
34
  );
33
35
  }
34
- return meta;
36
+ return {
37
+ ...meta,
38
+ indirect: meta.projectId !== root.projectId,
39
+ };
35
40
  };
36
41
 
37
42
  while (queue.length > 0) {
@@ -61,6 +66,7 @@ async function checkProjectMeta(
61
66
  const projectId = meta.projectId;
62
67
  const projectName = meta.projectName;
63
68
  const newVersion = meta.version;
69
+ const indirect = meta.indirect;
64
70
 
65
71
  // Checks newVersion against plasmic.lock
66
72
  const checkVersionLock = async (): Promise<boolean> => {
@@ -177,6 +183,24 @@ async function checkProjectMeta(
177
183
  );
178
184
  };
179
185
 
186
+ const checkIndirect = async (): Promise<boolean> => {
187
+ const projectConfig = context.config.projects.find(
188
+ (p) => p.projectId === projectId
189
+ );
190
+ const configIndirect = projectConfig?.indirect;
191
+ if (configIndirect && !indirect) {
192
+ logger.warn(
193
+ `'${projectName}' was synced indirectly before, but a direct sync was requested. If it has page components, they will be synced and saved to plasmic.json.`
194
+ );
195
+ return await confirmWithUser(
196
+ "Do you want to confirm it?",
197
+ opts.force || opts.yes,
198
+ "n"
199
+ );
200
+ }
201
+ return true;
202
+ };
203
+
180
204
  const projectIds =
181
205
  opts.projects.length > 0
182
206
  ? opts.projects
@@ -188,7 +212,11 @@ async function checkProjectMeta(
188
212
  return true;
189
213
  }
190
214
 
191
- return (await checkVersionLock()) && (await checkVersionRange());
215
+ return (
216
+ (await checkVersionLock()) &&
217
+ (await checkVersionRange()) &&
218
+ (await checkIndirect())
219
+ );
192
220
  }
193
221
 
194
222
  /**
@@ -216,12 +244,16 @@ export async function checkVersionResolution(
216
244
  ? [root]
217
245
  : walkDependencyTree(root, versionResolution.dependencies).reverse();
218
246
  for (const m of queue) {
219
- // If we haven't seen this yet
220
247
  if (!seen.find((p) => p.projectId === m.projectId)) {
221
248
  if (await checkProjectMeta(m, root, context, opts)) {
222
249
  result.push(m);
223
250
  }
224
251
  seen.push(m);
252
+ } else if (root.projectId === m.projectId) {
253
+ // If m is the root project and it was already seen (maybe as a dep
254
+ // for another project), set indirect = false.
255
+ const project = ensure(seen.find((p) => p.projectId === m.projectId));
256
+ project.indirect = false;
225
257
  }
226
258
  }
227
259
  }