@plasmicapp/cli 0.1.352 → 0.1.354

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 (42) hide show
  1. package/dist/__tests__/envdetect.spec.d.ts +1 -0
  2. package/dist/actions/sync-components.d.ts +1 -1
  3. package/dist/actions/sync-data-tokens.d.ts +1 -1
  4. package/dist/actions/sync-global-contexts.d.ts +1 -1
  5. package/dist/actions/sync-global-variants.d.ts +1 -1
  6. package/dist/actions/sync-icons.d.ts +1 -1
  7. package/dist/actions/sync-project-module.d.ts +1 -1
  8. package/dist/actions/sync-splits-provider.d.ts +1 -1
  9. package/dist/actions/sync-style-tokens-provider.d.ts +1 -1
  10. package/dist/api.d.ts +0 -8
  11. package/dist/index.js +246 -4576
  12. package/dist/lib.d.ts +5 -6
  13. package/dist/lib.js +595 -4885
  14. package/dist/plasmic.schema.json +0 -21
  15. package/dist/utils/code-utils.d.ts +6 -6
  16. package/dist/utils/config-utils.d.ts +3 -8
  17. package/dist/utils/envdetect.d.ts +1 -1
  18. package/package.json +2 -2
  19. package/src/__tests__/code-utils-spec.ts +6 -9
  20. package/src/__tests__/envdetect.spec.ts +115 -0
  21. package/src/actions/export.ts +110 -120
  22. package/src/actions/fix-imports.ts +5 -3
  23. package/src/actions/init.ts +5 -4
  24. package/src/actions/sync-components.ts +2 -6
  25. package/src/actions/sync-data-tokens.ts +2 -4
  26. package/src/actions/sync-global-contexts.ts +5 -6
  27. package/src/actions/sync-global-variants.ts +3 -8
  28. package/src/actions/sync-icons.ts +3 -4
  29. package/src/actions/sync-project-module.ts +5 -6
  30. package/src/actions/sync-splits-provider.ts +5 -6
  31. package/src/actions/sync-style-tokens-provider.ts +5 -7
  32. package/src/actions/sync.ts +15 -34
  33. package/src/api.ts +0 -63
  34. package/src/index.ts +0 -62
  35. package/src/lib.ts +11 -12
  36. package/src/migrations/migrations.ts +3 -3
  37. package/src/utils/code-utils.ts +16 -46
  38. package/src/utils/config-utils.ts +7 -27
  39. package/src/utils/envdetect.ts +42 -5
  40. package/src/utils/rsc-config.ts +29 -12
  41. package/dist/actions/upload-bundle.d.ts +0 -15
  42. package/src/actions/upload-bundle.ts +0 -38
