@plasmicapp/cli 0.1.304 → 0.1.306

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.
@@ -22,9 +22,7 @@ import {
22
22
  } from "../utils/code-utils";
23
23
  import {
24
24
  CONFIG_FILE_NAME,
25
- LOADER_CONFIG_FILE_NAME,
26
25
  PlasmicContext,
27
- PlasmicLoaderConfig,
28
26
  createProjectConfig,
29
27
  getOrAddProjectConfig,
30
28
  getOrAddProjectLock,
@@ -73,7 +71,6 @@ export interface SyncArgs extends CommonArgs {
73
71
  quiet?: boolean;
74
72
  metadata?: string;
75
73
  allFiles?: boolean;
76
- loaderConfig?: string;
77
74
  skipFormatting?: boolean;
78
75
  skipBuffering?: boolean;
79
76
  }
@@ -159,30 +156,6 @@ async function ensureRequiredPackages(
159
156
  }
160
157
  }
161
158
 
162
- function getLoaderConfigPath(opts: SyncArgs) {
163
- return opts.loaderConfig || LOADER_CONFIG_FILE_NAME;
164
- }
165
-
166
- function maybeReadLoaderConfig(opts: SyncArgs): Partial<PlasmicLoaderConfig> {
167
- const path = getLoaderConfigPath(opts);
168
- if (!existsBuffered(path)) {
169
- return {};
170
- }
171
- return JSON.parse(readFileText(path!));
172
- }
173
-
174
- function writeLoaderConfig(
175
- opts: SyncArgs,
176
- config: Partial<PlasmicLoaderConfig>
177
- ) {
178
- const loaderConfigPath = getLoaderConfigPath(opts);
179
-
180
- writeFileText(
181
- loaderConfigPath,
182
- formatAsLocal(JSON.stringify(config), loaderConfigPath, opts.baseDir)
183
- );
184
- }
185
-
186
159
  /**
187
160
  * Sync will always try to sync down a set of components that are version-consistent among specified projects.
188
161
  * (we only allow 1 version per projectId).
@@ -214,12 +187,8 @@ export async function sync(
214
187
  fixFileExtension(context);
215
188
  assertAllPathsInRootDir(context);
216
189
 
217
- const loaderConfig: Partial<PlasmicLoaderConfig> = process.env.PLASMIC_LOADER
218
- ? maybeReadLoaderConfig(opts)
219
- : {};
220
-
221
190
  const projectIdToToken = new Map(
222
- [...context.config.projects, ...(loaderConfig?.projects ?? [])]
191
+ [...context.config.projects]
223
192
  .filter((p) => p.projectApiToken)
224
193
  .map((p) => tuple(p.projectId, p.projectApiToken))
225
194
  );
@@ -265,9 +234,7 @@ export async function sync(
265
234
  context = await getContext(opts);
266
235
  } catch (e) {
267
236
  if ((e as any).message.includes("Unable to authenticate Plasmic")) {
268
- const configFileName = process.env.PLASMIC_LOADER
269
- ? LOADER_CONFIG_FILE_NAME
270
- : CONFIG_FILE_NAME;
237
+ const configFileName = CONFIG_FILE_NAME;
271
238
  throw new HandledError(
272
239
  `Unable to authenticate Plasmic. Please run 'plasmic auth' or check the projectApiTokens in your ${configFileName}, and try again.`
273
240
  );
@@ -376,26 +343,6 @@ export async function sync(
376
343
  // Now we know config.components are all correct, so we can go ahead and fix up all the import statements
377
344
  await fixAllImportStatements(context, opts.baseDir, summary);
378
345
 
379
- if (process.env.PLASMIC_LOADER) {
380
- const rootProjectIds = new Set(projectSyncParams.map((p) => p.projectId));
381
- const freshIdsAndTokens = projectIdsAndTokens
382
- .filter((p) => rootProjectIds.has(p.projectId))
383
- .map((p) => L.pick(p, "projectId", "projectApiToken"));
384
-
385
- const config: Partial<PlasmicLoaderConfig> = {
386
- ...loaderConfig,
387
- projects: L.sortBy(
388
- L.uniqBy(
389
- [...freshIdsAndTokens, ...(loaderConfig?.projects ?? [])],
390
- (p) => p.projectId
391
- ),
392
- (p) => p.projectId
393
- ),
394
- };
395
-
396
- writeLoaderConfig(opts, config);
397
- }
398
-
399
346
  const codegenVersion = await context.api.latestCodegenVersion();
400
347
  context.lock.projects.forEach((p) => {
401
348
  if (
package/src/api.ts CHANGED
@@ -26,7 +26,7 @@ export interface ComponentBundle {
26
26
  cssFileName: string;
27
27
  componentName: string;
28
28
  id: string;
29
- scheme: string;
29
+ scheme: "blackbox" | "plain";
30
30
  nameInIdToUuid: Array<[string, string]>;
31
31
  isPage: boolean;
32
32
  plumeType?: string;
@@ -291,6 +291,39 @@ export class PlasmicApi {
291
291
  );
292
292
  return result.data as ProjectBundle;
293
293
  }
294
+ /**
295
+ * Code-gen endpoint.
296
+ * This will fetch components from a given branch at an exact specified version
297
+ * using the "plain" scheme
298
+ */
299
+ async exportProject(
300
+ projectId: string,
301
+ branchName: string,
302
+ opts: {
303
+ platform: string;
304
+ platformOptions: {
305
+ nextjs?: {
306
+ appDir: boolean;
307
+ };
308
+ };
309
+ version: string;
310
+ imageOpts: ImagesConfig;
311
+ stylesOpts: StyleConfig;
312
+ i18nOpts?: I18NConfig;
313
+ codeOpts: Pick<CodeConfig, "lang">;
314
+ indirect: boolean;
315
+ wrapPagesWithGlobalContexts: boolean;
316
+ metadata?: Metadata;
317
+ }
318
+ ): Promise<ProjectBundle> {
319
+ const result = await this.post(
320
+ `${this.codegenHost}/api/v1/projects/${projectId}/code/components?branchName=${branchName}&export=true`,
321
+ {
322
+ ...opts,
323
+ }
324
+ );
325
+ return result.data as ProjectBundle;
326
+ }
294
327
 
