@plasmicapp/cli 0.1.304 → 0.1.305

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/lib.js CHANGED
@@ -731539,7 +731539,7 @@ var handleError = (p) => {
731539
731539
  return p.catch((e) => {
731540
731540
  if (e.message) {
731541
731541
  logger.error(
731542
- import_chalk.default.bold(import_chalk.default.redBright("\nPlasmic error: ")) + e.message
731542
+ import_chalk.default.bold(import_chalk.default.redBright("\nPlasmic error: ")) + e.message + e.stack
731543
731543
  );
731544
731544
  }
731545
731545
  if (checkEngineStrict()) {
@@ -731557,7 +731557,6 @@ var DEFAULT_HOST = process.env.PLASMIC_DEFAULT_HOST || "https://studio.plasmic.a
731557
731557
  var AUTH_FILE_NAME = ".plasmic.auth";
731558
731558
  var CONFIG_FILE_NAME = "plasmic.json";
731559
731559
  var LOCK_FILE_NAME = "plasmic.lock";
731560
- var LOADER_CONFIG_FILE_NAME = "plasmic-loader.json";
731561
731560
  var ENV_AUTH_HOST = "PLASMIC_AUTH_HOST";
731562
731561
  var ENV_AUTH_USER = "PLASMIC_AUTH_USER";
731563
731562
  var ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
@@ -731782,6 +731781,20 @@ var PlasmicApi = class {
731782
731781
  );
731783
731782
  return result.data;
731784
731783
  }
731784
+ /**
731785
+ * Code-gen endpoint.
731786
+ * This will fetch components from a given branch at an exact specified version
731787
+ * using the "plain" scheme
731788
+ */
731789
+ async exportProject(projectId, branchName, opts) {
731790
+ const result = await this.post(
731791
+ `${this.codegenHost}/api/v1/projects/${projectId}/code/components?branchName=${branchName}&export=true`,
731792
+ {
731793
+ ...opts
731794
+ }
731795
+ );
731796
+ return result.data;
731797
+ }
731785
731798
  async projectMeta(projectId) {
731786
731799
  const result = await this.post(
731787
731800
  `${this.codegenHost}/api/v1/projects/${projectId}/code/meta`
@@ -733060,7 +733073,8 @@ async function resolveMissingFilesInConfig(context, config) {
733060
733073
  }
733061
733074
  async function getContext(args, {
733062
733075
  enableSkipAuth = false,
733063
- skipMissingFiles = false
733076
+ skipMissingFiles = false,
733077
+ skipInit = false
733064
733078
  } = {}) {
733065
733079
  if (!args.baseDir)
733066
733080
  args.baseDir = process.cwd();
@@ -734149,25 +734163,7 @@ async function ensureRequiredPackages(context, baseDir, yes) {
734149
734163
  }
734150
734164
  }
734151
734165
  }
734152
- function getLoaderConfigPath(opts) {
734153
- return opts.loaderConfig || LOADER_CONFIG_FILE_NAME;
734154
- }
734155
- function maybeReadLoaderConfig(opts) {
734156
- const path14 = getLoaderConfigPath(opts);
734157
- if (!existsBuffered(path14)) {
734158
- return {};
734159
- }
734160
- return JSON.parse(readFileText(path14));
734161
- }
734162
- function writeLoaderConfig(opts, config) {
734163
- const loaderConfigPath = getLoaderConfigPath(opts);
734164
- writeFileText(
734165
- loaderConfigPath,
734166
- formatAsLocal(JSON.stringify(config), loaderConfigPath, opts.baseDir)
734167
- );
734168
- }
734169
734166
  async function sync(opts, metadataDefaults) {
734170
- var _a;
734171
734167
  if (!opts.baseDir)
734172
734168
  opts.baseDir = process.cwd();
734173
734169
  const baseDir = opts.baseDir;
@@ -734181,18 +734177,17 @@ async function sync(opts, metadataDefaults) {
734181
734177
  }
734182
734178
  fixFileExtension(context);
734183
734179
  assertAllPathsInRootDir(context);
734184
- const loaderConfig = process.env.PLASMIC_LOADER ? maybeReadLoaderConfig(opts) : {};
734185
734180
  const projectIdToToken = new Map(
734186
- [...context.config.projects, ...(_a = loaderConfig == null ? void 0 : loaderConfig.projects) != null ? _a : []].filter((p) => p.projectApiToken).map((p) => tuple(p.projectId, p.projectApiToken))
734181
+ [...context.config.projects].filter((p) => p.projectApiToken).map((p) => tuple(p.projectId, p.projectApiToken))
734187
734182
  );
734188
734183
  const projectConfigMap = import_lodash17.default.keyBy(context.config.projects, (p) => p.projectId);
734189
734184
  const projectWithVersion = opts.projects.map((p) => {
734190
- var _a2, _b, _c;
734185
+ var _a, _b, _c;
734191
734186
  const [projectIdToken, versionRange] = p.split("@");
734192
734187
  const [projectId, projectApiToken] = projectIdToken.split(":");
734193
734188
  return {
734194
734189
  projectId,
734195
- branchName: (_b = (_a2 = projectConfigMap[projectId]) == null ? void 0 : _a2.projectBranchName) != null ? _b : "main",
734190
+ branchName: (_b = (_a = projectConfigMap[projectId]) == null ? void 0 : _a.projectBranchName) != null ? _b : "main",
734196
734191
  versionRange: versionRange || ((_c = projectConfigMap[projectId]) == null ? void 0 : _c.version) || "latest",
734197
734192
  componentIdOrNames: void 0,
734198
734193
  // Get all components!
@@ -734201,10 +734196,10 @@ async function sync(opts, metadataDefaults) {
734201
734196
  };
734202
734197
  });
734203
734198
  const projectSyncParams = projectWithVersion.length ? projectWithVersion : context.config.projects.map((p) => {
734204
- var _a2;
734199
+ var _a;
734205
734200
  return {
734206
734201
  projectId: p.projectId,
734207
- branchName: (_a2 = p.projectBranchName) != null ? _a2 : "main",
734202
+ branchName: (_a = p.projectBranchName) != null ? _a : "main",
734208
734203
  versionRange: p.version,
734209
734204
  componentIdOrNames: void 0,
734210
734205
  // Get all components!
@@ -734222,7 +734217,7 @@ async function sync(opts, metadataDefaults) {
734222
734217
  context = await getContext(opts);
734223
734218
  } catch (e) {
734224
734219
  if (e.message.includes("Unable to authenticate Plasmic")) {
734225
- const configFileName = process.env.PLASMIC_LOADER ? LOADER_CONFIG_FILE_NAME : CONFIG_FILE_NAME;
734220
+ const configFileName = CONFIG_FILE_NAME;
734226
734221
  throw new HandledError(
734227
734222
  `Unable to authenticate Plasmic. Please run 'plasmic auth' or check the projectApiTokens in your ${configFileName}, and try again.`
734228
734223
  );
@@ -734259,7 +734254,6 @@ async function sync(opts, metadataDefaults) {
734259
734254
  const externalNpmPackages = /* @__PURE__ */ new Set();
734260
734255
  const externalCssImports = /* @__PURE__ */ new Set();
734261
734256
  const doSync = async () => {
734262
- var _a2;
734263
734257
  for (const projectMeta of projectsToSync) {
734264
734258
  await syncProject(
734265
734259
  context,
@@ -734303,21 +734297,6 @@ async function sync(opts, metadataDefaults) {
734303
734297
  });
734304
734298
  }
734305
734299
  await fixAllImportStatements(context, opts.baseDir, summary);
734306
- if (process.env.PLASMIC_LOADER) {
734307
- const rootProjectIds = new Set(projectSyncParams.map((p) => p.projectId));
734308
- const freshIdsAndTokens = projectIdsAndTokens.filter((p) => rootProjectIds.has(p.projectId)).map((p) => import_lodash17.default.pick(p, "projectId", "projectApiToken"));
734309
- const config = {
734310
- ...loaderConfig,
734311
- projects: import_lodash17.default.sortBy(
734312
- import_lodash17.default.uniqBy(
734313
- [...freshIdsAndTokens, ...(_a2 = loaderConfig == null ? void 0 : loaderConfig.projects) != null ? _a2 : []],
734314
- (p) => p.projectId
734315
- ),
734316
- (p) => p.projectId
734317
- )
734318
- };
734319
- writeLoaderConfig(opts, config);
734320
- }
734321
734300
  const codegenVersion = await context.api.latestCodegenVersion();
734322
734301
  context.lock.projects.forEach((p) => {
734323
734302
  if (projectsToSync.some(
@@ -1,23 +1,13 @@
1
1
  import { DeepPartial } from "utility-types";
2
- import { PlasmicApi, ProjectIdAndToken } from "../api";
2
+ import { PlasmicApi } from "../api";
3
3
  export declare const DEFAULT_HOST: string;
4
4
  export declare const AUTH_FILE_NAME = ".plasmic.auth";
5
5
  export declare const CONFIG_FILE_NAME = "plasmic.json";
6
6
  export declare const LOCK_FILE_NAME = "plasmic.lock";
7
- export declare const LOADER_CONFIG_FILE_NAME = "plasmic-loader.json";
8
7
  export declare const CONFIG_SCHEMA_FILE_NAME = "plasmic.schema.json";
9
8
  export declare const ENV_AUTH_HOST = "PLASMIC_AUTH_HOST";
10
9
  export declare const ENV_AUTH_USER = "PLASMIC_AUTH_USER";
11
10
  export declare const ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
12
- export interface PlasmicLoaderConfig {
13
- projects: ProjectIdAndToken[];
14
- aboutThisFile: string;
15
- dir: string;
16
- plasmicDir: string;
17
- pageDir: string;
18
- initArgs: Record<string, string>;
19
- substitutions?: Record<string, any>;
20
- }
21
11
  export interface PlasmicConfig {
22
12
  /** Target platform to generate code for */
23
13
  platform: "react" | "nextjs" | "gatsby";
@@ -1,10 +1,15 @@
1
1
  import { CommonArgs } from "../index";
2
2
  import { PlasmicContext, PlasmicLock } from "./config-utils";
3
3
  export declare function readLock(lockFile: string): PlasmicLock;
4
- export declare function getContext(args: CommonArgs, { enableSkipAuth, skipMissingFiles, }?: {
4
+ export declare function getContext(args: CommonArgs, { enableSkipAuth, skipMissingFiles, skipInit, }?: {
5
5
  enableSkipAuth?: boolean;
6
6
  skipMissingFiles?: boolean;
7
+ skipInit?: boolean;
7
8
  }): Promise<PlasmicContext>;
9
+ /**
10
+ * Use empty user/token to signify no auth (only returning to provide a default host).
11
+ */
12
+ export declare function getCurrentOrDefaultAuth(args: CommonArgs): Promise<import("./config-utils").AuthConfig>;
8
13
  /**
9
14
  * Table of where this metadata will be set
10
15
  *
@@ -1,5 +1,5 @@
1
1
  import * as tmp from "tmp";
2
- import { AuthConfig, PlasmicConfig, PlasmicLoaderConfig } from "../utils/config-utils";
2
+ import { AuthConfig, PlasmicConfig } from "../utils/config-utils";
3
3
  export declare class TempRepo {
4
4
  tmpDir: tmp.DirResult;
5
5
  constructor();
@@ -17,6 +17,4 @@ export declare class TempRepo {
17
17
  readPlasmicJson(): PlasmicConfig;
18
18
  writePlasmicJson(json: PlasmicConfig): void;
19
19
  deletePlasmicJson(): void;
20
- plasmicLoaderJsonPath(): string;
21
- readPlasmicLoaderJson(): PlasmicLoaderConfig;
22
20
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasmicapp/cli",
3
- "version": "0.1.304",
3
+ "version": "0.1.305",
4
4
  "description": "plasmic cli for syncing local code with Plasmic designs",
5
5
  "engines": {
6
6
  "node": ">=12"
@@ -78,5 +78,5 @@
78
78
  "wrap-ansi": "^7.0.0",
79
79
  "yargs": "^15.4.1"
80
80
  },
81
- "gitHead": "7569dd15624b746deaea9cf9631a43961a30f52f"
81
+ "gitHead": "f1d5f4fddc0f8d528cffb91a803501e51c877b42"
82
82
  }
@@ -158,55 +158,4 @@ describe("Project API tokens", () => {
158
158
  });
159
159
  await expect(sync(opts)).rejects.toThrow("Unable to authenticate");
160
160
  });
161
-
162
- test("should use plasmic-loader.json for API tokens in loader mode", async () => {
163
- process.env.PLASMIC_LOADER = "1";
164
-
165
- opts.projects = ["projectId1"];
166
- await expect(sync(opts)).resolves.toBeUndefined();
167
-
168
- const loaderConfig = tmpRepo.readPlasmicLoaderJson();
169
- expect(loaderConfig).toEqual({
170
- projects: [
171
- {
172
- projectId: "projectId1",
173
- projectApiToken: "abc",
174
- },
175
- ],
176
- });
177
-
178
- // Re-run, this time with no auth and no tokens in plasmic.json, only in plasmic-loader.json.
179
- removeAuth();
180
- tmpRepo.writePlasmicJson(defaultPlasmicJson);
181
- await expect(sync(opts)).resolves.toBeUndefined();
182
-
183
- delete process.env["PLASMIC_LOADER"];
184
- });
185
-
186
- test("works in PlasmicLoader mode even if root project was determined to not need an update", async () => {
187
- process.env.PLASMIC_LOADER = "1";
188
-
189
- // Make project1 have a dependency.
190
- standardTestSetup();
191
-
192
- // Explicitly sync both - we had a bug writing back the plasmic-loader.json in this case.
193
- opts.projects = ["projectId1", "dependencyId1"];
194
- await expect(sync(opts)).resolves.toBeUndefined();
195
-
196
- // We sync project1 which got updated, but the dependency is still same version.
197
- opts.force = false;
198
- removeAuth();
199
- mockApi.getMockProject("projectId1", "main", "1.2.3").version = "1.2.4";
200
- await expect(sync(opts)).resolves.toBeUndefined();
201
- });
202
-
203
- test("should fail in loader mode if not available", async () => {
204
- process.env.PLASMIC_LOADER = "1";
205
-
206
- opts.projects = ["projectId1"];
207
- removeAuth();
208
- await expect(sync(opts)).rejects.toThrow();
209
-
210
- delete process.env["PLASMIC_LOADER"];
211
- });
212
161
  });
@@ -0,0 +1,326 @@
1
+ import { keyBy, snakeCase } from "lodash";
2
+ import { CommonArgs } from "..";
3
+ import { ComponentBundle, PlasmicApi, ProjectBundle } from "../api";
4
+ import {
5
+ CodeConfig,
6
+ I18NConfig,
7
+ ImagesConfig,
8
+ PlasmicConfig,
9
+ StyleConfig,
10
+ findConfigFile,
11
+ } from "../utils/config-utils";
12
+ import { getContext, getCurrentOrDefaultAuth } from "../utils/get-context";
13
+ import { tuple } from "../utils/lang-utils";
14
+ import {
15
+ fixAllImportStatements,
16
+ formatAsLocal,
17
+ maybeConvertTsxToJsx,
18
+ } from "../utils/code-utils";
19
+ import { promises as fs, write } from "fs";
20
+ import path from "path";
21
+ import { DEFAULT_GLOBAL_CONTEXTS_NAME } from "./sync-global-contexts";
22
+ import { ensureImageAssetContents } from "./sync-images";
23
+ import { logger } from "../deps";
24
+
25
+ export interface ExportArgs extends CommonArgs {
26
+ projects: readonly string[];
27
+ platform: "" | "react" | "nextjs" | "gatsby";
28
+ codeLang: "" | "ts" | "js";
29
+ styleScheme: "" | "css" | "css-modules";
30
+ imagesScheme: "" | "inlined" | "files" | "public-files";
31
+ imagesPublicDir: string;
32
+ imagesPublicUrlPrefix: string;
33
+ i18nKeyScheme: "" | I18NConfig["keyScheme"];
34
+ i18nTagPrefix: "" | I18NConfig["tagPrefix"];
35
+
36
+ skipFormatting?: boolean;
37
+
38
+ outDir: string;
39
+ }
40
+
41
+ export async function exportProjectsCli(opts: ExportArgs): Promise<void> {
42
+ if (!opts.baseDir) opts.baseDir = process.cwd();
43
+ let configFile =
44
+ opts.config || findConfigFile(opts.baseDir, { traverseParents: true });
45
+ let context = configFile
46
+ ? await getContext(opts, { enableSkipAuth: true })
47
+ : undefined;
48
+ const projectConfigMap = keyBy(
49
+ context?.config.projects ?? [],
50
+ (p) => p.projectId
51
+ );
52
+ const projectIdToToken = new Map(
53
+ [...(context?.config.projects ?? [])]
54
+ .filter((p) => p.projectApiToken)
55
+ .map((p) => tuple(p.projectId, p.projectApiToken))
56
+ );
57
+ const projectWithVersion = opts.projects.map((p) => {
58
+ const [projectIdToken, versionRange] = p.split("@");
59
+ const [projectId, projectApiToken] = projectIdToken.split(":");
60
+ return {
61
+ projectId,
62
+ branchName: projectConfigMap[projectId]?.projectBranchName ?? "main",
63
+ versionRange:
64
+ versionRange || projectConfigMap[projectId]?.version || "latest",
65
+ componentIdOrNames: undefined, // Get all components!
66
+ projectApiToken: projectApiToken || projectIdToToken.get(projectId),
67
+ indirect: false,
68
+ };
69
+ });
70
+
71
+ const auth = await getCurrentOrDefaultAuth(opts);
72
+ const api = new PlasmicApi(auth);
73
+ const result = await exportProjects(api, {
74
+ projects: projectWithVersion.map((p) => ({
75
+ id: p.projectId,
76
+ token: p.projectApiToken,
77
+ branchName: p.branchName,
78
+ version: p.versionRange,
79
+ })),
80
+ platform: opts.platform || "react",
81
+ codeOpts: { lang: opts.codeLang || "ts" },
82
+ stylesOpts: { scheme: opts.styleScheme || "css-modules" },
83
+ imageOpts: { scheme: opts.imagesScheme || "files" },
84
+ i18nOpts: opts.i18nKeyScheme
85
+ ? { keyScheme: opts.i18nKeyScheme, tagPrefix: opts.i18nTagPrefix }
86
+ : undefined,
87
+ });
88
+
89
+ const extx = opts.codeLang === "js" ? "jsx" : "tsx";
90
+
91
+ const writeProj = async (bundle: ProjectBundle) => {
92
+ await ensureImageAssetContents(bundle.imageAssets);
93
+ const outPath = path.resolve(opts.outDir);
94
+ const promises: Promise<void>[] = [];
95
+ const writeFile = (fileName: string, content: string | Buffer) => {
96
+ if (typeof content === "string" && !opts.skipFormatting) {
97
+ content = formatAsLocal(content, fileName, opts.outDir);
98
+ }
99
+ const projectName = snakeCase(bundle.projectConfig.projectName);
100
+ promises.push(
101
+ (async () => {
102
+ await fs.mkdir(path.join(outPath, projectName), { recursive: true });
103
+ await fs.writeFile(
104
+ path.join(outPath, projectName, fileName),
105
+ content
106
+ );
107
+ })()
108
+ );
109
+ };
110
+ for (const comp of bundle.components) {
111
+ writeFile(comp.skeletonModuleFileName, comp.skeletonModule);
112
+ writeFile(comp.cssFileName, comp.cssRules);
113
+ }
114
+ for (const icon of bundle.iconAssets) {
115
+ writeFile(icon.fileName, icon.module);
116
+ }
117
+ for (const gv of bundle.globalVariants) {
118
+ writeFile(gv.contextFileName, gv.contextModule);
119
+ }
120
+
121
+ for (const img of bundle.imageAssets) {
122
+ writeFile(img.fileName, Buffer.from(img.blob, "base64"));
123
+ }
124
+
125
+ writeFile(bundle.projectConfig.cssFileName, bundle.projectConfig.cssRules);
126
+ if (bundle.projectConfig.globalContextBundle) {
127
+ writeFile(
128
+ `${DEFAULT_GLOBAL_CONTEXTS_NAME}.${extx}`,
129
+ bundle.projectConfig.globalContextBundle.contextModule
130
+ );
131
+ }
132
+
133
+ await Promise.all(promises);
134
+ };
135
+
136
+ await Promise.all(result.map((res) => writeProj(res)));
137
+
138
+ await fixAllImportStatements(
139
+ {
140
+ configFile: "",
141
+ lockFile: "",
142
+ rootDir: path.resolve(opts.outDir),
143
+ absoluteSrcDir: path.resolve(opts.outDir),
144
+ config: {
145
+ platform: opts.platform || "react",
146
+ srcDir: "./",
147
+ defaultPlasmicDir: "./",
148
+ code: {
149
+ lang: opts.codeLang || "ts",
150
+ scheme: "blackbox",
151
+ reactRuntime: "classic",
152
+ },
153
+ images: {
154
+ scheme: opts.imagesScheme || "files",
155
+ publicDir: opts.imagesPublicDir,
156
+ publicUrlPrefix: opts.imagesPublicUrlPrefix,
157
+ },
158
+ style: {
159
+ scheme: opts.styleScheme || "css-modules",
160
+ defaultStyleCssFilePath: "",
161
+ },
162
+ tokens: {} as any,
163
+ globalVariants: {
164
+ variantGroups: result.flatMap((bundle) => {
165
+ const projectName = snakeCase(bundle.projectConfig.projectName);
166
+ return bundle.globalVariants.map((gv) => ({
167
+ id: gv.id,
168
+ name: gv.name,
169
+ projectId: bundle.projectConfig.projectId,
170
+ contextFilePath: `./${projectName}/${gv.contextFileName}`,
171
+ }));
172
+ }),
173
+ },
174
+ projects: result.map((bundle) => {
175
+ const projectName = snakeCase(bundle.projectConfig.projectName);
176
+ return {
177
+ projectId: bundle.projectConfig.projectId,
178
+ projectName: bundle.projectConfig.projectName,
179
+ version: "latest",
180
+ cssFilePath: `${projectName}/${bundle.projectConfig.cssFileName}`,
181
+ globalContextsFilePath: bundle.projectConfig.globalContextBundle
182
+ ? `${projectName}/${DEFAULT_GLOBAL_CONTEXTS_NAME}.${extx}`
183
+ : "",
184
+ components: bundle.components.map((comp) => ({
185
+ id: comp.id,
186
+ name: comp.componentName,
187
+ projectId: bundle.projectConfig.projectId,
188
+ type: "managed",
189
+ importSpec: {
190
+ modulePath: `${projectName}/${comp.skeletonModuleFileName}`,
191
+ },
192
+ renderModuleFilePath: `${projectName}/${comp.skeletonModuleFileName}`,
193
+ cssFilePath: `${projectName}/${comp.cssFileName}`,
194
+ scheme: "blackbox",
195
+ componentType: `${comp.isPage ? "page" : "component"}`,
196
+ plumeType: comp.plumeType,
197
+ })),
198
+ codeComponents: bundle.codeComponentMetas.map((comp) => ({
199
+ id: comp.id,
200
+ name: comp.name,
201
+ displayName: comp.displayName,
202
+ componentImportPath: comp.importPath,
203
+ helper: comp.helper,
204
+ })),
205
+ icons: bundle.iconAssets.map((icon) => ({
206
+ id: icon.id,
207
+ name: icon.name,
208
+ moduleFilePath: `${projectName}/${icon.fileName}`,
209
+ })),
210
+ images: bundle.imageAssets.map((image) => ({
211
+ id: image.id,
212
+ name: image.name,
213
+ filePath: `${projectName}/${image.fileName}`,
214
+ })),
215
+ indirect: false,
216
+ };
217
+ }),
218
+ wrapPagesWithGlobalContexts: true,
219
+ },
220
+ lock: {} as any,
221
+ auth: {} as any,
222
+ api: api,
223
+ cliArgs: {} as any,
224
+ },
225
+ opts.outDir
226
+ );
227
+ }
228
+
229
+ interface ExportOpts {
230
+ projects: {
231
+ id: string;
232
+ token?: string;
233
+ branchName?: string;
234
+ version?: string;
235
+ }[];
236
+ platform?: PlasmicConfig["platform"];
237
+ imageOpts?: ImagesConfig;
238
+ stylesOpts?: Omit<StyleConfig, "defaultStyleCssFilePath">;
239
+ i18nOpts?: I18NConfig;
240
+ codeOpts?: Omit<CodeConfig, "scheme" | "reactRuntime">;
241
+ }
242
+
243
+ async function exportProjects(api: PlasmicApi, opts: ExportOpts) {
244
+ api.attachProjectIdsAndTokens(
245
+ opts.projects.map((proj) => ({
246
+ projectId: proj.id,
247
+ projectApiToken: proj.token,
248
+ }))
249
+ );
250
+
251
+ const versionResolution = await api.resolveSync(
252
+ opts.projects.map((p) => ({
253
+ projectId: p.id,
254
+ branchName: p.branchName ?? "main",
255
+ versionRange: p.version,
256
+ componentIdOrNames: undefined,
257
+ projectApiToken: p.token,
258
+ indirect: false,
259
+ })),
260
+ true
261
+ );
262
+
263
+ const versionsToSync = [
264
+ ...versionResolution.dependencies,
265
+ ...versionResolution.projects,
266
+ ];
267
+
268
+ const result = await Promise.all(
269
+ versionsToSync.map(async (v) => {
270
+ return api.exportProject(v.projectId, v.branchName, {
271
+ platform: opts.platform ?? "react",
272
+ platformOptions: {},
273
+ version: v.version,
274
+ imageOpts: opts.imageOpts ?? {
275
+ scheme: "files",
276
+ },
277
+ stylesOpts: {
278
+ defaultStyleCssFilePath: "",
279
+ scheme: "css-modules",
280
+ ...opts.stylesOpts,
281
+ },
282
+ i18nOpts: opts.i18nOpts,
283
+ codeOpts: opts.codeOpts ?? { lang: "ts" },
284
+ indirect: v.indirect,
285
+ wrapPagesWithGlobalContexts: true,
286
+ });
287
+ })
288
+ );
289
+
290
+ if (opts.codeOpts?.lang === "js") {
291
+ for (const proj of result) {
292
+ for (const comp of proj.components) {
293
+ [comp.skeletonModuleFileName, comp.skeletonModule] =
294
+ maybeConvertTsxToJsx(
295
+ comp.skeletonModuleFileName,
296
+ comp.skeletonModule,
297
+ "."
298
+ );
299
+ }
300
+ for (const icon of proj.iconAssets) {
301
+ [icon.fileName, icon.module] = maybeConvertTsxToJsx(
302
+ icon.fileName,
303
+ icon.module,
304
+ "."
305
+ );
306
+ }
307
+ for (const gv of proj.globalVariants) {
308
+ [gv.contextFileName, gv.contextModule] = maybeConvertTsxToJsx(
309
+ gv.contextFileName,
310
+ gv.contextModule,
311
+ "."
312
+ );
313
+ }
314
+ if (proj.projectConfig.globalContextBundle) {
315
+ const res = maybeConvertTsxToJsx(
316
+ `${DEFAULT_GLOBAL_CONTEXTS_NAME}.tsx`,
317
+ proj.projectConfig.globalContextBundle.contextModule,
318
+ "."
319
+ );
320
+ proj.projectConfig.globalContextBundle.contextModule = res[1];
321
+ }
322
+ }
323
+ }
324
+
325
+ return result;
326
+ }
@@ -22,6 +22,25 @@ export interface LocalizationStringsArgs extends CommonArgs {
22
22
  excludeDeps: boolean | undefined;
23
23
  }
24
24
 
25
+ export function getLocalizationYargs(key: "key-scheme" | "tag-prefix") {
26
+ if (key === "key-scheme") {
27
+ return {
28
+ describe:
29
+ "What value to use as message keys; `content` uses the message content itself, `hash` uses a hash of the content, and `path` uses a a hierarchical string containing the project id, component name, element name, and related variants, and does not encode the text content in the key. Defaults to whatever is specified in plasmic.json, or `content`",
30
+ type: "string" as const,
31
+ choices: ["content", "hash", "path"],
32
+ };
33
+ } else if (key === "tag-prefix") {
34
+ return {
35
+ describe:
36
+ "By default, rich text with markup tags look like '<0>hello</0>'. If your localization framework requires num-numeric tags, then specify a prefix; for example a prefix of 'n' turns it into '<n0>hello</n0>'.",
37
+ type: "string" as const,
38
+ };
39
+ } else {
40
+ throw new Error(`Unexpected localization option ${key}`);
41
+ }
42
+ }
43
+
25
44
  export async function localizationStrings(
26
45
  opts: LocalizationStringsArgs
27
46
  ): Promise<void> {
@@ -233,7 +233,7 @@ export async function syncProjectComponents(
233
233
 
234
234
  compConfig.plumeType = plumeType;
235
235
 
236
- if (scheme === "direct") {
236
+ if ((scheme as any) === "direct") {
237
237
  throw new Error(`Direct update codegen scheme is no longer supported`);
238
238
  } else if (/\/\/\s*plasmic-managed-jsx\/\d+/.test(editedFile)) {
239
239
  if (forceOverwrite) {
@@ -15,6 +15,7 @@ import {
15
15
  } from "../utils/file-utils";
16
16
 
17
17
  const COMPONENT_NAME = "PlasmicGlobalContextsProvider";
18
+ export const DEFAULT_GLOBAL_CONTEXTS_NAME = COMPONENT_NAME;
18
19
 
19
20
  export async function syncGlobalContexts(
20
21
  context: PlasmicContext,
@@ -130,7 +130,7 @@ export async function syncProjectImageAssets(
130
130
  );
131
131
  }
132
132
 
133
- async function ensureImageAssetContents(bundles: ImageBundle[]) {
133
+ export async function ensureImageAssetContents(bundles: ImageBundle[]) {
134
134
  // The server may send images as a url instead of a base64 blob. In that
135
135
  // case, we fetch the images here in the cli, instead of on the server.
136
136
  // If you have a lot of images, this moves the expensive / long fetch