@plasmicapp/cli 0.1.162

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 (162) hide show
  1. package/.eslintrc.js +61 -0
  2. package/.idea/cli.iml +11 -0
  3. package/.idea/misc.xml +6 -0
  4. package/.idea/modules.xml +8 -0
  5. package/.idea/vcs.xml +6 -0
  6. package/README +16 -0
  7. package/README.internal +46 -0
  8. package/README.md +17 -0
  9. package/build.sh +8 -0
  10. package/dist/__mocks__/api.d.ts +16 -0
  11. package/dist/__mocks__/api.js +297 -0
  12. package/dist/__tests__/code-utils-spec.d.ts +1 -0
  13. package/dist/__tests__/code-utils-spec.js +838 -0
  14. package/dist/__tests__/ftue-spec.d.ts +1 -0
  15. package/dist/__tests__/ftue-spec.js +39 -0
  16. package/dist/__tests__/project-api-token-spec.d.ts +1 -0
  17. package/dist/__tests__/project-api-token-spec.js +147 -0
  18. package/dist/__tests__/versioned-sync-spec.d.ts +1 -0
  19. package/dist/__tests__/versioned-sync-spec.js +145 -0
  20. package/dist/actions/auth.d.ts +8 -0
  21. package/dist/actions/auth.js +47 -0
  22. package/dist/actions/fix-imports.d.ts +4 -0
  23. package/dist/actions/fix-imports.js +25 -0
  24. package/dist/actions/init.d.ts +62 -0
  25. package/dist/actions/init.js +460 -0
  26. package/dist/actions/project-token.d.ts +6 -0
  27. package/dist/actions/project-token.js +42 -0
  28. package/dist/actions/sync-components.d.ts +10 -0
  29. package/dist/actions/sync-components.js +242 -0
  30. package/dist/actions/sync-global-variants.d.ts +3 -0
  31. package/dist/actions/sync-global-variants.js +89 -0
  32. package/dist/actions/sync-icons.d.ts +7 -0
  33. package/dist/actions/sync-icons.js +92 -0
  34. package/dist/actions/sync-images.d.ts +6 -0
  35. package/dist/actions/sync-images.js +137 -0
  36. package/dist/actions/sync-styles.d.ts +3 -0
  37. package/dist/actions/sync-styles.js +58 -0
  38. package/dist/actions/sync.d.ts +25 -0
  39. package/dist/actions/sync.js +417 -0
  40. package/dist/actions/upload-bundle.d.ts +15 -0
  41. package/dist/actions/upload-bundle.js +28 -0
  42. package/dist/actions/watch.d.ts +14 -0
  43. package/dist/actions/watch.js +90 -0
  44. package/dist/api.d.ts +182 -0
  45. package/dist/api.js +202 -0
  46. package/dist/deps.d.ts +2 -0
  47. package/dist/deps.js +20 -0
  48. package/dist/index.d.ts +7 -0
  49. package/dist/index.js +247 -0
  50. package/dist/lib.d.ts +10 -0
  51. package/dist/lib.js +23 -0
  52. package/dist/migrations/0.1.110-fileLocks.d.ts +2 -0
  53. package/dist/migrations/0.1.110-fileLocks.js +15 -0
  54. package/dist/migrations/0.1.143-ensureImportModuleType.d.ts +2 -0
  55. package/dist/migrations/0.1.143-ensureImportModuleType.js +12 -0
  56. package/dist/migrations/0.1.146-addReactRuntime.d.ts +2 -0
  57. package/dist/migrations/0.1.146-addReactRuntime.js +10 -0
  58. package/dist/migrations/0.1.27-migrateInit.d.ts +1 -0
  59. package/dist/migrations/0.1.27-migrateInit.js +8 -0
  60. package/dist/migrations/0.1.28-tsToTsx.d.ts +3 -0
  61. package/dist/migrations/0.1.28-tsToTsx.js +33 -0
  62. package/dist/migrations/0.1.31-ensureProjectIcons.d.ts +2 -0
  63. package/dist/migrations/0.1.31-ensureProjectIcons.js +12 -0
  64. package/dist/migrations/0.1.42-ensureVersion.d.ts +2 -0
  65. package/dist/migrations/0.1.42-ensureVersion.js +12 -0
  66. package/dist/migrations/0.1.57-ensureJsBundleThemes.d.ts +2 -0
  67. package/dist/migrations/0.1.57-ensureJsBundleThemes.js +12 -0
  68. package/dist/migrations/0.1.64-imageFiles.d.ts +2 -0
  69. package/dist/migrations/0.1.64-imageFiles.js +17 -0
  70. package/dist/migrations/0.1.95-componentType.d.ts +2 -0
  71. package/dist/migrations/0.1.95-componentType.js +16 -0
  72. package/dist/migrations/migrations.d.ts +10 -0
  73. package/dist/migrations/migrations.js +119 -0
  74. package/dist/plasmic.schema.json +463 -0
  75. package/dist/test-common/fixtures.d.ts +13 -0
  76. package/dist/test-common/fixtures.js +165 -0
  77. package/dist/tsconfig-transform.json +68 -0
  78. package/dist/utils/auth-utils.d.ts +31 -0
  79. package/dist/utils/auth-utils.js +236 -0
  80. package/dist/utils/checksum.d.ts +4 -0
  81. package/dist/utils/checksum.js +63 -0
  82. package/dist/utils/code-utils.d.ts +46 -0
  83. package/dist/utils/code-utils.js +457 -0
  84. package/dist/utils/config-utils.d.ts +271 -0
  85. package/dist/utils/config-utils.js +178 -0
  86. package/dist/utils/envdetect.d.ts +4 -0
  87. package/dist/utils/envdetect.js +42 -0
  88. package/dist/utils/error.d.ts +14 -0
  89. package/dist/utils/error.js +42 -0
  90. package/dist/utils/file-utils.d.ts +71 -0
  91. package/dist/utils/file-utils.js +433 -0
  92. package/dist/utils/get-context.d.ts +40 -0
  93. package/dist/utils/get-context.js +339 -0
  94. package/dist/utils/help.d.ts +2 -0
  95. package/dist/utils/help.js +56 -0
  96. package/dist/utils/lang-utils.d.ts +10 -0
  97. package/dist/utils/lang-utils.js +52 -0
  98. package/dist/utils/npm-utils.d.ts +28 -0
  99. package/dist/utils/npm-utils.js +215 -0
  100. package/dist/utils/prompts.d.ts +6 -0
  101. package/dist/utils/prompts.js +23 -0
  102. package/dist/utils/resolve-utils.d.ts +13 -0
  103. package/dist/utils/resolve-utils.js +198 -0
  104. package/dist/utils/semver.d.ts +34 -0
  105. package/dist/utils/semver.js +61 -0
  106. package/dist/utils/test-utils.d.ts +22 -0
  107. package/dist/utils/test-utils.js +106 -0
  108. package/dist/utils/user-utils.d.ts +7 -0
  109. package/dist/utils/user-utils.js +48 -0
  110. package/jest.config.js +6 -0
  111. package/package.json +80 -0
  112. package/src/__mocks__/api.ts +394 -0
  113. package/src/__tests__/code-utils-spec.ts +881 -0
  114. package/src/__tests__/ftue-spec.ts +43 -0
  115. package/src/__tests__/project-api-token-spec.ts +208 -0
  116. package/src/__tests__/versioned-sync-spec.ts +176 -0
  117. package/src/actions/auth.ts +43 -0
  118. package/src/actions/fix-imports.ts +13 -0
  119. package/src/actions/init.ts +638 -0
  120. package/src/actions/project-token.ts +36 -0
  121. package/src/actions/sync-components.ts +405 -0
  122. package/src/actions/sync-global-variants.ts +129 -0
  123. package/src/actions/sync-icons.ts +135 -0
  124. package/src/actions/sync-images.ts +191 -0
  125. package/src/actions/sync-styles.ts +71 -0
  126. package/src/actions/sync.ts +747 -0
  127. package/src/actions/upload-bundle.ts +38 -0
  128. package/src/actions/watch.ts +95 -0
  129. package/src/api.ts +407 -0
  130. package/src/deps.ts +18 -0
  131. package/src/index.ts +300 -0
  132. package/src/lib.ts +10 -0
  133. package/src/migrations/0.1.110-fileLocks.ts +16 -0
  134. package/src/migrations/0.1.146-addReactRuntime.ts +8 -0
  135. package/src/migrations/0.1.27-migrateInit.ts +4 -0
  136. package/src/migrations/0.1.28-tsToTsx.ts +37 -0
  137. package/src/migrations/0.1.31-ensureProjectIcons.ts +10 -0
  138. package/src/migrations/0.1.42-ensureVersion.ts +10 -0
  139. package/src/migrations/0.1.57-ensureJsBundleThemes.ts +10 -0
  140. package/src/migrations/0.1.64-imageFiles.ts +15 -0
  141. package/src/migrations/0.1.95-componentType.ts +14 -0
  142. package/src/migrations/migrations.ts +147 -0
  143. package/src/test-common/fixtures.ts +178 -0
  144. package/src/utils/auth-utils.ts +276 -0
  145. package/src/utils/checksum.ts +106 -0
  146. package/src/utils/code-utils.ts +656 -0
  147. package/src/utils/config-utils.ts +551 -0
  148. package/src/utils/envdetect.ts +39 -0
  149. package/src/utils/error.ts +36 -0
  150. package/src/utils/file-utils.ts +526 -0
  151. package/src/utils/get-context.ts +451 -0
  152. package/src/utils/help.ts +75 -0
  153. package/src/utils/lang-utils.ts +52 -0
  154. package/src/utils/npm-utils.ts +223 -0
  155. package/src/utils/prompts.ts +22 -0
  156. package/src/utils/resolve-utils.ts +245 -0
  157. package/src/utils/semver.ts +67 -0
  158. package/src/utils/test-utils.ts +116 -0
  159. package/src/utils/user-utils.ts +37 -0
  160. package/testData/fixImports_plasmic.json +66 -0
  161. package/tsconfig-transform.json +68 -0
  162. package/tsconfig.json +67 -0