295
328
  async projectMeta(projectId: string) {
296
329
  const result = await this.post(
package/src/index.ts CHANGED
@@ -5,6 +5,7 @@ import { fixImports, FixImportsArgs } from "./actions/fix-imports";
5
5
  import { InfoArgs, printProjectInfo } from "./actions/info";
6
6
  import { getYargsOption, InitArgs, initPlasmic } from "./actions/init";
7
7
  import {
8
+ getLocalizationYargs,
8
9
  localizationStrings,
9
10
  LocalizationStringsArgs,
10
11
  } from "./actions/localization-strings";
@@ -12,8 +13,8 @@ import * as projectToken from "./actions/project-token";
12
13
  import { sync, SyncArgs } from "./actions/sync";
13
14
  import { UploadBundleArgs, uploadJsBundle } from "./actions/upload-bundle";
14
15
  import { WatchArgs, watchProjects } from "./actions/watch";
15
- import { LOADER_CONFIG_FILE_NAME } from "./utils/config-utils";
16
16
  import { handleError } from "./utils/error";
17
+ import { ExportArgs, exportProjectsCli } from "./actions/export";
17
18
 
18
19
  if (process.env.DEBUG_CHDIR) {
19
20
  process.chdir(process.env.DEBUG_CHDIR);
@@ -248,7 +249,7 @@ yargs
248
249
  )
249
250
  .command<LocalizationStringsArgs>(
250
251
  "localization-strings",
251
- false,
252
+ "Generate localization strings",
252
253
  (yargs) =>
253
254
  yargs
254
255
  .option("projects", {
@@ -268,17 +269,8 @@ yargs
268
269
  choices: ["json", "po", "lingui"],
269
270
  default: "json",
270
271
  })
271
- .option("key-scheme", {
272
- describe:
273
- "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`",
274
- type: "string",
275
- choices: ["content", "hash", "path"],
276
- })
277
- .option("tag-prefix", {
278
- describe:
279
- "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>'.",
280
- type: "string",
281
- })
272
+ .option("key-scheme", getLocalizationYargs("key-scheme"))
273
+ .option("tag-prefix", getLocalizationYargs("tag-prefix"))
282
274
  .option("exclude-deps", {
283
275
  type: "boolean",
284
276
  describe:
@@ -303,6 +295,35 @@ yargs
303
295
  }),
304
296
  (argv) => handleError(localizationStrings(argv))
305
297
  )
298
+ .command<ExportArgs>(
299
+ "export",
300
+ false,
301
+ (yargs) =>
302
+ yargs
303
+ .option("projects", {
304
+ alias: "p",
305
+ describe: "ID of project to export from",
306
+ type: "array",
307
+ })
308
+ .option("out-dir", {
309
+ alias: "o",
310
+ describe: "Folder to output exported code to",
311
+ type: "string",
312
+ })
313
+ .option("platform", getYargsOption("platform"))
314
+ .option("code-lang", getYargsOption("codeLang"))
315
+ .option("code-scheme", getYargsOption("codeScheme"))
316
+ .option("style-scheme", getYargsOption("styleScheme"))
317
+ .option("images-scheme", getYargsOption("imagesScheme"))
318
+ .option("images-public-dir", getYargsOption("imagesPublicDir"))
319
+ .option(
320
+ "images-public-url-prefix",
321
+ getYargsOption("imagesPublicUrlPrefix")
322
+ )
323
+ .option("i18n-key-scheme", getLocalizationYargs("key-scheme"))
324
+ .option("i18n-tag-prefix", getLocalizationYargs("tag-prefix")),
325
+ (argv) => handleError(exportProjectsCli(argv))
326
+ )
306
327
  .demandCommand()
307
328
  .strict()
308
329
  .help("h")
@@ -325,13 +346,6 @@ function configureSyncArgs(
325
346
  describe: "Force sync to bypass specified version ranges.",
326
347
  default: false,
327
348
  })
328
- .option("loader-config", {
329
- type: "string",
330
- describe:
331
- "Path to loader config file, and causes CLI to run in PlasmicLoader mode.",
332
- hidden: true,
333
- default: LOADER_CONFIG_FILE_NAME,
334
- })
335
349
  .option("non-recursive", {
336
350
  type: "boolean",
337
351
  describe:
@@ -99,7 +99,6 @@ export function standardTestSetup(includeDep = true) {
99
99
  forceOverwrite: true,
100
100
  config: tmpRepo.plasmicJsonPath(),
101
101
  auth: tmpRepo.plasmicAuthPath(),
102
- loaderConfig: tmpRepo.plasmicLoaderJsonPath(),
103
102
  baseDir: process.cwd(),
104
103
  };
105
104
  }
@@ -154,9 +153,9 @@ export const project1Config: ProjectConfig = {
154
153
  globalContextsFilePath: "",
155
154
  };
156
155
 
157
- export function expectProject1PlasmicJson(
158
- optional?: { [k in keyof ProjectConfig]?: boolean }
159
- ) {
156
+ export function expectProject1PlasmicJson(optional?: {
157
+ [k in keyof ProjectConfig]?: boolean;
158
+ }) {
160
159
  const plasmicJson = tmpRepo.readPlasmicJson();
161
160
  expect(plasmicJson.projects.length).toEqual(1);
162
161
  const projectConfig = plasmicJson.projects[0];
@@ -18,7 +18,6 @@ export const DEFAULT_HOST =
18
18
  export const AUTH_FILE_NAME = ".plasmic.auth";
19
19
  export const CONFIG_FILE_NAME = "plasmic.json";
20
20
  export const LOCK_FILE_NAME = "plasmic.lock";
21
- export const LOADER_CONFIG_FILE_NAME = "plasmic-loader.json";
22
21
  export const CONFIG_SCHEMA_FILE_NAME = "plasmic.schema.json";
23
22
 
24
23
  // Default environment variable names
@@ -26,16 +25,6 @@ export const ENV_AUTH_HOST = "PLASMIC_AUTH_HOST";
26
25
  export const ENV_AUTH_USER = "PLASMIC_AUTH_USER";
27
26
  export const ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
28
27
 
29
- export interface PlasmicLoaderConfig {
30
- projects: ProjectIdAndToken[];
31
- aboutThisFile: string;
32
- dir: string;
33
- plasmicDir: string;
34
- pageDir: string;
35
- initArgs: Record<string, string>;
36
- substitutions?: Record<string, any>;
37
- }
38
-
39
28
  export interface PlasmicConfig {
40
29
  /** Target platform to generate code for */
41
30
  platform: "react" | "nextjs" | "gatsby";
@@ -16,10 +16,10 @@ export class HandledError extends Error {}
16
16
  * @returns
17
17
  */
18
18
  export const handleError = <T>(p: Promise<T>) => {
19
- return p.catch((e) => {
19
+ return p.catch((e: Error) => {
20
20
  if (e.message) {
21
21
  logger.error(
22
- chalk.bold(chalk.redBright("\nPlasmic error: ")) + e.message
22
+ chalk.bold(chalk.redBright("\nPlasmic error: ")) + e.message + e.stack
23
23
  );
24
24
  }
25
25
  // Check if we satisfy the engine policy first
@@ -135,6 +135,14 @@ export function eqPagePath(a: string, b: string) {
135
135
  return true;
136
136
  }
137
137
 
138
+ // We also let users rename [...page].js to [[...page]].js
139
+ const normPagePathBrackets = (p: string) => {
140
+ return p.replace("[[", "[").replace("]]", "]");
141
+ };
142
+ if (normPagePathBrackets(a) === normPagePathBrackets(b)) {
143
+ return true;
144
+ }
145
+
138
146
  // pages/about.* and pages/about/index.* resolve to the same URI, but
139
147
  // pages/index.* and pages/index/index.* do not.
140
148
  if (!a.endsWith("/index") && `${a}/index` === b) {
@@ -289,7 +289,12 @@ export async function getContext(
289
289
  {
290
290
  enableSkipAuth = false,
291
291
  skipMissingFiles = false,
292
- }: { enableSkipAuth?: boolean; skipMissingFiles?: boolean } = {}
292
+ skipInit = false,
293
+ }: {
294
+ enableSkipAuth?: boolean;
295
+ skipMissingFiles?: boolean;
296
+ skipInit?: boolean;
297
+ } = {}
293
298
  ): Promise<PlasmicContext> {
294
299
  if (!args.baseDir) args.baseDir = process.cwd();
295
300
  const auth = enableSkipAuth
@@ -361,7 +366,7 @@ export async function getContext(
361
366
  /**
362
367
  * Use empty user/token to signify no auth (only returning to provide a default host).
363
368
  */
364
- async function getCurrentOrDefaultAuth(args: CommonArgs) {
369
+ export async function getCurrentOrDefaultAuth(args: CommonArgs) {
365
370
  const auth = await getCurrentAuth(args.auth);
366
371
  if (auth) {
367
372
  return auth;
@@ -5,9 +5,7 @@ import {
5
5
  AuthConfig,
6
6
  AUTH_FILE_NAME,
7
7
  CONFIG_FILE_NAME,
8
- LOADER_CONFIG_FILE_NAME,
9
8
  PlasmicConfig,
10
- PlasmicLoaderConfig,
11
9
  } from "../utils/config-utils";
12
10
  import { deleteFileBuffered, readFileText, writeFileText } from "./file-utils";
13
11
 
@@ -105,12 +103,4 @@ export class TempRepo {
105
103
  deletePlasmicJson() {
106
104
  this.deleteFile(CONFIG_FILE_NAME);
107
105
  }
108
-
109
- plasmicLoaderJsonPath() {
110
- return this.resolveFile(LOADER_CONFIG_FILE_NAME);
111
- }
112
-
113
- readPlasmicLoaderJson(): PlasmicLoaderConfig {
114
- return JSON.parse(this.readFile(LOADER_CONFIG_FILE_NAME));
115
- }
116
106
  }