@@ -44,7 +44,6 @@ import { assert, flatMap } from "./lang-utils";
44
44
  export async function formatAsLocal(
45
45
  content: string,
46
46
  filePath: string,
47
- baseDir: string,
48
47
  defaultOpts?: Options
49
48
  ): Promise<string> {
50
49
  if (GLOBAL_SETTINGS.skipFormatting) {
@@ -56,7 +55,7 @@ export async function formatAsLocal(
56
55
  // createPlasmicElementProxy. So we're going to stop for now until we find
57
56
  // a better solution, like maybe letting user specify a prettier config
58
57
  // file in plasmic.json
59
- // const opts = resolveConfig.sync(baseDir) || defaultOpts;
58
+ // const opts = resolveConfig.sync() || defaultOpts;
60
59
  const opts: Options = {
61
60
  trailingComma: "none",
62
61
  ...defaultOpts,
@@ -73,7 +72,6 @@ export async function formatAsLocal(
73
72
 
74
73
  async function nodeToFormattedCode(
75
74
  n: Node,
76
- baseDir: string,
77
75
  unformatted?: boolean,
78
76
  commentsToRemove?: Set<string>
79
77
  ): Promise<string> {
@@ -84,7 +82,7 @@ async function nodeToFormattedCode(
84
82
  }).code;
85
83
  return unformatted
86
84
  ? c
87
- : await formatAsLocal(c, "/tmp/x.tsx", baseDir, {
85
+ : await formatAsLocal(c, "/tmp/x.tsx", {
88
86
  arrowParens: "avoid",
89
87
  });
90
88
  }
@@ -174,7 +172,6 @@ type PlasmicImportType =
174
172
  | "defaultcss"
175
173
  | "icon"
176
174
  | "picture"
177
- | "jsBundle"
178
175
  | "codeComponent"
179
176
  | "codeComponentHelper"
180
177
  | "globalContext"
@@ -214,7 +211,7 @@ function tryParsePlasmicImportSpec(node: ImportDeclaration) {
214
211
  "plasmic-import:\\s+([",
215
212
  ...validJsIdentifierChars,
216
213
  "\\.",
217
- "]+)(?:\\/(component|css|render|globalVariant|projectcss|defaultcss|icon|picture|jsBundle|codeComponent|globalContext|customFunction|splitsProvider|styleTokensProvider|dataTokens|projectModule|rscClient|rscServer))?",
214
+ "]+)(?:\\/(component|css|render|globalVariant|projectcss|defaultcss|icon|picture|codeComponent|globalContext|customFunction|splitsProvider|styleTokensProvider|dataTokens|projectModule|rscClient|rscServer))?",
218
215
  ].join("")
219
216
  )
220
217
  );
@@ -243,7 +240,6 @@ export async function replaceImports(
243
240
  fromPath: string,
244
241
  fixImportContext: FixImportContext,
245
242
  removeImportDirective: boolean,
246
- baseDir: string,
247
243
  changed = false
248
244
  ): Promise<string> {
249
245
  [code, changed] = filterUnformattedMarker(code, changed);
@@ -509,7 +505,7 @@ export async function replaceImports(
509
505
  return code;
510
506
  }
511
507
 
512
- return nodeToFormattedCode(file, baseDir, !changed, commentsToRemove);
508
+ return nodeToFormattedCode(file, !changed, commentsToRemove);
513
509
  }
514
510
 
515
511
  function throwMissingReference(
@@ -631,7 +627,6 @@ export const mkFixImportContext = (config: PlasmicConfig): FixImportContext => {
631
627
  */
632
628
  export async function fixAllImportStatements(
633
629
  context: PlasmicContext,
634
- baseDir: string,
635
630
  summary?: Map<string, ComponentUpdateSummary>
636
631
  ) {
637
632
  logger.info("Fixing import statements...");
@@ -641,12 +636,7 @@ export async function fixAllImportStatements(
641
636
  for (const project of config.projects) {
642
637
  for (const compConfig of project.components) {
643
638
  try {
644
- await fixRscModulesImports(
645
- context,
646
- baseDir,
647
- fixImportContext,
648
- compConfig
649
- );
639
+ await fixRscModulesImports(context, fixImportContext, compConfig);
650
640
  } catch (err) {
651
641
  lastError = err;
652
642
  }
@@ -664,8 +654,7 @@ export async function fixAllImportStatements(
664
654
  context,
665
655
  compConfig,
666
656
  fixImportContext,
667
- fixSkeletonModule,
668
- baseDir
657
+ fixSkeletonModule
669
658
  );
670
659
  } catch (err) {
671
660
  logger.error(
@@ -678,7 +667,7 @@ export async function fixAllImportStatements(
678
667
  }
679
668
 
680
669
  try {
681
- await fixGlobalContextImportStatements(context, fixImportContext, baseDir);
670
+ await fixGlobalContextImportStatements(context, fixImportContext);
682
671
  } catch (err) {
683
672
  logger.error(
684
673
  `Error encountered while fixing imports for global contexts: ${err}`
@@ -690,7 +679,6 @@ export async function fixAllImportStatements(
690
679
  await fixImportStatements(
691
680
  context,
692
681
  fixImportContext,
693
- baseDir,
694
682
  "splitsProviderFilePath",
695
683
  getSplitsProviderResourcePath
696
684
  );
@@ -705,7 +693,6 @@ export async function fixAllImportStatements(
705
693
  await fixImportStatements(
706
694
  context,
707
695
  fixImportContext,
708
- baseDir,
709
696
  "projectModuleFilePath",
710
697
  getProjectModuleResourcePath
711
698
  );
@@ -720,7 +707,6 @@ export async function fixAllImportStatements(
720
707
  await fixImportStatements(
721
708
  context,
722
709
  fixImportContext,
723
- baseDir,
724
710
  "styleTokensProviderFilePath",
725
711
  getStyleTokensProviderResourcePath
726
712
  );
@@ -735,7 +721,6 @@ export async function fixAllImportStatements(
735
721
  await fixImportStatements(
736
722
  context,
737
723
  fixImportContext,
738
- baseDir,
739
724
  "dataTokensFilePath",
740
725
  getDataTokensResourcePath
741
726
  );
@@ -755,8 +740,7 @@ async function fixComponentImportStatements(
755
740
  context: PlasmicContext,
756
741
  compConfig: ComponentConfig,
757
742
  fixImportContext: FixImportContext,
758
- fixSkeletonModule: boolean,
759
- baseDir: string
743
+ fixSkeletonModule: boolean
760
744
  ) {
761
745
  // If ComponentConfig.importPath is still a local file, we best-effort also fix up the import statements there.
762
746
  if (
@@ -768,8 +752,7 @@ async function fixComponentImportStatements(
768
752
  context,
769
753
  compConfig.importSpec.modulePath,
770
754
  fixImportContext,
771
- true,
772
- baseDir
755
+ true
773
756
  );
774
757
  }
775
758
 
@@ -796,7 +779,6 @@ async function fixComponentImportStatements(
796
779
  compConfig.renderModuleFilePath,
797
780
  fixImportContext,
798
781
  false,
799
- baseDir,
800
782
  renderModuleChanged
801
783
  );
802
784
  }
@@ -806,7 +788,6 @@ async function fixFileImportStatements(
806
788
  srcDirFilePath: string,
807
789
  fixImportContext: FixImportContext,
808
790
  removeImportDirective: boolean,
809
- baseDir: string,
810
791
  fileHasChanged = false
811
792
  ) {
812
793
  const filePath = makeFilePath(context, srcDirFilePath);
@@ -825,7 +806,6 @@ async function fixFileImportStatements(
825
806
  srcDirFilePath,
826
807
  fixImportContext,
827
808
  removeImportDirective,
828
- baseDir,
829
809
  fileHasChanged
830
810
  );
831
811
  if (prevContent !== newContent) {
@@ -887,21 +867,17 @@ export const tsxToJsx = (code: string) => {
887
867
 
888
868
  export async function maybeConvertTsxToJsx(
889
869
  fileName: string,
890
- content: string,
891
- baseDir: string
870
+ content: string
892
871
  ): Promise<[string, string]> {
893
872
  if (fileName.endsWith("tsx")) {
894
873
  const jsFileName = stripExtension(fileName) + ".jsx";
895
- const jsContent = await formatScript(tsxToJsx(content), baseDir);
874
+ const jsContent = await formatScript(tsxToJsx(content));
896
875
  return [jsFileName, jsContent];
897
876
  }
898
877
  return [fileName, content];
899
878
  }
900
879
 
901
- export async function formatScript(
902
- code: string,
903
- baseDir: string
904
- ): Promise<string> {
880
+ export async function formatScript(code: string): Promise<string> {
905
881
  const file = parser.parse(code, {
906
882
  strictMode: true,
907
883
  sourceType: "module",
@@ -923,12 +899,12 @@ export async function formatScript(
923
899
  },
924
900
  });
925
901
 
926
- const withmarkers = await nodeToFormattedCode(file, baseDir, true);
902
+ const withmarkers = await nodeToFormattedCode(file, true);
927
903
  const withNewLines = withmarkers.replace(
928
904
  new RegExp(`"${newLineMarker}"`, "g"),
929
905
  "\n"
930
906
  );
931
- return await formatAsLocal(withNewLines, "/tmp/x.tsx", baseDir, {
907
+ return await formatAsLocal(withNewLines, "/tmp/x.tsx", {
932
908
  printWidth: 80,
933
909
  tabWidth: 2,
934
910
  useTabs: false,
@@ -937,8 +913,7 @@ export async function formatScript(
937
913
 
938
914
  async function fixGlobalContextImportStatements(
939
915
  context: PlasmicContext,
940
- fixImportContext: FixImportContext,
941
- baseDir: string
916
+ fixImportContext: FixImportContext
942
917
  ) {
943
918
  for (const project of context.config.projects) {
944
919
  if (!project.globalContextsFilePath) {
@@ -964,7 +939,6 @@ async function fixGlobalContextImportStatements(
964
939
  resourcePath,
965
940
  fixImportContext,
966
941
  false,
967
- baseDir,
968
942
  true
969
943
  );
970
944
 
@@ -979,7 +953,6 @@ async function fixGlobalContextImportStatements(
979
953
  async function fixImportStatements(
980
954
  context: PlasmicContext,
981
955
  fixImportContext: FixImportContext,
982
- baseDir: string,
983
956
  configKey: keyof ProjectConfig,
984
957
  getResourcePath: (ctx: PlasmicContext, project: ProjectConfig) => string
985
958
  ) {
@@ -1008,7 +981,6 @@ async function fixImportStatements(
1008
981
  resourcePath,
1009
982
  fixImportContext,
1010
983
  false,
1011
- baseDir,
1012
984
  true
1013
985
  );
1014
986
 
@@ -1022,7 +994,6 @@ async function fixImportStatements(
1022
994
 
1023
995
  export async function fixRscModulesImports(
1024
996
  context: PlasmicContext,
1025
- baseDir: string,
1026
997
  fixImportContext: FixImportContext,
1027
998
  compConfig: ComponentConfig
1028
999
  ) {
@@ -1041,8 +1012,7 @@ export async function fixRscModulesImports(
1041
1012
  context,
1042
1013
  modulePath,
1043
1014
  fixImportContext,
1044
- false,
1045
- baseDir
1015
+ false
1046
1016
  );
1047
1017
  } catch (err) {
1048
1018
  logger.error(
@@ -148,11 +148,6 @@ export interface ImagesConfig {
148
148
  publicUrlPrefix?: string;
149
149
  }
150
150
 
151
- export interface JsBundleThemeConfig {
152
- themeFilePath: string;
153
- bundleName: string;
154
- }
155
-
156
151
  export interface CodeComponentConfig {
157
152
  id: string;
158
153
  name: string;
@@ -203,7 +198,6 @@ export interface ProjectConfig {
203
198
 
204
199
  // Code-component-related fields can be treated as optional not to be shown
205
200
  // to the users nor appear to be missing in the documentation.
206
- jsBundleThemes?: JsBundleThemeConfig[];
207
201
  codeComponents?: CodeComponentConfig[];
208
202
  customFunctions?: CustomFunctionConfig[];
209
203
 
@@ -555,11 +549,7 @@ export function readConfig(
555
549
  }
556
550
  }
557
551
 
558
- export async function writeConfig(
559
- configFile: string,
560
- config: PlasmicConfig,
561
- baseDir: string
562
- ) {
552
+ export async function writeConfig(configFile: string, config: PlasmicConfig) {
563
553
  await writeFileContentRaw(
564
554
  configFile,
565
555
  await formatAsLocal(
@@ -571,8 +561,7 @@ export async function writeConfig(
571
561
  undefined,
572
562
  2
573
563
  ),
574
- configFile,
575
- baseDir
564
+ configFile
576
565
  ),
577
566
  {
578
567
  force: true,
@@ -580,18 +569,10 @@ export async function writeConfig(
580
569
  );
581
570
  }
582
571
 
583
- export async function writeLock(
584
- lockFile: string,
585
- lock: PlasmicLock,
586
- baseDir: string
587
- ) {
572
+ export async function writeLock(lockFile: string, lock: PlasmicLock) {
588
573
  await writeFileContentRaw(
589
574
  lockFile,
590
- await formatAsLocal(
591
- JSON.stringify(lock, undefined, 2),
592
- "/tmp/x.json",
593
- baseDir
594
- ),
575
+ await formatAsLocal(JSON.stringify(lock, undefined, 2), "/tmp/x.json"),
595
576
  {
596
577
  force: true,
597
578
  }
@@ -600,15 +581,14 @@ export async function writeLock(
600
581
 
601
582
  export async function updateConfig(
602
583
  context: PlasmicContext,
603
- newConfig: PlasmicConfig,
604
- baseDir: string
584
+ newConfig: PlasmicConfig
605
585
  ) {
606
586
  // plasmic.json
607
- await writeConfig(context.configFile, newConfig, baseDir);
587
+ await writeConfig(context.configFile, newConfig);
608
588
  context.config = newConfig;
609
589
 
610
590
  // plasmic.lock
611
- await writeLock(context.lockFile, context.lock, baseDir);
591
+ await writeLock(context.lockFile, context.lock);
612
592
  }
613
593
 
614
594
  export function getOrAddProjectConfig(
@@ -1,4 +1,5 @@
1
1
  import findupSync from "findup-sync";
2
+ import semver from "semver";
2
3
  import { getParsedPackageJson } from "./npm-utils";
3
4
 
4
5
  export function detectTypescript() {
@@ -7,9 +8,13 @@ export function detectTypescript() {
7
8
 
8
9
  export function detectNextJs() {
9
10
  if (
10
- findupSync("next.config.js") ||
11
- findupSync(".next") ||
12
- findupSync("next-env.d.ts")
11
+ findupSync([
12
+ "next.config.js",
13
+ "next.config.ts",
14
+ "next.config.mjs",
15
+ ".next/",
16
+ "next-env.d.ts",
17
+ ])
13
18
  ) {
14
19
  return true;
15
20
  }
@@ -26,12 +31,44 @@ export function detectNextJs() {
26
31
  }
27
32
 
28
33
  export function detectNextJsAppDir() {
34
+ if (!detectNextJs()) {
35
+ return false;
36
+ }
37
+
29
38
  const nextConfigPath = findupSync("next.config.js");
30
- if (!nextConfigPath) {
39
+ // Legacy Next.js (<13.4): explicit opt-in
40
+ if (nextConfigPath && require(nextConfigPath)?.experimental?.appDir) {
41
+ return true;
42
+ }
43
+
44
+ if (!findupSync("app")) {
45
+ return false;
46
+ }
47
+
48
+ if (!findupSync("pages")) {
49
+ return true;
50
+ }
51
+
52
+ // Both app/ and pages/ exist - need to check Next.js version
53
+ try {
54
+ const packageJson = getParsedPackageJson();
55
+ const nextVersion: string | undefined = packageJson.dependencies?.next;
56
+ if (nextVersion) {
57
+ if (nextVersion === "latest") {
58
+ return true;
59
+ }
60
+ const coercedVersion = semver.coerce(nextVersion);
61
+ // For Next.js >= 13.4, app dir is the default
62
+ if (coercedVersion && semver.gte(coercedVersion, "13.4.0")) {
63
+ return true;
64
+ }
65
+ }
66
+ } catch {
67
+ // Can't read package.json - can't determine if App Router is enabled
31
68
  return false;
32
69
  }
33
70
 
34
- return require(nextConfigPath)?.experimental?.appDir || false;
71
+ return false;
35
72
  }
36
73
 
37
74
  export function detectGatsby() {
@@ -1,4 +1,5 @@
1
1
  import { ComponentBundle } from "../api";
2
+ import { maybeConvertTsxToJsx } from "./code-utils";
2
3
  import { ComponentConfig, PlasmicContext, ProjectConfig } from "./config-utils";
3
4
  import { defaultResourcePath, writeFileContent } from "./file-utils";
4
5
 
@@ -20,33 +21,49 @@ export async function syncRscFiles(
20
21
  };
21
22
  }
22
23
 
23
- const serverModuleFilePath = defaultResourcePath(
24
+ let serverModuleFilePath = defaultResourcePath(
24
25
  context,
25
26
  project,
26
27
  rscMetadata.pageWrappers.server.fileName
27
28
  );
29
+ let serverModuleContent = rscMetadata.pageWrappers.server.module;
30
+
31
+ if (context.config.code.lang === "js") {
32
+ const [convertedFileName, convertedContent] = await maybeConvertTsxToJsx(
33
+ serverModuleFilePath,
34
+ serverModuleContent
35
+ );
36
+ serverModuleFilePath = convertedFileName;
37
+ serverModuleContent = convertedContent;
38
+ }
28
39
  compConfig.rsc.serverModulePath = serverModuleFilePath;
29
40
 
30
- await writeFileContent(
31
- context,
32
- serverModuleFilePath,
33
- rscMetadata.pageWrappers.server.module,
34
- {
35
- force: true,
36
- }
37
- );
41
+ await writeFileContent(context, serverModuleFilePath, serverModuleContent, {
42
+ force: true,
43
+ });
38
44
 
39
- const clientModuleFilePath = compConfig.importSpec.modulePath.replace(
40
- /\.tsx$/,
45
+ let clientModuleFilePath = compConfig.importSpec.modulePath.replace(
46
+ /\.(tsx|jsx)$/,
41
47
  "-client.tsx"
42
48
  );
49
+ let clientModuleContent = rscMetadata.pageWrappers.client.module;
50
+
51
+ if (context.config.code.lang === "js") {
52
+ const [convertedFileName, convertedContent] = await maybeConvertTsxToJsx(
53
+ clientModuleFilePath,
54
+ clientModuleContent
55
+ );
56
+ clientModuleFilePath = convertedFileName;
57
+ clientModuleContent = convertedContent;
58
+ }
59
+
43
60
  compConfig.rsc.clientModulePath = clientModuleFilePath;
44
61
 
45
62
  if (opts.shouldRegenerate) {
46
63
  await writeFileContent(
47
64
  context,
48
65
  clientModuleFilePath,
49
- rscMetadata.pageWrappers.client.module,
66
+ clientModuleContent,
50
67
  {
51
68
  force: false,
52
69
  }
@@ -1,15 +0,0 @@
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>;
@@ -1,38 +0,0 @@
1
- import pako from "pako";
2
- import { CommonArgs } from "..";
3
- import { readFileText } from "../utils/file-utils";
4
- import { getContext } from "../utils/get-context";
5
-
6
- export interface UploadBundleArgs extends CommonArgs {
7
- project: string;
8
- bundleName: string;
9
- bundleJsFile: string;
10
- cssFiles: readonly string[];
11
- metaJsonFile: string;
12
- genModulePath?: string;
13
- genCssPaths: string[];
14
- pkgVersion?: string;
15
- extraPropMetaJsonFile?: string;
16
- themeProviderWrapper?: string;
17
- themeModuleFile?: string;
18
- }
19
-
20
- export async function uploadJsBundle(opts: UploadBundleArgs) {
21
- const context = await getContext(opts);
22
- const api = context.api;
23
- await api.uploadBundle(
24
- opts.project,
25
- opts.bundleName,
26
- pako.deflate(readFileText(opts.bundleJsFile), { to: "string" }),
27
- opts.cssFiles.map((f) => pako.deflate(readFileText(f), { to: "string" })),
28
- pako.deflate(readFileText(opts.metaJsonFile), { to: "string" }),
29
- opts.genModulePath,
30
- opts.genCssPaths,
31
- opts.pkgVersion,
32
- opts.extraPropMetaJsonFile
33
- ? readFileText(opts.extraPropMetaJsonFile)
34
- : undefined,
35
- opts.themeProviderWrapper,
36
- opts.themeModuleFile ? readFileText(opts.themeModuleFile) : undefined
37
- );
38
- }