@plasmicapp/cli 0.1.336 → 0.1.338

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
@@ -494564,6 +494564,9 @@ function makeImportPath(context, fromPath, toPath, stripExt, forceRelative = fal
494564
494564
  if (stripExt) {
494565
494565
  result = stripExtension(result);
494566
494566
  }
494567
+ if (result.endsWith(".css") && context.config.platform === "tanstack" && context.config.style.scheme === "css") {
494568
+ result = `${result}?url`;
494569
+ }
494567
494570
  return result;
494568
494571
  }
494569
494572
  function isLocalModulePath(modulePath) {
@@ -494878,7 +494881,6 @@ async function fixRscModulesImports(context, baseDir, fixImportContext, compConf
494878
494881
  if (!modulePath) {
494879
494882
  continue;
494880
494883
  }
494881
- logger.info(`Fixing rsc import statements... ${modulePath}`);
494882
494884
  try {
494883
494885
  await fixFileImportStatements(
494884
494886
  context,
@@ -494969,7 +494971,7 @@ function defaultPublicResourcePath(context, project, ...subpaths) {
494969
494971
  var INDEX_EXT_REGEXP = /\/index\.(jsx|tsx)$/;
494970
494972
  var EXT_REGEXP = /\.(jsx|tsx)$/;
494971
494973
  function defaultPagePath(context, fileName) {
494972
- var _a, _b, _c, _d;
494974
+ var _a, _b, _c, _d, _e;
494973
494975
  if (context.config.platform === "nextjs") {
494974
494976
  if ((_b = (_a = context.config.nextjsConfig) == null ? void 0 : _a.pagesDir) == null ? void 0 : _b.endsWith("app")) {
494975
494977
  const matchesIndex = fileName.match(INDEX_EXT_REGEXP);
@@ -494989,6 +494991,16 @@ function defaultPagePath(context, fileName) {
494989
494991
  }
494990
494992
  } else if (context.config.platform === "gatsby") {
494991
494993
  return import_upath3.default.join(((_d = context.config.gatsbyConfig) == null ? void 0 : _d.pagesDir) || "", fileName);
494994
+ } else if (context.config.platform === "tanstack") {
494995
+ let renamedFileName = fileName.replace(/\[(\w+)\]/g, "$$$1");
494996
+ const matchesIndex = fileName.match(INDEX_EXT_REGEXP);
494997
+ if (!matchesIndex) {
494998
+ renamedFileName = renamedFileName.replace(EXT_REGEXP, "/index.$1");
494999
+ }
495000
+ return import_upath3.default.join(
495001
+ ((_e = context.config.tanstackConfig) == null ? void 0 : _e.pagesDir) || "",
495002
+ renamedFileName
495003
+ );
494992
495004
  } else {
494993
495005
  return fileName;
494994
495006
  }
@@ -495135,6 +495147,9 @@ function getAllPaths(context) {
495135
495147
  if (config.nextjsConfig) {
495136
495148
  pushPath(config.nextjsConfig, "pagesDir");
495137
495149
  }
495150
+ if (config.tanstackConfig) {
495151
+ pushPath(config.tanstackConfig, "pagesDir");
495152
+ }
495138
495153
  return pairs;
495139
495154
  }
495140
495155
  function assertAllPathsInRootDir(context) {
@@ -495203,11 +495218,15 @@ function readFileText(path15) {
495203
495218
  case "create":
495204
495219
  return ensureString(action.content);
495205
495220
  case "rename":
495206
- return readFileText(action.newPath);
495221
+ return import_fs.default.readFileSync(path15, "utf8");
495207
495222
  case "delete":
495208
495223
  throw new HandledError("File does not exists");
495209
495224
  }
495210
495225
  }
495226
+ const renamedFilePath = renamedFiles.get(path15);
495227
+ if (renamedFilePath) {
495228
+ return readFileText(renamedFilePath);
495229
+ }
495211
495230
  }
495212
495231
  return import_fs.default.readFileSync(path15, "utf8");
495213
495232
  }
@@ -495629,7 +495648,7 @@ function getOrAddProjectLock(context, projectId, branchName, base) {
495629
495648
  return project;
495630
495649
  }
495631
495650
  function isPageAwarePlatform(platform) {
495632
- return platform === "nextjs" || platform === "gatsby";
495651
+ return platform === "nextjs" || platform === "gatsby" || platform === "tanstack";
495633
495652
  }
495634
495653
 
495635
495654
  // src/api.ts
@@ -496165,6 +496184,14 @@ function detectCreateReactApp() {
496165
496184
  return false;
496166
496185
  }
496167
496186
  }
496187
+ function detectTanStackApp() {
496188
+ try {
496189
+ const packageJsonContent = getParsedPackageJson();
496190
+ return "@tanstack/react-router" in packageJsonContent.dependencies;
496191
+ } catch {
496192
+ return false;
496193
+ }
496194
+ }
496168
496195
 
496169
496196
  // src/actions/init.ts
496170
496197
  async function initPlasmic(opts) {
@@ -496207,13 +496234,22 @@ function createInitConfig(opts) {
496207
496234
  pagesDir: opts.pagesDir
496208
496235
  }
496209
496236
  },
496237
+ ...opts.platform === "tanstack" && {
496238
+ tanstackConfig: {
496239
+ pagesDir: opts.pagesDir
496240
+ }
496241
+ },
496210
496242
  code: {
496211
496243
  ...opts.codeLang && { lang: opts.codeLang },
496212
496244
  ...opts.codeScheme && { scheme: opts.codeScheme },
496213
496245
  ...opts.reactRuntime && { reactRuntime: opts.reactRuntime }
496214
496246
  },
496215
496247
  style: {
496216
- ...opts.styleScheme && { scheme: opts.styleScheme }
496248
+ ...opts.styleScheme && {
496249
+ // Css Modules is not supported yet in SSR for TanStack
496250
+ // https://github.com/TanStack/router/issues/3023
496251
+ scheme: opts.platform === "tanstack" ? "css" : opts.styleScheme
496252
+ }
496217
496253
  },
496218
496254
  images: {
496219
496255
  ...opts.imagesScheme && { scheme: opts.imagesScheme },
@@ -496236,12 +496272,13 @@ function simulatePrompt(question, defaultAnswer, bold = false) {
496236
496272
  }
496237
496273
  async function deriveInitAnswers(opts) {
496238
496274
  const plasmicRootDir = opts.config ? import_upath5.default.dirname(opts.config) : opts.baseDir;
496239
- const platform = !!opts.platform ? opts.platform : detectNextJs() ? "nextjs" : detectGatsby() ? "gatsby" : detectCreateReactApp() ? "react" : "";
496275
+ const platform = !!opts.platform ? opts.platform : detectNextJs() ? "nextjs" : detectGatsby() ? "gatsby" : detectTanStackApp() ? "tanstack" : detectCreateReactApp() ? "react" : "";
496240
496276
  const isCra = platform === "react";
496241
496277
  const isNext = platform === "nextjs";
496242
496278
  const isNextAppDir = isNext && detectNextJsAppDir();
496243
496279
  const isGatsby = platform === "gatsby";
496244
- const isGeneric = !isCra && !isNext && !isGatsby;
496280
+ const isTanStack = platform === "tanstack";
496281
+ const isGeneric = !isCra && !isNext && !isGatsby && !isTanStack;
496245
496282
  const isTypescript = detectTypescript();
496246
496283
  if (isNext) {
496247
496284
  if (isNextAppDir) {
@@ -496251,10 +496288,12 @@ async function deriveInitAnswers(opts) {
496251
496288
  }
496252
496289
  } else if (isGatsby) {
496253
496290
  logger.info("Detected Gatsby...");
496291
+ } else if (isTanStack) {
496292
+ logger.info("Detected TanStack router app...");
496254
496293
  } else if (isCra) {
496255
496294
  logger.info("Detected create-react-app...");
496256
496295
  }
496257
- const deriver = isNext ? getNextDefaults(plasmicRootDir, isNextAppDir) : isGatsby ? getGatsbyDefaults(plasmicRootDir) : isCra ? getCraDefaults(plasmicRootDir) : getGenericDefaults(plasmicRootDir);
496296
+ const deriver = isNext ? getNextDefaults(plasmicRootDir, isNextAppDir) : isGatsby ? getGatsbyDefaults(plasmicRootDir) : isTanStack ? getTanStackDefaults(plasmicRootDir) : isCra ? getCraDefaults(plasmicRootDir) : getGenericDefaults(plasmicRootDir);
496258
496297
  const srcDir = ensureString(deriver.srcDir);
496259
496298
  const getDefaultAnswer = (name, defaultAnswer) => {
496260
496299
  if (opts[name]) {
@@ -496491,6 +496530,35 @@ function getGatsbyDefaults(plasmicRootDir) {
496491
496530
  alwaysDerived: ["imagesScheme", "pagesDir"]
496492
496531
  };
496493
496532
  }
496533
+ function getTanStackDefaults(plasmicRootDir) {
496534
+ var _a;
496535
+ const projectRootDir = (_a = findPackageJsonDir(plasmicRootDir)) != null ? _a : plasmicRootDir;
496536
+ return {
496537
+ srcDir: import_upath5.default.relative(
496538
+ plasmicRootDir,
496539
+ import_upath5.default.join(projectRootDir, "src", "components")
496540
+ ),
496541
+ pagesDir: (srcDir) => {
496542
+ const absSrcDir = import_upath5.default.join(plasmicRootDir, srcDir);
496543
+ const absPagesDir = import_upath5.default.join(projectRootDir, "src", "routes");
496544
+ const relDir = import_upath5.default.relative(absSrcDir, absPagesDir);
496545
+ return relDir;
496546
+ },
496547
+ styleScheme: "css",
496548
+ imagesScheme: "public-files",
496549
+ imagesPublicDir: (srcDir) => import_upath5.default.relative(
496550
+ import_upath5.default.join(plasmicRootDir, srcDir),
496551
+ import_upath5.default.join(projectRootDir, "public")
496552
+ ),
496553
+ imagesPublicUrlPrefix: "/",
496554
+ alwaysDerived: [
496555
+ "styleScheme",
496556
+ "imagesScheme",
496557
+ "imagesPublicDir",
496558
+ "pagesDir"
496559
+ ]
496560
+ };
496561
+ }
496494
496562
  function getCraDefaults(plasmicRootDir) {
496495
496563
  var _a;
496496
496564
  const projectRootDir = (_a = findPackageJsonDir(plasmicRootDir)) != null ? _a : plasmicRootDir;
@@ -496524,7 +496592,7 @@ var INIT_ARGS_DESCRIPTION = {
496524
496592
  platform: {
496525
496593
  shortDescription: "Target platform",
496526
496594
  longDescription: "Target platform to generate code for",
496527
- choices: ["react", "nextjs", "gatsby"]
496595
+ choices: ["react", "nextjs", "gatsby", "tanstack"]
496528
496596
  },
496529
496597
  codeLang: {
496530
496598
  shortDescription: "Target language",
@@ -497566,7 +497634,7 @@ var import_lodash15 = __toESM(require_lodash());
497566
497634
  var import_upath9 = __toESM(require_upath());
497567
497635
 
497568
497636
  // src/utils/rsc-config.ts
497569
- async function syncRscFiles(context, project, bundle, compConfig) {
497637
+ async function syncRscFiles(context, project, bundle, compConfig, opts) {
497570
497638
  const rscMetadata = bundle.rscMetadata;
497571
497639
  if (rscMetadata) {
497572
497640
  if (!compConfig.rsc) {
@@ -497594,19 +497662,22 @@ async function syncRscFiles(context, project, bundle, compConfig) {
497594
497662
  "-client.tsx"
497595
497663
  );
497596
497664
  compConfig.rsc.clientModulePath = clientModuleFilePath;
497597
- await writeFileContent(
497598
- context,
497599
- clientModuleFilePath,
497600
- rscMetadata.pageWrappers.client.module,
497601
- {
497602
- force: false
497603
- }
497604
- );
497665
+ if (opts.shouldRegenerate) {
497666
+ await writeFileContent(
497667
+ context,
497668
+ clientModuleFilePath,
497669
+ rscMetadata.pageWrappers.client.module,
497670
+ {
497671
+ force: false
497672
+ }
497673
+ );
497674
+ }
497605
497675
  }
497606
497676
  }
497607
497677
 
497608
497678
  // src/actions/sync-components.ts
497609
497679
  async function syncProjectComponents(context, project, version, componentBundles, forceOverwrite, summary, projectLock, checksums, baseDir) {
497680
+ var _a;
497610
497681
  const componentsFromChecksums = /* @__PURE__ */ new Set([
497611
497682
  ...checksums.cssRulesChecksums.map(([id, _]) => id),
497612
497683
  checksums.renderModuleChecksums.map(([id, _]) => id)
@@ -497765,6 +497836,23 @@ async function syncProjectComponents(context, project, version, componentBundles
497765
497836
  }
497766
497837
  renameFile(context, compConfig.importSpec.modulePath, skeletonPath);
497767
497838
  compConfig.importSpec.modulePath = skeletonPath;
497839
+ if (((_a = compConfig.rsc) == null ? void 0 : _a.clientModulePath) && fileExists(context, compConfig.rsc.clientModulePath)) {
497840
+ const clientModulePath = skeletonPath.replace(
497841
+ /\.tsx$/,
497842
+ "-client.tsx"
497843
+ );
497844
+ if (context.cliArgs.quiet !== true) {
497845
+ logger.info(
497846
+ `Renaming page file: ${compConfig.rsc.clientModulePath} -> ${clientModulePath} ['${project.projectName}' ${project.projectId}/${id} ${project.version}]`
497847
+ );
497848
+ }
497849
+ renameFile(
497850
+ context,
497851
+ compConfig.rsc.clientModulePath,
497852
+ clientModulePath
497853
+ );
497854
+ compConfig.rsc.clientModulePath = clientModulePath;
497855
+ }
497768
497856
  }
497769
497857
  compConfig.plumeType = plumeType;
497770
497858
  if (scheme === "direct") {
@@ -497832,7 +497920,9 @@ async function syncProjectComponents(context, project, version, componentBundles
497832
497920
  );
497833
497921
  }
497834
497922
  summary.set(id, { skeletonModuleModified });
497835
- await syncRscFiles(context, project, bundle, compConfig);
497923
+ await syncRscFiles(context, project, bundle, compConfig, {
497924
+ shouldRegenerate
497925
+ });
497836
497926
  }
497837
497927
  }
497838
497928
 
@@ -113,11 +113,14 @@
113
113
  "type": "string"
114
114
  },
115
115
  "rsc": {
116
+ "description": "RSC metadata for this component. The structure of the config changes when this is set:\nrenderModuleFilePath points to the client blackbox render module.\nimportSpec points to the server skeleton file.",
116
117
  "properties": {
117
118
  "clientModulePath": {
119
+ "description": "The client skeleton file",
118
120
  "type": "string"
119
121
  },
120
122
  "serverModulePath": {
123
+ "description": "The server blackbox render module",
121
124
  "type": "string"
122
125
  }
123
126
  },
@@ -565,7 +568,8 @@
565
568
  "enum": [
566
569
  "gatsby",
567
570
  "nextjs",
568
- "react"
571
+ "react",
572
+ "tanstack"
569
573
  ],
570
574
  "type": "string"
571
575
  },
@@ -591,6 +595,16 @@
591
595
  "$ref": "#/definitions/StyleConfig",
592
596
  "description": "Config for style generation"
593
597
  },
598
+ "tanstackConfig": {
599
+ "description": "Tanstack-specific config",
600
+ "properties": {
601
+ "pagesDir": {
602
+ "description": "The folder containing page components source files.",
603
+ "type": "string"
604
+ }
605
+ },
606
+ "type": "object"
607
+ },
594
608
  "tokens": {
595
609
  "$ref": "#/definitions/TokensConfig",
596
610
  "description": "Config for style tokens"
@@ -10,7 +10,7 @@ export declare const ENV_AUTH_USER = "PLASMIC_AUTH_USER";
10
10
  export declare const ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
11
11
  export interface PlasmicConfig {
12
12
  /** Target platform to generate code for */
13
- platform: "react" | "nextjs" | "gatsby";
13
+ platform: "react" | "nextjs" | "gatsby" | "tanstack";
14
14
  /**
15
15
  * The folder containing the component source files; this is the default place where
16
16
  * all files are generated and stored.
@@ -34,6 +34,11 @@ export interface PlasmicConfig {
34
34
  /** The folder containing page components source files. */
35
35
  pagesDir?: string;
36
36
  };
37
+ /** Tanstack-specific config */
38
+ tanstackConfig?: {
39
+ /** The folder containing page components source files. */
40
+ pagesDir?: string;
41
+ };
37
42
  /** Config for code generation */
38
43
  code: CodeConfig;
39
44
  /** Config for pictures */
@@ -206,8 +211,15 @@ export interface ComponentConfig {
206
211
  path?: string;
207
212
  /** Plume type if component is a Plume component */
208
213
  plumeType?: string;
214
+ /**
215
+ * RSC metadata for this component. The structure of the config changes when this is set:
216
+ * renderModuleFilePath points to the client blackbox render module.
217
+ * importSpec points to the server skeleton file.
218
+ */
209
219
  rsc?: {
220
+ /** The server blackbox render module */
210
221
  serverModulePath: string;
222
+ /** The client skeleton file */
211
223
  clientModulePath: string;
212
224
  };
213
225
  }
@@ -3,3 +3,4 @@ export declare function detectNextJs(): boolean;
3
3
  export declare function detectNextJsAppDir(): any;
4
4
  export declare function detectGatsby(): string | null;
5
5
  export declare function detectCreateReactApp(): boolean;
6
+ export declare function detectTanStackApp(): boolean;
@@ -9,7 +9,7 @@ export declare function writeFileContentRaw(filePath: string, content: string |
9
9
  export declare function defaultResourcePath(context: PlasmicContext, project: ProjectConfig | ProjectMetaBundle | string, ...subpaths: string[]): string;
10
10
  export declare function defaultPublicResourcePath(context: PlasmicContext, project: ProjectConfig, ...subpaths: string[]): string;
11
11
  export declare function defaultPagePath(context: {
12
- config: Pick<PlasmicConfig, "platform" | "gatsbyConfig" | "nextjsConfig">;
12
+ config: Pick<PlasmicConfig, "platform" | "gatsbyConfig" | "nextjsConfig" | "tanstackConfig">;
13
13
  }, fileName: string): string;
14
14
  /**
15
15
  * Returns true iff paths `a` and `b` resolve to the same page URI. For
@@ -1,3 +1,5 @@
1
1
  import { ComponentBundle } from "../api";
2
2
  import { ComponentConfig, PlasmicContext, ProjectConfig } from "./config-utils";
3
- export declare function syncRscFiles(context: PlasmicContext, project: ProjectConfig, bundle: ComponentBundle, compConfig: ComponentConfig): Promise<void>;
3
+ export declare function syncRscFiles(context: PlasmicContext, project: ProjectConfig, bundle: ComponentBundle, compConfig: ComponentConfig, opts: {
4
+ shouldRegenerate: boolean;
5
+ }): Promise<void>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@plasmicapp/cli",
3
- "version": "0.1.336",
3
+ "version": "0.1.338",
4
4
  "description": "plasmic cli for syncing local code with Plasmic designs",
5
5
  "engines": {
6
6
  "node": ">=12"
@@ -83,5 +83,5 @@
83
83
  "wrap-ansi": "^7.0.0",
84
84
  "yargs": "^15.4.1"
85
85
  },
86
- "gitHead": "e390ac2d296d887f8ed34f29fd85f21a315c35da"
86
+ "gitHead": "7199e5b0c2c94b6e95c81c8120d9861faf98d7ee"
87
87
  }
@@ -102,4 +102,51 @@ describe("defaultPagePath", () => {
102
102
  )
103
103
  ).toBe("../app/not-index/page.tsx");
104
104
  });
105
+ it("handles tanstack pagesDir", () => {
106
+ expect(
107
+ defaultPagePath(
108
+ {
109
+ config: {
110
+ platform: "tanstack",
111
+ tanstackConfig: { pagesDir: "../routes" },
112
+ },
113
+ },
114
+ "/index.tsx"
115
+ )
116
+ ).toBe("../routes/index.tsx");
117
+ expect(
118
+ defaultPagePath(
119
+ {
120
+ config: {
121
+ platform: "tanstack",
122
+ tanstackConfig: { pagesDir: "../routes" },
123
+ },
124
+ },
125
+ "/nested/index.tsx"
126
+ )
127
+ ).toBe("../routes/nested/index.tsx");
128
+
129
+ expect(
130
+ defaultPagePath(
131
+ {
132
+ config: {
133
+ platform: "tanstack",
134
+ tanstackConfig: { pagesDir: "../routes" },
135
+ },
136
+ },
137
+ "/post.tsx"
138
+ )
139
+ ).toBe("../routes/post/index.tsx");
140
+ expect(
141
+ defaultPagePath(
142
+ {
143
+ config: {
144
+ platform: "tanstack",
145
+ tanstackConfig: { pagesDir: "../routes" },
146
+ },
147
+ },
148
+ "/post/[postId].tsx"
149
+ )
150
+ ).toBe("../routes/post/$postId/index.tsx");
151
+ });
105
152
  });
@@ -24,7 +24,7 @@ import { DEFAULT_SPLITS_PROVIDER_NAME } from "./sync-splits-provider";
24
24
 
25
25
  export interface ExportArgs extends CommonArgs {
26
26
  projects: readonly string[];
27
- platform: "" | "react" | "nextjs" | "gatsby";
27
+ platform: "" | "react" | "nextjs" | "gatsby" | "tanstack";
28
28
  codeLang: "" | "ts" | "js";
29
29
  styleScheme: "" | "css" | "css-modules";
30
30
  imagesScheme: "" | "inlined" | "files";
@@ -20,6 +20,7 @@ import {
20
20
  detectGatsby,
21
21
  detectNextJs,
22
22
  detectNextJsAppDir,
23
+ detectTanStackApp,
23
24
  detectTypescript,
24
25
  } from "../utils/envdetect";
25
26
  import { existsBuffered } from "../utils/file-utils";
@@ -33,7 +34,7 @@ import { confirmWithUser } from "../utils/user-utils";
33
34
 
34
35
  export interface InitArgs extends CommonArgs {
35
36
  host: string;
36
- platform: "" | "react" | "nextjs" | "gatsby";
37
+ platform: "" | "react" | "nextjs" | "gatsby" | "tanstack";
37
38
  codeLang: "" | "ts" | "js";
38
39
  codeScheme: "" | "blackbox";
39
40
  styleScheme: "" | "css" | "css-modules";
@@ -97,13 +98,22 @@ function createInitConfig(opts: Omit<InitArgs, "baseDir">): PlasmicConfig {
97
98
  pagesDir: opts.pagesDir,
98
99
  },
99
100
  }),
101
+ ...(opts.platform === "tanstack" && {
102
+ tanstackConfig: {
103
+ pagesDir: opts.pagesDir,
104
+ },
105
+ }),
100
106
  code: {
101
107
  ...(opts.codeLang && { lang: opts.codeLang }),
102
108
  ...(opts.codeScheme && { scheme: opts.codeScheme }),
103
109
  ...(opts.reactRuntime && { reactRuntime: opts.reactRuntime }),
104
110
  },
105
111
  style: {
106
- ...(opts.styleScheme && { scheme: opts.styleScheme }),
112
+ ...(opts.styleScheme && {
113
+ // Css Modules is not supported yet in SSR for TanStack
114
+ // https://github.com/TanStack/router/issues/3023
115
+ scheme: opts.platform === "tanstack" ? "css" : opts.styleScheme,
116
+ }),
107
117
  },
108
118
  images: {
109
119
  ...(opts.imagesScheme && { scheme: opts.imagesScheme }),
@@ -165,6 +175,8 @@ async function deriveInitAnswers(
165
175
  ? "nextjs"
166
176
  : detectGatsby()
167
177
  ? "gatsby"
178
+ : detectTanStackApp()
179
+ ? "tanstack"
168
180
  : detectCreateReactApp()
169
181
  ? "react"
170
182
  : "";
@@ -172,7 +184,8 @@ async function deriveInitAnswers(
172
184
  const isNext = platform === "nextjs";
173
185
  const isNextAppDir = isNext && detectNextJsAppDir();
174
186
  const isGatsby = platform === "gatsby";
175
- const isGeneric = !isCra && !isNext && !isGatsby;
187
+ const isTanStack = platform === "tanstack";
188
+ const isGeneric = !isCra && !isNext && !isGatsby && !isTanStack;
176
189
  const isTypescript = detectTypescript();
177
190
 
178
191
  if (isNext) {
@@ -183,6 +196,8 @@ async function deriveInitAnswers(
183
196
  }
184
197
  } else if (isGatsby) {
185
198
  logger.info("Detected Gatsby...");
199
+ } else if (isTanStack) {
200
+ logger.info("Detected TanStack router app...");
186
201
  } else if (isCra) {
187
202
  logger.info("Detected create-react-app...");
188
203
  }
@@ -192,6 +207,8 @@ async function deriveInitAnswers(
192
207
  ? getNextDefaults(plasmicRootDir, isNextAppDir)
193
208
  : isGatsby
194
209
  ? getGatsbyDefaults(plasmicRootDir)
210
+ : isTanStack
211
+ ? getTanStackDefaults(plasmicRootDir)
195
212
  : isCra
196
213
  ? getCraDefaults(plasmicRootDir)
197
214
  : getGenericDefaults(plasmicRootDir);
@@ -473,6 +490,36 @@ function getGatsbyDefaults(plasmicRootDir: string): DefaultDeriver {
473
490
  };
474
491
  }
475
492
 
493
+ function getTanStackDefaults(plasmicRootDir: string): DefaultDeriver {
494
+ const projectRootDir = findPackageJsonDir(plasmicRootDir) ?? plasmicRootDir;
495
+ return {
496
+ srcDir: path.relative(
497
+ plasmicRootDir,
498
+ path.join(projectRootDir, "src", "components")
499
+ ),
500
+ pagesDir: (srcDir: string) => {
501
+ const absSrcDir = path.join(plasmicRootDir, srcDir);
502
+ const absPagesDir = path.join(projectRootDir, "src", "routes");
503
+ const relDir = path.relative(absSrcDir, absPagesDir);
504
+ return relDir;
505
+ },
506
+ styleScheme: "css",
507
+ imagesScheme: "public-files",
508
+ imagesPublicDir: (srcDir: string) =>
509
+ path.relative(
510
+ path.join(plasmicRootDir, srcDir),
511
+ path.join(projectRootDir, "public")
512
+ ),
513
+ imagesPublicUrlPrefix: "/",
514
+ alwaysDerived: [
515
+ "styleScheme",
516
+ "imagesScheme",
517
+ "imagesPublicDir",
518
+ "pagesDir",
519
+ ],
520
+ };
521
+ }
522
+
476
523
  function getCraDefaults(plasmicRootDir: string): DefaultDeriver {
477
524
  const projectRootDir = findPackageJsonDir(plasmicRootDir) ?? plasmicRootDir;
478
525
  return {
@@ -519,7 +566,7 @@ const INIT_ARGS_DESCRIPTION: {
519
566
  platform: {
520
567
  shortDescription: "Target platform",
521
568
  longDescription: "Target platform to generate code for",
522
- choices: ["react", "nextjs", "gatsby"],
569
+ choices: ["react", "nextjs", "gatsby", "tanstack"],
523
570
  },
524
571
  codeLang: {
525
572
  shortDescription: "Target language",
@@ -232,6 +232,26 @@ export async function syncProjectComponents(
232
232
  }
233
233
  renameFile(context, compConfig.importSpec.modulePath, skeletonPath);
234
234
  compConfig.importSpec.modulePath = skeletonPath;
235
+ if (
236
+ compConfig.rsc?.clientModulePath &&
237
+ fileExists(context, compConfig.rsc.clientModulePath)
238
+ ) {
239
+ const clientModulePath = skeletonPath.replace(
240
+ /\.tsx$/,
241
+ "-client.tsx"
242
+ );
243
+ if (context.cliArgs.quiet !== true) {
244
+ logger.info(
245
+ `Renaming page file: ${compConfig.rsc.clientModulePath} -> ${clientModulePath}\t['${project.projectName}' ${project.projectId}/${id} ${project.version}]`
246
+ );
247
+ }
248
+ renameFile(
249
+ context,
250
+ compConfig.rsc.clientModulePath,
251
+ clientModulePath
252
+ );
253
+ compConfig.rsc.clientModulePath = clientModulePath;
254
+ }
235
255
  }
236
256
 
237
257
  compConfig.plumeType = plumeType;
@@ -306,6 +326,8 @@ export async function syncProjectComponents(
306
326
  }
307
327
  summary.set(id, { skeletonModuleModified });
308
328
 
309
- await syncRscFiles(context, project, bundle, compConfig);
329
+ await syncRscFiles(context, project, bundle, compConfig, {
330
+ shouldRegenerate,
331
+ });
310
332
  }
311
333
  }
@@ -528,6 +528,16 @@ function makeImportPath(
528
528
  if (stripExt) {
529
529
  result = stripExtension(result);
530
530
  }
531
+
532
+ if (
533
+ result.endsWith(".css") &&
534
+ context.config.platform === "tanstack" &&
535
+ context.config.style.scheme === "css"
536
+ ) {
537
+ // In Tanstack we import css as url such as ".css?url" at the moment
538
+ result = `${result}?url`;
539
+ }
540
+
531
541
  return result;
532
542
  }
533
543
 
@@ -946,8 +956,6 @@ export async function fixRscModulesImports(
946
956
  continue;
947
957
  }
948
958
 
949
- logger.info(`Fixing rsc import statements... ${modulePath}`);
950
-
951
959
  try {
952
960
  await fixFileImportStatements(
953
961
  context,
@@ -27,7 +27,7 @@ export const ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
27
27
 
28
28
  export interface PlasmicConfig {
29
29
  /** Target platform to generate code for */
30
- platform: "react" | "nextjs" | "gatsby";
30
+ platform: "react" | "nextjs" | "gatsby" | "tanstack";
31
31
 
32
32
  /**
33
33
  * The folder containing the component source files; this is the default place where
@@ -56,6 +56,12 @@ export interface PlasmicConfig {
56
56
  pagesDir?: string;
57
57
  };
58
58
 
59
+ /** Tanstack-specific config */
60
+ tanstackConfig?: {
61
+ /** The folder containing page components source files. */
62
+ pagesDir?: string;
63
+ };
64
+
59
65
  /** Config for code generation */
60
66
  code: CodeConfig;
61
67
 
@@ -289,8 +295,15 @@ export interface ComponentConfig {
289
295
  /** Plume type if component is a Plume component */
290
296
  plumeType?: string;
291
297
 
298
+ /**
299
+ * RSC metadata for this component. The structure of the config changes when this is set:
300
+ * renderModuleFilePath points to the client blackbox render module.
301
+ * importSpec points to the server skeleton file.
302
+ */
292
303
  rsc?: {
304
+ /** The server blackbox render module */
293
305
  serverModulePath: string;
306
+ /** The client skeleton file */
294
307
  clientModulePath: string;
295
308
  };
296
309
  }
@@ -629,5 +642,7 @@ export function getOrAddProjectLock(
629
642
  }
630
643
 
631
644
  export function isPageAwarePlatform(platform: string): boolean {
632
- return platform === "nextjs" || platform === "gatsby";
645
+ return (
646
+ platform === "nextjs" || platform === "gatsby" || platform === "tanstack"
647
+ );
633
648
  }