@@ -0,0 +1,881 @@
1
+ import {
2
+ formatScript,
3
+ mkFixImportContext,
4
+ replaceImports,
5
+ tsxToJsx,
6
+ } from "../utils/code-utils";
7
+ import { readFileText } from "../utils/file-utils";
8
+
9
+ describe("code-utils", function () {
10
+ it("typescript to javascript should work", function () {
11
+ const code = `
12
+ // This is a skeleton starter React component generated by Plasmic.
13
+ // @jsx helper
14
+ import React, { ReactNode } from "react";
15
+ import {
16
+ PlasmicCodeSandboxDialogContent__RenderHelper,
17
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
18
+ PlasmicCodeSandboxDialogContent__ArgsType,
19
+ PlasmicCodeSandboxDialogContent__VariantsType,
20
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
21
+ } from "./PP__CodeSandboxDialogContent"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
22
+
23
+ import Button from "../Button"; // plasmic-import: 4SYnkOQLd5/component
24
+ import { PlasmicButton__VariantsArgs } from "../../../plasmic/PlasmicButton"; // plasmic-import: 4SYnkOQLd5/renderer
25
+ import Dropdown from "./Dropdown"; // plasmic-import: a200b79f-288d-4306-be99-e5fd221b8ba6/component
26
+ import { PlasmicDropdown__VariantsArgs } from "./PP__Dropdown"; // plasmic-import: a200b79f-288d-4306-be99-e5fd221b8ba6/renderer
27
+ import DropdownItem from "./DropdownItem"; // plasmic-import: f4c2f0bb-8dce-49c7-a106-65abe9e70e51/component
28
+ import { PlasmicDropdownItem__VariantsArgs } from "./PP__DropdownItem"; // plasmic-import: f4c2f0bb-8dce-49c7-a106-65abe9e70e51/renderer
29
+ import IconButton from "../../IconButton"; // plasmic-import: cfe92-5RW/component
30
+ import { PlasmicIconButton__VariantsArgs } from "../../../plasmic/PlasmicIconButton"; // plasmic-import: cfe92-5RW/renderer
31
+ import { hasVariant, DefaultFlexStack, FlexStack } from "@plasmicapp/react-web";
32
+ import { StudioCtx } from "../../../StudioCtx";
33
+ import { ensure, asOne, isValidEmail } from "../../../../common";
34
+ import { CodeSandboxInfo } from "../../../../shared/db-json-blobs";
35
+ import { createSandboxUrl } from "../../../../codesandbox/url";
36
+ import { Tooltip } from "antd";
37
+ import { observer } from "mobx-react-lite";
38
+
39
+ interface CodeSandboxDialogContentProps {
40
+ sc: StudioCtx;
41
+ onClose: () => void;
42
+
43
+ // Required className prop is used for positioning this component
44
+ className?: string;
45
+ }
46
+
47
+ function _CodeSandboxDialogContent(props: CodeSandboxDialogContentProps) {
48
+ const sc = props.sc;
49
+ const [inviting, setInviting] = React.useState(false);
50
+ const [submitting, setSubmitting] = React.useState(false);
51
+ const [email, setEmail] = React.useState("");
52
+ const [sandboxInfo, setSandboxInfo] = React.useState<
53
+ CodeSandboxInfo | undefined
54
+ >(asOne(sc.siteInfo.codeSandboxInfos));
55
+ const [codeScheme, setCodeScheme] = React.useState<"blackbox" | "direct">(
56
+ sandboxInfo ? sandboxInfo.code.scheme : "blackbox"
57
+ );
58
+
59
+ const openSandboxPopup = (sandboxId: string) => {
60
+ const url = createSandboxUrl({ id: sandboxId });
61
+ if (sc.popupCodesandboxWindow && !sc.popupCodesandboxWindow.closed) {
62
+ sc.popupCodesandboxWindow.location.href = url;
63
+ sc.popupCodesandboxWindow.focus();
64
+ } else {
65
+ sc.popupCodesandboxWindow = window.open(url);
66
+ }
67
+ };
68
+
69
+ const onCreateOrUpdateSandbox = async () => {
70
+ setSubmitting(true);
71
+ const { id } = await sc.appCtx.api.publishCodeSandbox(
72
+ sc.siteInfo.id,
73
+ sandboxInfo
74
+ ? { ...sandboxInfo }
75
+ : { code: { lang: "ts", scheme: codeScheme } }
76
+ );
77
+
78
+ await sc.refreshSiteInfo();
79
+ setSubmitting(false);
80
+ setSandboxInfo((sc.siteInfo.codeSandboxInfos || []).find(x => x.id === id));
81
+ openSandboxPopup(id);
82
+ };
83
+
84
+ const onInvite = () => {
85
+ setInviting(true);
86
+ sc.appCtx.api
87
+ .shareCodeSandbox(sc.siteInfo.id, ensure(sandboxInfo).id, email)
88
+ .then(() => {
89
+ setInviting(false);
90
+ });
91
+ setEmail("");
92
+ };
93
+
94
+ const onSwitchCodeScheme = (scheme: "blackbox" | "direct") => {
95
+ setCodeScheme(scheme);
96
+ setSandboxInfo(
97
+ (sc.siteInfo.codeSandboxInfos || []).find(x => x.code.scheme === scheme)
98
+ );
99
+ };
100
+
101
+ const onDeleteSandbox = async () => {
102
+ setSubmitting(true);
103
+ await sc.appCtx.api.detachCodeSandbox(
104
+ sc.siteInfo.id,
105
+ ensure(sandboxInfo).id
106
+ );
107
+
108
+ await sc.refreshSiteInfo();
109
+ setSubmitting(false);
110
+ setSandboxInfo(undefined);
111
+ };
112
+
113
+ const variants: PlasmicCodeSandboxDialogContent__VariantsArgs = {
114
+ state: inviting ? "inviting" : submitting ? "submitting" : undefined,
115
+ hasSandbox: !!sandboxInfo ? "yes" : "no",
116
+ invalidEmail: !isValidEmail(email) ? "yes" : undefined,
117
+ canEdit: !sc.canEditProject() ? "no" : undefined,
118
+ scheme: codeScheme === "direct" ? "direct" : "blackbox"
119
+ };
120
+
121
+ const args: PlasmicCodeSandboxDialogContent__ArgsType = {};
122
+
123
+ // The following code block is fully managed by Plasmic. Don't edit - it will
124
+ // be overwritten after every "plasmic sync".
125
+ // plasmic-managed-start
126
+
127
+ const rh = new PlasmicCodeSandboxDialogContent__RenderHelper(
128
+ variants,
129
+ args,
130
+ props.className
131
+ );
132
+
133
+ // plasmic-managed-end
134
+
135
+ // plasmic-managed-jsx/5487
136
+ return (
137
+ <div className={rh.clsRoot()}>
138
+ <div className={rh.clsF7050e55$eea1$41ab$9682$db9ad8d08cb1()}>
139
+ <div className={rh.cls70032be2$1620$48b3$ba29$c027e30b7907()}>
140
+ CodeSandbox
141
+ </div>
142
+ <DefaultFlexStack className={rh.cls8oFaZaiIX()}>
143
+ {rh.showOpenButton() && (
144
+ <Button
145
+ startIcon={
146
+ <img className={rh.cls$qzB2zcT8()} {...rh.props$qzB2zcT8()} />
147
+ }
148
+ {...rh.propsOpenButton()}
149
+ onClick={() => openSandboxPopup(ensure(sandboxInfo).id)}
150
+ >
151
+ Open in new tab
152
+ </Button>
153
+ )}
154
+
155
+ <img
156
+ className={rh.clsCloseButton()}
157
+ {...rh.propsCloseButton()}
158
+ onClick={props.onClose}
159
+ />
160
+ </DefaultFlexStack>
161
+ </div>
162
+ <div className={rh.cls43fcb29a$5286$4b5a$8593$49b737cdd7b0()} />
163
+ <DefaultFlexStack className={rh.clsWL8ypAgbq()}>
164
+ <div className={rh.clsTmQlfUKwS()}>Code scheme</div>
165
+ <Dropdown
166
+ {...rh.propsCodeSchemeDropdown()}
167
+ selectedValue={rh.childStrCodeSchemeDropdown()}
168
+ items={
169
+ <>
170
+ <DropdownItem
171
+ {...rh.propsBlackBoxOption()}
172
+ value={"Blackbox Library"}
173
+ selected={codeScheme === "blackbox"}
174
+ onSelected={() => onSwitchCodeScheme("blackbox")}
175
+ />
176
+
177
+ <DropdownItem
178
+ {...rh.propsPlainReactOption()}
179
+ value={"Direct Edit"}
180
+ selected={codeScheme === "direct"}
181
+ onSelected={() => onSwitchCodeScheme("direct")}
182
+ />
183
+ </>
184
+ }
185
+ />
186
+ </DefaultFlexStack>
187
+ <div className={rh.clsH1u3gI8vG()}>{rh.childStrH1u3gI8vG()}</div>
188
+ {rh.showCreateHint() && (
189
+ <div className={rh.clsCreateHint()}>
190
+ {rh.showCreateHint2() && (
191
+ <div className={rh.clsCreateHint2()}>
192
+ {rh.childStrCreateHint2()}
193
+ </div>
194
+ )}
195
+ </div>
196
+ )}
197
+
198
+ {rh.showCreateButton() && (
199
+ <Button
200
+ startIcon={
201
+ <img className={rh.clsGvtJoBerl()} {...rh.propsGvtJoBerl()} />
202
+ }
203
+ {...rh.propsCreateButton()}
204
+ onClick={onCreateOrUpdateSandbox}
205
+ >
206
+ {rh.childStrCreateButton()}
207
+ </Button>
208
+ )}
209
+
210
+ {rh.showUpdateHint() && (
211
+ <div className={rh.clsUpdateHint()}>
212
+ <div className={rh.clsCreateHint22()}>
213
+ {rh.childStrCreateHint22()}
214
+ </div>
215
+ </div>
216
+ )}
217
+
218
+ {rh.showNmdHeAjEx() && (
219
+ <DefaultFlexStack className={rh.clsNmdHeAjEx()}>
220
+ <input
221
+ className={rh.clsEmail()}
222
+ {...rh.propsEmail()}
223
+ onChange={e => setEmail(e.target.value)}
224
+ value={email}
225
+ />
226
+
227
+ <Button {...rh.propsInviteButton()} onClick={onInvite}>
228
+ {rh.childStrInviteButton()}
229
+ </Button>
230
+ <div className={rh.clsZG$NA1rCh()} />
231
+ {rh.show$kdxH_yN6() && (
232
+ <div className={rh.cls$kdxH_yN6()}>
233
+ {rh.showUpdateButton() && (
234
+ <Button
235
+ startIcon={
236
+ rh.showL4QcXYzNZ() && (
237
+ <img
238
+ className={rh.clsL4QcXYzNZ()}
239
+ {...rh.propsL4QcXYzNZ()}
240
+ />
241
+ )
242
+ }
243
+ {...rh.propsUpdateButton()}
244
+ onClick={onCreateOrUpdateSandbox}
245
+ >
246
+ {rh.childStrUpdateButton()}
247
+ </Button>
248
+ )}
249
+
250
+ {rh.showDeleteButton() && (
251
+ <Tooltip title="Detach this code sandbox. You can still access it via codesandbox.io, but Plasmic will start using a new sandbox instead.">
252
+ <IconButton
253
+ {...rh.propsDeleteButton()}
254
+ onClick={onDeleteSandbox}
255
+ />
256
+ </Tooltip>
257
+ )}
258
+ </div>
259
+ )}
260
+ </DefaultFlexStack>
261
+ )}
262
+ </div>
263
+ );
264
+ }
265
+
266
+ export const CodeSandboxDialogContent = observer(
267
+ _CodeSandboxDialogContent as React.FunctionComponent<
268
+ CodeSandboxDialogContentProps
269
+ >
270
+ );`;
271
+ expect(formatScript(tsxToJsx(code), process.cwd()).trim()).toEqual(
272
+ `
273
+ // This is a skeleton starter React component generated by Plasmic.
274
+ // @jsx helper
275
+ import React from "react";
276
+ import { PlasmicCodeSandboxDialogContent__RenderHelper } from "./PP__CodeSandboxDialogContent"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
277
+ import Button from "../Button"; // plasmic-import: 4SYnkOQLd5/component
278
+ import Dropdown from "./Dropdown"; // plasmic-import: a200b79f-288d-4306-be99-e5fd221b8ba6/component
279
+ import DropdownItem from "./DropdownItem"; // plasmic-import: f4c2f0bb-8dce-49c7-a106-65abe9e70e51/component
280
+ import IconButton from "../../IconButton"; // plasmic-import: cfe92-5RW/component
281
+ import { DefaultFlexStack } from "@plasmicapp/react-web";
282
+ import { ensure, asOne, isValidEmail } from "../../../../common";
283
+ import { createSandboxUrl } from "../../../../codesandbox/url";
284
+ import { Tooltip } from "antd";
285
+ import { observer } from "mobx-react-lite";
286
+
287
+ function _CodeSandboxDialogContent(props) {
288
+ const sc = props.sc;
289
+ const [inviting, setInviting] = React.useState(false);
290
+ const [submitting, setSubmitting] = React.useState(false);
291
+ const [email, setEmail] = React.useState("");
292
+ const [sandboxInfo, setSandboxInfo] = React.useState(
293
+ asOne(sc.siteInfo.codeSandboxInfos)
294
+ );
295
+ const [codeScheme, setCodeScheme] = React.useState(
296
+ sandboxInfo ? sandboxInfo.code.scheme : "blackbox"
297
+ );
298
+ const openSandboxPopup = (sandboxId) => {
299
+ const url = createSandboxUrl({ id: sandboxId });
300
+ if (sc.popupCodesandboxWindow && !sc.popupCodesandboxWindow.closed) {
301
+ sc.popupCodesandboxWindow.location.href = url;
302
+ sc.popupCodesandboxWindow.focus();
303
+ } else {
304
+ sc.popupCodesandboxWindow = window.open(url);
305
+ }
306
+ };
307
+ const onCreateOrUpdateSandbox = async () => {
308
+ setSubmitting(true);
309
+ const { id } = await sc.appCtx.api.publishCodeSandbox(
310
+ sc.siteInfo.id,
311
+ sandboxInfo
312
+ ? { ...sandboxInfo }
313
+ : { code: { lang: "ts", scheme: codeScheme } }
314
+ );
315
+ await sc.refreshSiteInfo();
316
+ setSubmitting(false);
317
+ setSandboxInfo(
318
+ (sc.siteInfo.codeSandboxInfos || []).find((x) => x.id === id)
319
+ );
320
+ openSandboxPopup(id);
321
+ };
322
+ const onInvite = () => {
323
+ setInviting(true);
324
+ sc.appCtx.api
325
+ .shareCodeSandbox(sc.siteInfo.id, ensure(sandboxInfo).id, email)
326
+ .then(() => {
327
+ setInviting(false);
328
+ });
329
+ setEmail("");
330
+ };
331
+ const onSwitchCodeScheme = (scheme) => {
332
+ setCodeScheme(scheme);
333
+ setSandboxInfo(
334
+ (sc.siteInfo.codeSandboxInfos || []).find((x) => x.code.scheme === scheme)
335
+ );
336
+ };
337
+ const onDeleteSandbox = async () => {
338
+ setSubmitting(true);
339
+ await sc.appCtx.api.detachCodeSandbox(
340
+ sc.siteInfo.id,
341
+ ensure(sandboxInfo).id
342
+ );
343
+ await sc.refreshSiteInfo();
344
+ setSubmitting(false);
345
+ setSandboxInfo(undefined);
346
+ };
347
+ const variants = {
348
+ state: inviting ? "inviting" : submitting ? "submitting" : undefined,
349
+ hasSandbox: !!sandboxInfo ? "yes" : "no",
350
+ invalidEmail: !isValidEmail(email) ? "yes" : undefined,
351
+ canEdit: !sc.canEditProject() ? "no" : undefined,
352
+ scheme: codeScheme === "direct" ? "direct" : "blackbox",
353
+ };
354
+
355
+ const args = {};
356
+ // The following code block is fully managed by Plasmic. Don't edit - it will
357
+ // be overwritten after every "plasmic sync".
358
+ // plasmic-managed-start
359
+ const rh = new PlasmicCodeSandboxDialogContent__RenderHelper(
360
+ variants,
361
+ args,
362
+ props.className
363
+ );
364
+ // plasmic-managed-end
365
+ // plasmic-managed-jsx/5487
366
+ return (
367
+ <div className={rh.clsRoot()}>
368
+ <div className={rh.clsF7050e55$eea1$41ab$9682$db9ad8d08cb1()}>
369
+ <div className={rh.cls70032be2$1620$48b3$ba29$c027e30b7907()}>
370
+ CodeSandbox
371
+ </div>
372
+ <DefaultFlexStack className={rh.cls8oFaZaiIX()}>
373
+ {rh.showOpenButton() && (
374
+ <Button
375
+ startIcon={
376
+ <img className={rh.cls$qzB2zcT8()} {...rh.props$qzB2zcT8()} />
377
+ }
378
+ {...rh.propsOpenButton()}
379
+ onClick={() => openSandboxPopup(ensure(sandboxInfo).id)}
380
+ >
381
+ Open in new tab
382
+ </Button>
383
+ )}
384
+
385
+ <img
386
+ className={rh.clsCloseButton()}
387
+ {...rh.propsCloseButton()}
388
+ onClick={props.onClose}
389
+ />
390
+ </DefaultFlexStack>
391
+ </div>
392
+ <div className={rh.cls43fcb29a$5286$4b5a$8593$49b737cdd7b0()} />
393
+ <DefaultFlexStack className={rh.clsWL8ypAgbq()}>
394
+ <div className={rh.clsTmQlfUKwS()}>Code scheme</div>
395
+ <Dropdown
396
+ {...rh.propsCodeSchemeDropdown()}
397
+ selectedValue={rh.childStrCodeSchemeDropdown()}
398
+ items={
399
+ <>
400
+ <DropdownItem
401
+ {...rh.propsBlackBoxOption()}
402
+ value={"Blackbox Library"}
403
+ selected={codeScheme === "blackbox"}
404
+ onSelected={() => onSwitchCodeScheme("blackbox")}
405
+ />
406
+
407
+ <DropdownItem
408
+ {...rh.propsPlainReactOption()}
409
+ value={"Direct Edit"}
410
+ selected={codeScheme === "direct"}
411
+ onSelected={() => onSwitchCodeScheme("direct")}
412
+ />
413
+ </>
414
+ }
415
+ />
416
+ </DefaultFlexStack>
417
+ <div className={rh.clsH1u3gI8vG()}>{rh.childStrH1u3gI8vG()}</div>
418
+ {rh.showCreateHint() && (
419
+ <div className={rh.clsCreateHint()}>
420
+ {rh.showCreateHint2() && (
421
+ <div className={rh.clsCreateHint2()}>
422
+ {rh.childStrCreateHint2()}
423
+ </div>
424
+ )}
425
+ </div>
426
+ )}
427
+
428
+ {rh.showCreateButton() && (
429
+ <Button
430
+ startIcon={
431
+ <img className={rh.clsGvtJoBerl()} {...rh.propsGvtJoBerl()} />
432
+ }
433
+ {...rh.propsCreateButton()}
434
+ onClick={onCreateOrUpdateSandbox}
435
+ >
436
+ {rh.childStrCreateButton()}
437
+ </Button>
438
+ )}
439
+
440
+ {rh.showUpdateHint() && (
441
+ <div className={rh.clsUpdateHint()}>
442
+ <div className={rh.clsCreateHint22()}>
443
+ {rh.childStrCreateHint22()}
444
+ </div>
445
+ </div>
446
+ )}
447
+
448
+ {rh.showNmdHeAjEx() && (
449
+ <DefaultFlexStack className={rh.clsNmdHeAjEx()}>
450
+ <input
451
+ className={rh.clsEmail()}
452
+ {...rh.propsEmail()}
453
+ onChange={(e) => setEmail(e.target.value)}
454
+ value={email}
455
+ />
456
+
457
+ <Button {...rh.propsInviteButton()} onClick={onInvite}>
458
+ {rh.childStrInviteButton()}
459
+ </Button>
460
+ <div className={rh.clsZG$NA1rCh()} />
461
+ {rh.show$kdxH_yN6() && (
462
+ <div className={rh.cls$kdxH_yN6()}>
463
+ {rh.showUpdateButton() && (
464
+ <Button
465
+ startIcon={
466
+ rh.showL4QcXYzNZ() && (
467
+ <img
468
+ className={rh.clsL4QcXYzNZ()}
469
+ {...rh.propsL4QcXYzNZ()}
470
+ />
471
+ )
472
+ }
473
+ {...rh.propsUpdateButton()}
474
+ onClick={onCreateOrUpdateSandbox}
475
+ >
476
+ {rh.childStrUpdateButton()}
477
+ </Button>
478
+ )}
479
+
480
+ {rh.showDeleteButton() && (
481
+ <Tooltip title="Detach this code sandbox. You can still access it via codesandbox.io, but Plasmic will start using a new sandbox instead.">
482
+ <IconButton
483
+ {...rh.propsDeleteButton()}
484
+ onClick={onDeleteSandbox}
485
+ />
486
+ </Tooltip>
487
+ )}
488
+ </div>
489
+ )}
490
+ </DefaultFlexStack>
491
+ )}
492
+ </div>
493
+ );
494
+ }
495
+
496
+ export const CodeSandboxDialogContent = observer(_CodeSandboxDialogContent);
497
+ `.trim()
498
+ );
499
+ });
500
+
501
+ it("fix imports for file should work", function () {
502
+ const code = `// This is a skeleton starter React component generated by Plasmic.
503
+ import React, { ReactNode } from "react";
504
+ import {
505
+ PlasmicCodeSandboxDialogContent__RenderHelper,
506
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
507
+ PlasmicCodeSandboxDialogContent__ArgsType,
508
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
509
+ } from "./PP__CodeSandboxDialogContent"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
510
+ import Button from "./Button"; // plasmic-import: 4SYnkOQLd5/component
511
+ import CloseIcon from "./PlasmicIcon__Close"; // plasmic-import: rFn9Vj2p9/icon
512
+
513
+ import "@plasmicapp/react-web/lib/plasmic.css";
514
+ import "./PP__plasmic__default_style.css"; // plasmic-import: global/defaultcss
515
+ import "./PP__plasmic_kit.css"; // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
516
+ import "./PP__CodeSandboxDialogContent.css"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/css
517
+
518
+ import {
519
+ hasVariant,
520
+ DefaultFlexStack,
521
+ Stack,
522
+ PlasmicIcon,
523
+ } from "@plasmicapp/react-web";
524
+ import { StudioCtx } from "../../../StudioCtx";
525
+ import { observer } from "mobx-react-lite";
526
+
527
+ function _CodeSandboxDialogContent(props) {
528
+ return null;
529
+ }
530
+ `;
531
+ const configJson = readFileText(
532
+ "./testData/fixImports_plasmic.json"
533
+ ).toString();
534
+ const config = JSON.parse(configJson);
535
+ const context = {
536
+ config,
537
+ cliArgs: {},
538
+ } as any;
539
+ const fixImportContext = mkFixImportContext(config);
540
+ const replaced = replaceImports(
541
+ context,
542
+ code,
543
+ "/tmp/CodeSandbox.tsx",
544
+ fixImportContext,
545
+ false,
546
+ process.cwd(),
547
+ );
548
+ const expectedCode = `// This is a skeleton starter React component generated by Plasmic.
549
+ import React, { ReactNode } from "react";
550
+ import {
551
+ PlasmicCodeSandboxDialogContent__RenderHelper,
552
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
553
+ PlasmicCodeSandboxDialogContent__ArgsType,
554
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
555
+ } from "./newDir/PP__CodeSandboxDialogContent"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
556
+ import Button from "./newDir/Button"; // plasmic-import: 4SYnkOQLd5/component
557
+ import CloseIcon from "./newDir/PlasmicIcon__Close"; // plasmic-import: rFn9Vj2p9/icon
558
+
559
+ import "@plasmicapp/react-web/lib/plasmic.css";
560
+ import "./newDir/PP__plasmic__default_style.css"; // plasmic-import: global/defaultcss
561
+ import "./newDir/PP__plasmic_kit.css"; // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
562
+ import "./newDir/PP__CodeSandboxDialogContent.css"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/css
563
+
564
+ import {
565
+ hasVariant,
566
+ DefaultFlexStack,
567
+ Stack,
568
+ PlasmicIcon,
569
+ } from "@plasmicapp/react-web";
570
+ import { StudioCtx } from "../../../StudioCtx";
571
+ import { observer } from "mobx-react-lite";
572
+
573
+ function _CodeSandboxDialogContent(props) {
574
+ return null;
575
+ }
576
+ `;
577
+ expect(replaced).toEqual(expectedCode);
578
+ });
579
+
580
+ it("fix imports should remove directives", function () {
581
+ const code = `// This is a skeleton starter React component generated by Plasmic.
582
+ import React, { ReactNode } from "react";
583
+ import {
584
+ PlasmicCodeSandboxDialogContent__RenderHelper,
585
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
586
+ PlasmicCodeSandboxDialogContent__ArgsType,
587
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
588
+ } from "./PP__CodeSandboxDialogContent"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
589
+ import Button from "./Button"; // plasmic-import: 4SYnkOQLd5/component
590
+ import CloseIcon from "./PlasmicIcon__Close"; // plasmic-import: rFn9Vj2p9/icon
591
+
592
+ import "@plasmicapp/react-web/lib/plasmic.css";
593
+ import "./PP__plasmic__default_style.css"; // plasmic-import: global/defaultcss
594
+ import "./PP__plasmic_kit.css"; // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
595
+ import "./PP__CodeSandboxDialogContent.css"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/css
596
+
597
+ import {
598
+ hasVariant,
599
+ DefaultFlexStack,
600
+ Stack,
601
+ PlasmicIcon,
602
+ } from "@plasmicapp/react-web";
603
+ import { StudioCtx } from "../../../StudioCtx";
604
+ import { observer } from "mobx-react-lite";
605
+
606
+ function _CodeSandboxDialogContent(props) {
607
+ return null;
608
+ }
609
+ `;
610
+ const configJson = readFileText(
611
+ "./testData/fixImports_plasmic.json"
612
+ ).toString();
613
+ const config = JSON.parse(configJson);
614
+ const fixImportContext = mkFixImportContext(config);
615
+ const context = {
616
+ config,
617
+ cliArgs: {},
618
+ } as any;
619
+ const replaced = replaceImports(
620
+ context,
621
+ code,
622
+ "/tmp/CodeSandbox.tsx",
623
+ fixImportContext,
624
+ true,
625
+ process.cwd(),
626
+ );
627
+ const expectedCode = `// This is a skeleton starter React component generated by Plasmic.
628
+ import React, { ReactNode } from "react";
629
+ import {
630
+ PlasmicCodeSandboxDialogContent__RenderHelper,
631
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
632
+ PlasmicCodeSandboxDialogContent__ArgsType,
633
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
634
+ } from "./newDir/PP__CodeSandboxDialogContent";
635
+ import Button from "./newDir/Button";
636
+ import CloseIcon from "./newDir/PlasmicIcon__Close";
637
+
638
+ import "@plasmicapp/react-web/lib/plasmic.css";
639
+ import "./newDir/PP__plasmic__default_style.css";
640
+ import "./newDir/PP__plasmic_kit.css";
641
+ import "./newDir/PP__CodeSandboxDialogContent.css";
642
+
643
+ import {
644
+ hasVariant,
645
+ DefaultFlexStack,
646
+ Stack,
647
+ PlasmicIcon,
648
+ } from "@plasmicapp/react-web";
649
+ import { StudioCtx } from "../../../StudioCtx";
650
+ import { observer } from "mobx-react-lite";
651
+
652
+ function _CodeSandboxDialogContent(props) {
653
+ return null;
654
+ }
655
+ `;
656
+ expect(replaced).toEqual(expectedCode);
657
+ });
658
+
659
+ it("fix imports for file should work when the code has no semicolon", function () {
660
+ const code = `// This is a skeleton starter React component generated by Plasmic.
661
+ import React, { ReactNode } from "react";
662
+ import {
663
+ PlasmicCodeSandboxDialogContent__RenderHelper,
664
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
665
+ PlasmicCodeSandboxDialogContent__ArgsType,
666
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
667
+ } from "./PP__CodeSandboxDialogContent" // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
668
+ import Button from "./Button" // plasmic-import: 4SYnkOQLd5/component
669
+ import CloseIcon from "./PlasmicIcon__Close" // plasmic-import: rFn9Vj2p9/icon
670
+
671
+ import "@plasmicapp/react-web/lib/plasmic.css"
672
+ import "./PP__plasmic__default_style.css" // plasmic-import: global/defaultcss
673
+ import "./PP__plasmic_kit.css" // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
674
+ import "./PP__CodeSandboxDialogContent.css" // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/css
675
+
676
+ import {
677
+ hasVariant,
678
+ DefaultFlexStack,
679
+ Stack,
680
+ PlasmicIcon,
681
+ } from "@plasmicapp/react-web";
682
+ import { StudioCtx } from "../../../StudioCtx"
683
+ import { observer } from "mobx-react-lite"
684
+
685
+ function _CodeSandboxDialogContent(props) {
686
+ return null
687
+ }
688
+ `;
689
+
690
+ const configJson = readFileText(
691
+ "./testData/fixImports_plasmic.json"
692
+ ).toString();
693
+ const config = JSON.parse(configJson);
694
+ const fixImportContext = mkFixImportContext(config);
695
+ const context = {
696
+ config,
697
+ cliArgs: {},
698
+ } as any;
699
+ const replaced = replaceImports(
700
+ context,
701
+ code,
702
+ "/tmp/CodeSandbox.tsx",
703
+ fixImportContext,
704
+ false,
705
+ process.cwd(),
706
+ );
707
+ const expectedCode = `// This is a skeleton starter React component generated by Plasmic.
708
+ import React, { ReactNode } from "react";
709
+ import {
710
+ PlasmicCodeSandboxDialogContent__RenderHelper,
711
+ PlasmicCodeSandboxDialogContent__VariantsArgs,
712
+ PlasmicCodeSandboxDialogContent__ArgsType,
713
+ PlasmicCodeSandboxDialogContent__TriggerStateType,
714
+ } from "./newDir/PP__CodeSandboxDialogContent"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/render
715
+ import Button from "./newDir/Button"; // plasmic-import: 4SYnkOQLd5/component
716
+ import CloseIcon from "./newDir/PlasmicIcon__Close"; // plasmic-import: rFn9Vj2p9/icon
717
+
718
+ import "@plasmicapp/react-web/lib/plasmic.css";
719
+ import "./newDir/PP__plasmic__default_style.css"; // plasmic-import: global/defaultcss
720
+ import "./newDir/PP__plasmic_kit.css"; // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
721
+ import "./newDir/PP__CodeSandboxDialogContent.css"; // plasmic-import: f68b061e-0f85-41c1-8707-3ba9f634f1af/css
722
+
723
+ import {
724
+ hasVariant,
725
+ DefaultFlexStack,
726
+ Stack,
727
+ PlasmicIcon,
728
+ } from "@plasmicapp/react-web";
729
+ import { StudioCtx } from "../../../StudioCtx";
730
+ import { observer } from "mobx-react-lite";
731
+
732
+ function _CodeSandboxDialogContent(props) {
733
+ return null;
734
+ }
735
+ `;
736
+ expect(replaced).toEqual(expectedCode);
737
+ });
738
+
739
+ it("Ts to js should not remove unused React", function () {
740
+ const input = `
741
+ /* eslint-disable */
742
+ /* tslint:disable */
743
+ /* prettier-ignore-start */
744
+ /** @jsx createPlasmicElementProxy */
745
+ // This class is auto-generated by Plasmic; please do not edit!
746
+ // Plasmic Project: aBwbYpvCqht4V3F8CJNJX3
747
+ // Component: 4SYnkOQLd5
748
+ import React, { ReactNode } from "react";
749
+ import {
750
+ hasVariant,
751
+ createPlasmicElement,
752
+ RenderOpts,
753
+ Override,
754
+ classNames,
755
+ Flex,
756
+ RenderFunc,
757
+ RenderFuncOverrides,
758
+ wrapWithClassName,
759
+ Renderer,
760
+ NodeRenderer,
761
+ createPlasmicElementProxy,
762
+ makeFragment,
763
+ PlasmicIcon,
764
+ PlasmicSlot,
765
+ MultiChoiceArg,
766
+ SingleBooleanChoiceArg,
767
+ SingleChoiceArg
768
+ } from "@plasmicapp/react-web";
769
+
770
+ import "@plasmicapp/react-web/lib/plasmic.css";
771
+ import "../plasmic__default_style.css"; // plasmic-import: global/defaultcss
772
+ import "./plasmic_plasmic_kit.css"; // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
773
+ import "./PlasmicButton.css"; // plasmic-import: 4SYnkOQLd5/css
774
+ import TrashIcon from "./PlasmicIcon__Trash"; // plasmic-import: wibhDXsBy/icon
775
+
776
+ export type PlasmicButton__VariantsArgs = {
777
+ type?: SingleChoiceArg<
778
+ | "primary"
779
+ | "secondary"
780
+ | "link"
781
+ | "backlitError"
782
+ | "backlitInfo"
783
+ | "chip"
784
+ | "toggleOn"
785
+ | "toggleOff"
786
+ | "clear"
787
+ >;
788
+ size?: SingleChoiceArg<"small" | "stretch" | "wide">;
789
+ withIcons?: SingleChoiceArg<"startIcon">;
790
+ disabled?: SingleBooleanChoiceArg<"disabled">;
791
+ font?: SingleChoiceArg<"bold">;
792
+ };
793
+
794
+ export type PlasmicButton__ArgsType = {
795
+ children?: ReactNode;
796
+ startIcon?: ReactNode;
797
+ };
798
+
799
+ function PlasmicButton(props: {}): ReactNode {
800
+ return <button></button>;
801
+ }
802
+
803
+ function PlasmicButton2(props: {}): React.ReactNode {
804
+ return <button></button>;
805
+ }
806
+
807
+ export default PlasmicButton;
808
+ /* prettier-ignore-end */
809
+ `;
810
+ expect(tsxToJsx(input).trim()).toEqual(
811
+ `
812
+ /* eslint-disable */
813
+ /* tslint:disable */
814
+ /* prettier-ignore-start */
815
+ /** @jsx createPlasmicElementProxy */
816
+ // This class is auto-generated by Plasmic; please do not edit!
817
+ // Plasmic Project: aBwbYpvCqht4V3F8CJNJX3
818
+ // Component: 4SYnkOQLd5
819
+ import React from \"react\";
820
+ import { createPlasmicElementProxy } from "@plasmicapp/react-web";
821
+ import "@plasmicapp/react-web/lib/plasmic.css";
822
+ import "../plasmic__default_style.css"; // plasmic-import: global/defaultcss
823
+ import "./plasmic_plasmic_kit.css"; // plasmic-import: aBwbYpvCqht4V3F8CJNJX3/projectcss
824
+ import "./PlasmicButton.css"; // plasmic-import: 4SYnkOQLd5/css
825
+ function PlasmicButton(props) {
826
+ return <button></button>;
827
+ }
828
+ function PlasmicButton2(props) {
829
+ return <button></button>;
830
+ }
831
+ export default PlasmicButton;
832
+ /* prettier-ignore-end */`.trim()
833
+ );
834
+ });
835
+
836
+ it("formatJs should not add spaces to comment block", function () {
837
+ const input = `
838
+ import React, { ReactNode } from "react";
839
+ import "@plasmicapp/react-web/lib/plasmic.css";
840
+
841
+ function PlasmicButton(props: {}): React.ReactNode {
842
+ return <button></button>;
843
+ }
844
+
845
+ function forNode(name: keyof typeof PlasmicButton) {
846
+ const x = [1, 2].map(v => v > 1);
847
+ return null;
848
+ }
849
+
850
+ export default PlasmicButton;
851
+
852
+ // For debugging
853
+ /* plasmic-nameInIdToUuid/123
854
+ [{"1": 1""},
855
+ {"2" : "2}]
856
+ */
857
+ `;
858
+ expect(formatScript(input, process.cwd())).toEqual(
859
+ `import React, { ReactNode } from "react";
860
+ import "@plasmicapp/react-web/lib/plasmic.css";
861
+
862
+ function PlasmicButton(props: {}): React.ReactNode {
863
+ return <button></button>;
864
+ }
865
+
866
+ function forNode(name: keyof typeof PlasmicButton) {
867
+ const x = [1, 2].map((v) => v > 1);
868
+ return null;
869
+ }
870
+
871
+ export default PlasmicButton;
872
+
873
+ // For debugging
874
+ /* plasmic-nameInIdToUuid/123
875
+ [{"1": 1""},
876
+ {"2" : "2}]
877
+ */
878
+ `
879
+ );
880
+ });
881
+ });