@plasmicapp/cli 0.1.335 → 0.1.337
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/api.d.ts +8 -2
- package/dist/index.js +35145 -36822
- package/dist/lib.js +35164 -36841
- package/dist/plasmic.schema.json +18 -0
- package/dist/utils/code-utils.d.ts +1 -0
- package/dist/utils/config-utils.d.ts +11 -0
- package/dist/utils/rsc-config.d.ts +5 -0
- package/package.json +2 -2
- package/src/actions/sync-components.ts +26 -1
- package/src/actions/sync.ts +3 -3
- package/src/api.ts +15 -2
- package/src/utils/code-utils.ts +93 -2
- package/src/utils/config-utils.ts +12 -0
- package/src/utils/file-utils.ts +8 -2
- package/src/utils/rsc-config.ts +56 -0
package/dist/plasmic.schema.json
CHANGED
|
@@ -112,6 +112,24 @@
|
|
|
112
112
|
"description": "The file path for the blackbox render module, relative to srcDir.",
|
|
113
113
|
"type": "string"
|
|
114
114
|
},
|
|
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.",
|
|
117
|
+
"properties": {
|
|
118
|
+
"clientModulePath": {
|
|
119
|
+
"description": "The client skeleton file",
|
|
120
|
+
"type": "string"
|
|
121
|
+
},
|
|
122
|
+
"serverModulePath": {
|
|
123
|
+
"description": "The server blackbox render module",
|
|
124
|
+
"type": "string"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"required": [
|
|
128
|
+
"clientModulePath",
|
|
129
|
+
"serverModulePath"
|
|
130
|
+
],
|
|
131
|
+
"type": "object"
|
|
132
|
+
},
|
|
115
133
|
"scheme": {
|
|
116
134
|
"description": "Code generation scheme used for this component",
|
|
117
135
|
"enum": [
|
|
@@ -36,3 +36,4 @@ export declare function fixAllImportStatements(context: PlasmicContext, baseDir:
|
|
|
36
36
|
export declare const tsxToJsx: (code: string) => string;
|
|
37
37
|
export declare function maybeConvertTsxToJsx(fileName: string, content: string, baseDir: string): string[];
|
|
38
38
|
export declare const formatScript: (code: string, baseDir: string) => string;
|
|
39
|
+
export declare function fixRscModulesImports(context: PlasmicContext, baseDir: string, fixImportContext: FixImportContext, compConfig: ComponentConfig): Promise<void>;
|
|
@@ -206,6 +206,17 @@ export interface ComponentConfig {
|
|
|
206
206
|
path?: string;
|
|
207
207
|
/** Plume type if component is a Plume component */
|
|
208
208
|
plumeType?: string;
|
|
209
|
+
/**
|
|
210
|
+
* RSC metadata for this component. The structure of the config changes when this is set:
|
|
211
|
+
* renderModuleFilePath points to the client blackbox render module.
|
|
212
|
+
* importSpec points to the server skeleton file.
|
|
213
|
+
*/
|
|
214
|
+
rsc?: {
|
|
215
|
+
/** The server blackbox render module */
|
|
216
|
+
serverModulePath: string;
|
|
217
|
+
/** The client skeleton file */
|
|
218
|
+
clientModulePath: string;
|
|
219
|
+
};
|
|
209
220
|
}
|
|
210
221
|
export interface IconConfig {
|
|
211
222
|
/** ID of icon */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { ComponentBundle } from "../api";
|
|
2
|
+
import { ComponentConfig, PlasmicContext, ProjectConfig } from "./config-utils";
|
|
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.
|
|
3
|
+
"version": "0.1.337",
|
|
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": "
|
|
86
|
+
"gitHead": "5dbcf9cb4a1be8f4060acbb9e3bdf698e99af7c6"
|
|
87
87
|
}
|
|
@@ -5,10 +5,10 @@ import { logger } from "../deps";
|
|
|
5
5
|
import { ComponentUpdateSummary, formatAsLocal } from "../utils/code-utils";
|
|
6
6
|
import {
|
|
7
7
|
CONFIG_FILE_NAME,
|
|
8
|
-
isPageAwarePlatform,
|
|
9
8
|
PlasmicContext,
|
|
10
9
|
ProjectConfig,
|
|
11
10
|
ProjectLock,
|
|
11
|
+
isPageAwarePlatform,
|
|
12
12
|
} from "../utils/config-utils";
|
|
13
13
|
import {
|
|
14
14
|
defaultPagePath,
|
|
@@ -21,6 +21,7 @@ import {
|
|
|
21
21
|
writeFileContent,
|
|
22
22
|
} from "../utils/file-utils";
|
|
23
23
|
import { assert, ensure } from "../utils/lang-utils";
|
|
24
|
+
import { syncRscFiles } from "../utils/rsc-config";
|
|
24
25
|
import { confirmWithUser } from "../utils/user-utils";
|
|
25
26
|
|
|
26
27
|
export async function syncProjectComponents(
|
|
@@ -231,6 +232,26 @@ export async function syncProjectComponents(
|
|
|
231
232
|
}
|
|
232
233
|
renameFile(context, compConfig.importSpec.modulePath, skeletonPath);
|
|
233
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
|
+
}
|
|
234
255
|
}
|
|
235
256
|
|
|
236
257
|
compConfig.plumeType = plumeType;
|
|
@@ -304,5 +325,9 @@ export async function syncProjectComponents(
|
|
|
304
325
|
);
|
|
305
326
|
}
|
|
306
327
|
summary.set(id, { skeletonModuleModified });
|
|
328
|
+
|
|
329
|
+
await syncRscFiles(context, project, bundle, compConfig, {
|
|
330
|
+
shouldRegenerate,
|
|
331
|
+
});
|
|
307
332
|
}
|
|
308
333
|
}
|
package/src/actions/sync.ts
CHANGED
|
@@ -22,11 +22,11 @@ import {
|
|
|
22
22
|
} from "../utils/code-utils";
|
|
23
23
|
import {
|
|
24
24
|
CONFIG_FILE_NAME,
|
|
25
|
-
createProjectConfig,
|
|
26
25
|
CustomFunctionConfig,
|
|
26
|
+
PlasmicContext,
|
|
27
|
+
createProjectConfig,
|
|
27
28
|
getOrAddProjectConfig,
|
|
28
29
|
getOrAddProjectLock,
|
|
29
|
-
PlasmicContext,
|
|
30
30
|
updateConfig,
|
|
31
31
|
} from "../utils/config-utils";
|
|
32
32
|
import { HandledError } from "../utils/error";
|
|
@@ -38,7 +38,7 @@ import {
|
|
|
38
38
|
withBufferedFs,
|
|
39
39
|
writeFileContent,
|
|
40
40
|
} from "../utils/file-utils";
|
|
41
|
-
import { generateMetadata, getContext
|
|
41
|
+
import { Metadata, generateMetadata, getContext } from "../utils/get-context";
|
|
42
42
|
import { printFirstSyncInfo } from "../utils/help";
|
|
43
43
|
import { ensure, tuple } from "../utils/lang-utils";
|
|
44
44
|
import {
|
package/src/api.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import axios, { AxiosError } from "axios";
|
|
2
|
-
import socketio
|
|
2
|
+
import socketio from "socket.io-client";
|
|
3
3
|
import {
|
|
4
4
|
AuthConfig,
|
|
5
5
|
CodeConfig,
|
|
@@ -33,6 +33,19 @@ export interface ComponentBundle {
|
|
|
33
33
|
isPage: boolean;
|
|
34
34
|
path?: string;
|
|
35
35
|
plumeType?: string;
|
|
36
|
+
rscMetadata?: {
|
|
37
|
+
// When we generate code for RSC, we generate two additional files per page, those files are used to increment the user experience,
|
|
38
|
+
// it's added one managed server file which is responsible for performing the server actions and one skeleton file which allows the
|
|
39
|
+
// user to add client side logic to the page (the `renderModule` will contain a server component for entry point allowing the user to
|
|
40
|
+
// perform additional server operations).
|
|
41
|
+
pageWrappers: Record<
|
|
42
|
+
"client" | "server",
|
|
43
|
+
{
|
|
44
|
+
module: string;
|
|
45
|
+
fileName: string;
|
|
46
|
+
}
|
|
47
|
+
>;
|
|
48
|
+
};
|
|
36
49
|
}
|
|
37
50
|
|
|
38
51
|
export interface GlobalVariantBundle {
|
|
@@ -440,7 +453,7 @@ export class PlasmicApi {
|
|
|
440
453
|
return result.data as ProjectIconsResponse;
|
|
441
454
|
}
|
|
442
455
|
|
|
443
|
-
connectSocket():
|
|
456
|
+
connectSocket(): ReturnType<typeof socketio> {
|
|
444
457
|
const socket = socketio(this.studioHost, {
|
|
445
458
|
path: `/api/v1/socket`,
|
|
446
459
|
transportOptions: {
|
package/src/utils/code-utils.ts
CHANGED
|
@@ -18,9 +18,9 @@ import { logger } from "../deps";
|
|
|
18
18
|
import { GLOBAL_SETTINGS } from "../globals";
|
|
19
19
|
import { HandledError } from "../utils/error";
|
|
20
20
|
import {
|
|
21
|
+
CONFIG_FILE_NAME,
|
|
21
22
|
CodeComponentConfig,
|
|
22
23
|
ComponentConfig,
|
|
23
|
-
CONFIG_FILE_NAME,
|
|
24
24
|
CustomFunctionConfig,
|
|
25
25
|
GlobalVariantGroupConfig,
|
|
26
26
|
IconConfig,
|
|
@@ -173,6 +173,8 @@ type PlasmicImportType =
|
|
|
173
173
|
| "globalContext"
|
|
174
174
|
| "customFunction"
|
|
175
175
|
| "splitsProvider"
|
|
176
|
+
| "rscClient"
|
|
177
|
+
| "rscServer"
|
|
176
178
|
| undefined;
|
|
177
179
|
|
|
178
180
|
const validJsIdentifierChars = [
|
|
@@ -201,7 +203,7 @@ function tryParsePlasmicImportSpec(node: ImportDeclaration) {
|
|
|
201
203
|
"plasmic-import:\\s+([",
|
|
202
204
|
...validJsIdentifierChars,
|
|
203
205
|
"\\.",
|
|
204
|
-
"]+)(?:\\/(component|css|render|globalVariant|projectcss|defaultcss|icon|picture|jsBundle|codeComponent|globalContext|customFunction|splitsProvider))?",
|
|
206
|
+
"]+)(?:\\/(component|css|render|globalVariant|projectcss|defaultcss|icon|picture|jsBundle|codeComponent|globalContext|customFunction|splitsProvider|rscClient|rscServer))?",
|
|
205
207
|
].join("")
|
|
206
208
|
)
|
|
207
209
|
);
|
|
@@ -439,6 +441,46 @@ export function replaceImports(
|
|
|
439
441
|
true
|
|
440
442
|
);
|
|
441
443
|
stmt.source.value = realPath;
|
|
444
|
+
} else if (type === "rscClient") {
|
|
445
|
+
const compConfig = fixImportContext.components[uuid];
|
|
446
|
+
if (!compConfig) {
|
|
447
|
+
throwMissingReference(context, "component", uuid, fromPath);
|
|
448
|
+
}
|
|
449
|
+
const clientModulePath = compConfig.rsc?.clientModulePath;
|
|
450
|
+
if (!clientModulePath) {
|
|
451
|
+
throw new HandledError(
|
|
452
|
+
`Encountered Plasmic component "${uuid}" that is missing a rscClientModulePath.`
|
|
453
|
+
);
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
stmt.source.value = makeImportPath(
|
|
457
|
+
context,
|
|
458
|
+
fromPath,
|
|
459
|
+
clientModulePath,
|
|
460
|
+
true
|
|
461
|
+
);
|
|
462
|
+
} else if (type === "rscServer") {
|
|
463
|
+
const compConfig = fixImportContext.components[uuid];
|
|
464
|
+
if (!compConfig) {
|
|
465
|
+
throwMissingReference(context, "component", uuid, fromPath);
|
|
466
|
+
}
|
|
467
|
+
const serverModulePath = compConfig.rsc?.serverModulePath;
|
|
468
|
+
if (!serverModulePath) {
|
|
469
|
+
throw new HandledError(
|
|
470
|
+
`Encountered Plasmic component "${uuid}" that is missing a rscServerModulePath.`
|
|
471
|
+
);
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
logger.info(
|
|
475
|
+
`Fixing "rscServer" with "${serverModulePath}" and from "${fromPath}"`
|
|
476
|
+
);
|
|
477
|
+
|
|
478
|
+
stmt.source.value = makeImportPath(
|
|
479
|
+
context,
|
|
480
|
+
fromPath,
|
|
481
|
+
serverModulePath,
|
|
482
|
+
true
|
|
483
|
+
);
|
|
442
484
|
}
|
|
443
485
|
});
|
|
444
486
|
|
|
@@ -569,6 +611,17 @@ export async function fixAllImportStatements(
|
|
|
569
611
|
let lastError: any = undefined;
|
|
570
612
|
for (const project of config.projects) {
|
|
571
613
|
for (const compConfig of project.components) {
|
|
614
|
+
try {
|
|
615
|
+
await fixRscModulesImports(
|
|
616
|
+
context,
|
|
617
|
+
baseDir,
|
|
618
|
+
fixImportContext,
|
|
619
|
+
compConfig
|
|
620
|
+
);
|
|
621
|
+
} catch (err) {
|
|
622
|
+
lastError = err;
|
|
623
|
+
}
|
|
624
|
+
|
|
572
625
|
const compSummary = summary?.get(compConfig.id);
|
|
573
626
|
if (summary && !compSummary) {
|
|
574
627
|
continue;
|
|
@@ -876,3 +929,41 @@ async function fixSplitsProviderImportStatements(
|
|
|
876
929
|
}
|
|
877
930
|
}
|
|
878
931
|
}
|
|
932
|
+
|
|
933
|
+
export async function fixRscModulesImports(
|
|
934
|
+
context: PlasmicContext,
|
|
935
|
+
baseDir: string,
|
|
936
|
+
fixImportContext: FixImportContext,
|
|
937
|
+
compConfig: ComponentConfig
|
|
938
|
+
) {
|
|
939
|
+
const errors: any[] = [];
|
|
940
|
+
|
|
941
|
+
for (const modulePath of [
|
|
942
|
+
compConfig.rsc?.clientModulePath,
|
|
943
|
+
compConfig.rsc?.serverModulePath,
|
|
944
|
+
]) {
|
|
945
|
+
if (!modulePath) {
|
|
946
|
+
continue;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
try {
|
|
950
|
+
await fixFileImportStatements(
|
|
951
|
+
context,
|
|
952
|
+
modulePath,
|
|
953
|
+
fixImportContext,
|
|
954
|
+
false,
|
|
955
|
+
baseDir
|
|
956
|
+
);
|
|
957
|
+
} catch (err) {
|
|
958
|
+
logger.error(
|
|
959
|
+
`Error encountered while fixing imports for rsc modules ${compConfig.name}: ${err}`
|
|
960
|
+
);
|
|
961
|
+
|
|
962
|
+
errors.push(err);
|
|
963
|
+
}
|
|
964
|
+
}
|
|
965
|
+
|
|
966
|
+
if (errors.length) {
|
|
967
|
+
throw errors[0];
|
|
968
|
+
}
|
|
969
|
+
}
|
|
@@ -288,6 +288,18 @@ export interface ComponentConfig {
|
|
|
288
288
|
|
|
289
289
|
/** Plume type if component is a Plume component */
|
|
290
290
|
plumeType?: string;
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* RSC metadata for this component. The structure of the config changes when this is set:
|
|
294
|
+
* renderModuleFilePath points to the client blackbox render module.
|
|
295
|
+
* importSpec points to the server skeleton file.
|
|
296
|
+
*/
|
|
297
|
+
rsc?: {
|
|
298
|
+
/** The server blackbox render module */
|
|
299
|
+
serverModulePath: string;
|
|
300
|
+
/** The client skeleton file */
|
|
301
|
+
clientModulePath: string;
|
|
302
|
+
};
|
|
291
303
|
}
|
|
292
304
|
|
|
293
305
|
export interface IconConfig {
|
package/src/utils/file-utils.ts
CHANGED
|
@@ -463,11 +463,18 @@ export function readFileText(path: string): string {
|
|
|
463
463
|
case "create":
|
|
464
464
|
return ensureString(action.content);
|
|
465
465
|
case "rename":
|
|
466
|
-
|
|
466
|
+
// eslint-disable-next-line no-restricted-properties
|
|
467
|
+
return fs.readFileSync(path, "utf8");
|
|
467
468
|
case "delete":
|
|
468
469
|
throw new HandledError("File does not exists");
|
|
469
470
|
}
|
|
470
471
|
}
|
|
472
|
+
// If we are buffering files and the file has been renamed, only the old file path
|
|
473
|
+
// exists in disk, so we need to read the content from the old file path.
|
|
474
|
+
const renamedFilePath = renamedFiles.get(path);
|
|
475
|
+
if (renamedFilePath) {
|
|
476
|
+
return readFileText(renamedFilePath);
|
|
477
|
+
}
|
|
471
478
|
}
|
|
472
479
|
|
|
473
480
|
// eslint-disable-next-line no-restricted-properties
|
|
@@ -503,7 +510,6 @@ export function renameFileBuffered(oldPath: string, newPath: string) {
|
|
|
503
510
|
if (renamedFile !== undefined) {
|
|
504
511
|
oldPath = renamedFile;
|
|
505
512
|
}
|
|
506
|
-
|
|
507
513
|
buffer.set(oldPath, { type: "rename", newPath });
|
|
508
514
|
renamedFiles.set(newPath, oldPath);
|
|
509
515
|
} else {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { ComponentBundle } from "../api";
|
|
2
|
+
import { ComponentConfig, PlasmicContext, ProjectConfig } from "./config-utils";
|
|
3
|
+
import { defaultResourcePath, writeFileContent } from "./file-utils";
|
|
4
|
+
|
|
5
|
+
export async function syncRscFiles(
|
|
6
|
+
context: PlasmicContext,
|
|
7
|
+
project: ProjectConfig,
|
|
8
|
+
bundle: ComponentBundle,
|
|
9
|
+
compConfig: ComponentConfig,
|
|
10
|
+
opts: {
|
|
11
|
+
shouldRegenerate: boolean;
|
|
12
|
+
}
|
|
13
|
+
) {
|
|
14
|
+
const rscMetadata = bundle.rscMetadata;
|
|
15
|
+
if (rscMetadata) {
|
|
16
|
+
if (!compConfig.rsc) {
|
|
17
|
+
compConfig.rsc = {
|
|
18
|
+
serverModulePath: "",
|
|
19
|
+
clientModulePath: "",
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const serverModuleFilePath = defaultResourcePath(
|
|
24
|
+
context,
|
|
25
|
+
project,
|
|
26
|
+
rscMetadata.pageWrappers.server.fileName
|
|
27
|
+
);
|
|
28
|
+
compConfig.rsc.serverModulePath = serverModuleFilePath;
|
|
29
|
+
|
|
30
|
+
await writeFileContent(
|
|
31
|
+
context,
|
|
32
|
+
serverModuleFilePath,
|
|
33
|
+
rscMetadata.pageWrappers.server.module,
|
|
34
|
+
{
|
|
35
|
+
force: true,
|
|
36
|
+
}
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const clientModuleFilePath = compConfig.importSpec.modulePath.replace(
|
|
40
|
+
/\.tsx$/,
|
|
41
|
+
"-client.tsx"
|
|
42
|
+
);
|
|
43
|
+
compConfig.rsc.clientModulePath = clientModuleFilePath;
|
|
44
|
+
|
|
45
|
+
if (opts.shouldRegenerate) {
|
|
46
|
+
await writeFileContent(
|
|
47
|
+
context,
|
|
48
|
+
clientModuleFilePath,
|
|
49
|
+
rscMetadata.pageWrappers.client.module,
|
|
50
|
+
{
|
|
51
|
+
force: false,
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}
|