@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.
- package/.eslintrc.js +61 -0
- package/.idea/cli.iml +11 -0
- package/.idea/misc.xml +6 -0
- package/.idea/modules.xml +8 -0
- package/.idea/vcs.xml +6 -0
- package/README +16 -0
- package/README.internal +46 -0
- package/README.md +17 -0
- package/build.sh +8 -0
- package/dist/__mocks__/api.d.ts +16 -0
- package/dist/__mocks__/api.js +297 -0
- package/dist/__tests__/code-utils-spec.d.ts +1 -0
- package/dist/__tests__/code-utils-spec.js +838 -0
- package/dist/__tests__/ftue-spec.d.ts +1 -0
- package/dist/__tests__/ftue-spec.js +39 -0
- package/dist/__tests__/project-api-token-spec.d.ts +1 -0
- package/dist/__tests__/project-api-token-spec.js +147 -0
- package/dist/__tests__/versioned-sync-spec.d.ts +1 -0
- package/dist/__tests__/versioned-sync-spec.js +145 -0
- package/dist/actions/auth.d.ts +8 -0
- package/dist/actions/auth.js +47 -0
- package/dist/actions/fix-imports.d.ts +4 -0
- package/dist/actions/fix-imports.js +25 -0
- package/dist/actions/init.d.ts +62 -0
- package/dist/actions/init.js +460 -0
- package/dist/actions/project-token.d.ts +6 -0
- package/dist/actions/project-token.js +42 -0
- package/dist/actions/sync-components.d.ts +10 -0
- package/dist/actions/sync-components.js +242 -0
- package/dist/actions/sync-global-variants.d.ts +3 -0
- package/dist/actions/sync-global-variants.js +89 -0
- package/dist/actions/sync-icons.d.ts +7 -0
- package/dist/actions/sync-icons.js +92 -0
- package/dist/actions/sync-images.d.ts +6 -0
- package/dist/actions/sync-images.js +137 -0
- package/dist/actions/sync-styles.d.ts +3 -0
- package/dist/actions/sync-styles.js +58 -0
- package/dist/actions/sync.d.ts +25 -0
- package/dist/actions/sync.js +417 -0
- package/dist/actions/upload-bundle.d.ts +15 -0
- package/dist/actions/upload-bundle.js +28 -0
- package/dist/actions/watch.d.ts +14 -0
- package/dist/actions/watch.js +90 -0
- package/dist/api.d.ts +182 -0
- package/dist/api.js +202 -0
- package/dist/deps.d.ts +2 -0
- package/dist/deps.js +20 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +247 -0
- package/dist/lib.d.ts +10 -0
- package/dist/lib.js +23 -0
- package/dist/migrations/0.1.110-fileLocks.d.ts +2 -0
- package/dist/migrations/0.1.110-fileLocks.js +15 -0
- package/dist/migrations/0.1.143-ensureImportModuleType.d.ts +2 -0
- package/dist/migrations/0.1.143-ensureImportModuleType.js +12 -0
- package/dist/migrations/0.1.146-addReactRuntime.d.ts +2 -0
- package/dist/migrations/0.1.146-addReactRuntime.js +10 -0
- package/dist/migrations/0.1.27-migrateInit.d.ts +1 -0
- package/dist/migrations/0.1.27-migrateInit.js +8 -0
- package/dist/migrations/0.1.28-tsToTsx.d.ts +3 -0
- package/dist/migrations/0.1.28-tsToTsx.js +33 -0
- package/dist/migrations/0.1.31-ensureProjectIcons.d.ts +2 -0
- package/dist/migrations/0.1.31-ensureProjectIcons.js +12 -0
- package/dist/migrations/0.1.42-ensureVersion.d.ts +2 -0
- package/dist/migrations/0.1.42-ensureVersion.js +12 -0
- package/dist/migrations/0.1.57-ensureJsBundleThemes.d.ts +2 -0
- package/dist/migrations/0.1.57-ensureJsBundleThemes.js +12 -0
- package/dist/migrations/0.1.64-imageFiles.d.ts +2 -0
- package/dist/migrations/0.1.64-imageFiles.js +17 -0
- package/dist/migrations/0.1.95-componentType.d.ts +2 -0
- package/dist/migrations/0.1.95-componentType.js +16 -0
- package/dist/migrations/migrations.d.ts +10 -0
- package/dist/migrations/migrations.js +119 -0
- package/dist/plasmic.schema.json +463 -0
- package/dist/test-common/fixtures.d.ts +13 -0
- package/dist/test-common/fixtures.js +165 -0
- package/dist/tsconfig-transform.json +68 -0
- package/dist/utils/auth-utils.d.ts +31 -0
- package/dist/utils/auth-utils.js +236 -0
- package/dist/utils/checksum.d.ts +4 -0
- package/dist/utils/checksum.js +63 -0
- package/dist/utils/code-utils.d.ts +46 -0
- package/dist/utils/code-utils.js +457 -0
- package/dist/utils/config-utils.d.ts +271 -0
- package/dist/utils/config-utils.js +178 -0
- package/dist/utils/envdetect.d.ts +4 -0
- package/dist/utils/envdetect.js +42 -0
- package/dist/utils/error.d.ts +14 -0
- package/dist/utils/error.js +42 -0
- package/dist/utils/file-utils.d.ts +71 -0
- package/dist/utils/file-utils.js +433 -0
- package/dist/utils/get-context.d.ts +40 -0
- package/dist/utils/get-context.js +339 -0
- package/dist/utils/help.d.ts +2 -0
- package/dist/utils/help.js +56 -0
- package/dist/utils/lang-utils.d.ts +10 -0
- package/dist/utils/lang-utils.js +52 -0
- package/dist/utils/npm-utils.d.ts +28 -0
- package/dist/utils/npm-utils.js +215 -0
- package/dist/utils/prompts.d.ts +6 -0
- package/dist/utils/prompts.js +23 -0
- package/dist/utils/resolve-utils.d.ts +13 -0
- package/dist/utils/resolve-utils.js +198 -0
- package/dist/utils/semver.d.ts +34 -0
- package/dist/utils/semver.js +61 -0
- package/dist/utils/test-utils.d.ts +22 -0
- package/dist/utils/test-utils.js +106 -0
- package/dist/utils/user-utils.d.ts +7 -0
- package/dist/utils/user-utils.js +48 -0
- package/jest.config.js +6 -0
- package/package.json +80 -0
- package/src/__mocks__/api.ts +394 -0
- package/src/__tests__/code-utils-spec.ts +881 -0
- package/src/__tests__/ftue-spec.ts +43 -0
- package/src/__tests__/project-api-token-spec.ts +208 -0
- package/src/__tests__/versioned-sync-spec.ts +176 -0
- package/src/actions/auth.ts +43 -0
- package/src/actions/fix-imports.ts +13 -0
- package/src/actions/init.ts +638 -0
- package/src/actions/project-token.ts +36 -0
- package/src/actions/sync-components.ts +405 -0
- package/src/actions/sync-global-variants.ts +129 -0
- package/src/actions/sync-icons.ts +135 -0
- package/src/actions/sync-images.ts +191 -0
- package/src/actions/sync-styles.ts +71 -0
- package/src/actions/sync.ts +747 -0
- package/src/actions/upload-bundle.ts +38 -0
- package/src/actions/watch.ts +95 -0
- package/src/api.ts +407 -0
- package/src/deps.ts +18 -0
- package/src/index.ts +300 -0
- package/src/lib.ts +10 -0
- package/src/migrations/0.1.110-fileLocks.ts +16 -0
- package/src/migrations/0.1.146-addReactRuntime.ts +8 -0
- package/src/migrations/0.1.27-migrateInit.ts +4 -0
- package/src/migrations/0.1.28-tsToTsx.ts +37 -0
- package/src/migrations/0.1.31-ensureProjectIcons.ts +10 -0
- package/src/migrations/0.1.42-ensureVersion.ts +10 -0
- package/src/migrations/0.1.57-ensureJsBundleThemes.ts +10 -0
- package/src/migrations/0.1.64-imageFiles.ts +15 -0
- package/src/migrations/0.1.95-componentType.ts +14 -0
- package/src/migrations/migrations.ts +147 -0
- package/src/test-common/fixtures.ts +178 -0
- package/src/utils/auth-utils.ts +276 -0
- package/src/utils/checksum.ts +106 -0
- package/src/utils/code-utils.ts +656 -0
- package/src/utils/config-utils.ts +551 -0
- package/src/utils/envdetect.ts +39 -0
- package/src/utils/error.ts +36 -0
- package/src/utils/file-utils.ts +526 -0
- package/src/utils/get-context.ts +451 -0
- package/src/utils/help.ts +75 -0
- package/src/utils/lang-utils.ts +52 -0
- package/src/utils/npm-utils.ts +223 -0
- package/src/utils/prompts.ts +22 -0
- package/src/utils/resolve-utils.ts +245 -0
- package/src/utils/semver.ts +67 -0
- package/src/utils/test-utils.ts +116 -0
- package/src/utils/user-utils.ts +37 -0
- package/testData/fixImports_plasmic.json +66 -0
- package/tsconfig-transform.json +68 -0
- package/tsconfig.json +67 -0
|
@@ -0,0 +1,405 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ComponentInfoForMerge,
|
|
3
|
+
makeCachedProjectSyncDataProvider,
|
|
4
|
+
mergeFiles,
|
|
5
|
+
} from "@plasmicapp/code-merger";
|
|
6
|
+
import L from "lodash";
|
|
7
|
+
import path from "upath";
|
|
8
|
+
import { AppServerError, ChecksumBundle, ComponentBundle } from "../api";
|
|
9
|
+
import { logger } from "../deps";
|
|
10
|
+
import { ComponentUpdateSummary, formatAsLocal } from "../utils/code-utils";
|
|
11
|
+
import {
|
|
12
|
+
ComponentConfig,
|
|
13
|
+
CONFIG_FILE_NAME,
|
|
14
|
+
isPageAwarePlatform,
|
|
15
|
+
PlasmicContext,
|
|
16
|
+
ProjectConfig,
|
|
17
|
+
ProjectLock,
|
|
18
|
+
} from "../utils/config-utils";
|
|
19
|
+
import { HandledError } from "../utils/error";
|
|
20
|
+
import {
|
|
21
|
+
defaultPagePath,
|
|
22
|
+
defaultResourcePath,
|
|
23
|
+
deleteFile,
|
|
24
|
+
fileExists,
|
|
25
|
+
readFileContent,
|
|
26
|
+
renameFile,
|
|
27
|
+
writeFileContent,
|
|
28
|
+
} from "../utils/file-utils";
|
|
29
|
+
import { assert, ensure } from "../utils/lang-utils";
|
|
30
|
+
import { confirmWithUser } from "../utils/user-utils";
|
|
31
|
+
|
|
32
|
+
export interface ComponentPendingMerge {
|
|
33
|
+
// path of the skeleton module
|
|
34
|
+
skeletonModulePath: string;
|
|
35
|
+
editedSkeletonFile: string;
|
|
36
|
+
newSkeletonFile: string;
|
|
37
|
+
// function to perform code merger using input whose import has been resolved.
|
|
38
|
+
merge: (
|
|
39
|
+
resolvedNewSkeletonFile: string,
|
|
40
|
+
resolvedEditedSkeletonFile: string
|
|
41
|
+
) => Promise<void>;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const updateDirectSkeleton = async (
|
|
45
|
+
newFileContent: string,
|
|
46
|
+
editedFileContent: string,
|
|
47
|
+
context: PlasmicContext,
|
|
48
|
+
compConfig: ComponentConfig,
|
|
49
|
+
forceOverwrite: boolean,
|
|
50
|
+
nameInIdToUuid: [string, string][],
|
|
51
|
+
appendJsxOnMissingBase: boolean
|
|
52
|
+
) => {
|
|
53
|
+
// merge code!
|
|
54
|
+
const componentByUuid = new Map<string, ComponentInfoForMerge>();
|
|
55
|
+
|
|
56
|
+
componentByUuid.set(compConfig.id, {
|
|
57
|
+
editedFile: editedFileContent,
|
|
58
|
+
newFile: newFileContent,
|
|
59
|
+
newNameInIdToUuid: new Map(nameInIdToUuid),
|
|
60
|
+
});
|
|
61
|
+
const mergedFiles = await mergeFiles(
|
|
62
|
+
componentByUuid,
|
|
63
|
+
compConfig.projectId,
|
|
64
|
+
makeCachedProjectSyncDataProvider(async (projectId, revision) => {
|
|
65
|
+
try {
|
|
66
|
+
return await context.api.projectSyncMetadata(projectId, revision, true);
|
|
67
|
+
} catch (e) {
|
|
68
|
+
if (
|
|
69
|
+
e instanceof AppServerError &&
|
|
70
|
+
/revision \d+ not found/.test(e.message)
|
|
71
|
+
) {
|
|
72
|
+
throw e;
|
|
73
|
+
} else {
|
|
74
|
+
throw new HandledError(e.messag);
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}),
|
|
78
|
+
() => {},
|
|
79
|
+
appendJsxOnMissingBase
|
|
80
|
+
);
|
|
81
|
+
const merged = mergedFiles?.get(compConfig.id);
|
|
82
|
+
if (merged) {
|
|
83
|
+
await writeFileContent(context, compConfig.importSpec.modulePath, merged, {
|
|
84
|
+
force: true,
|
|
85
|
+
});
|
|
86
|
+
} else {
|
|
87
|
+
if (!forceOverwrite) {
|
|
88
|
+
throw new HandledError(
|
|
89
|
+
`Cannot merge ${compConfig.importSpec.modulePath}. If you just switched the code scheme for the component from blackbox to direct, use --force-overwrite option to force the switch.`
|
|
90
|
+
);
|
|
91
|
+
} else {
|
|
92
|
+
logger.warn(
|
|
93
|
+
`Overwrite ${compConfig.importSpec.modulePath} despite merge failure`
|
|
94
|
+
);
|
|
95
|
+
await writeFileContent(
|
|
96
|
+
context,
|
|
97
|
+
compConfig.importSpec.modulePath,
|
|
98
|
+
newFileContent,
|
|
99
|
+
{
|
|
100
|
+
force: true,
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
export async function syncProjectComponents(
|
|
108
|
+
context: PlasmicContext,
|
|
109
|
+
project: ProjectConfig,
|
|
110
|
+
version: string,
|
|
111
|
+
componentBundles: ComponentBundle[],
|
|
112
|
+
forceOverwrite: boolean,
|
|
113
|
+
appendJsxOnMissingBase: boolean,
|
|
114
|
+
summary: Map<string, ComponentUpdateSummary>,
|
|
115
|
+
pendingMerge: ComponentPendingMerge[],
|
|
116
|
+
projectLock: ProjectLock,
|
|
117
|
+
checksums: ChecksumBundle,
|
|
118
|
+
baseDir: string
|
|
119
|
+
) {
|
|
120
|
+
const componentsFromChecksums = new Set([
|
|
121
|
+
...checksums.cssRulesChecksums.map(([id, _]) => id),
|
|
122
|
+
checksums.renderModuleChecksums.map(([id, _]) => id),
|
|
123
|
+
]);
|
|
124
|
+
const allCompConfigs = L.keyBy(project.components, (c) => c.id);
|
|
125
|
+
const componentBundleIds = L.keyBy(componentBundles, (i) => i.id);
|
|
126
|
+
const deletedComponents = L.filter(
|
|
127
|
+
allCompConfigs,
|
|
128
|
+
(i) => !componentBundleIds[i.id] && !componentsFromChecksums.has(i.id)
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
const renderModuleFileLocks = L.keyBy(
|
|
132
|
+
projectLock.fileLocks.filter(
|
|
133
|
+
(fileLock) => fileLock.type === "renderModule"
|
|
134
|
+
),
|
|
135
|
+
(fl) => fl.assetId
|
|
136
|
+
);
|
|
137
|
+
const cssRulesFileLocks = L.keyBy(
|
|
138
|
+
projectLock.fileLocks.filter((fileLock) => fileLock.type === "cssRules"),
|
|
139
|
+
(fl) => fl.assetId
|
|
140
|
+
);
|
|
141
|
+
const id2RenderModuleChecksum = new Map(checksums.renderModuleChecksums);
|
|
142
|
+
const id2CssRulesChecksum = new Map(checksums.cssRulesChecksums);
|
|
143
|
+
|
|
144
|
+
const deletedComponentFiles = new Set<string>();
|
|
145
|
+
for (const deletedComponent of deletedComponents) {
|
|
146
|
+
const componentConfig = allCompConfigs[deletedComponent.id];
|
|
147
|
+
if (
|
|
148
|
+
fileExists(context, componentConfig.renderModuleFilePath) &&
|
|
149
|
+
fileExists(context, componentConfig.cssFilePath)
|
|
150
|
+
) {
|
|
151
|
+
logger.info(
|
|
152
|
+
`Deleting component: ${componentConfig.name}@${version}\t['${project.projectName}' ${project.projectId}/${componentConfig.id} ${project.version}]`
|
|
153
|
+
);
|
|
154
|
+
deleteFile(context, componentConfig.renderModuleFilePath);
|
|
155
|
+
deleteFile(context, componentConfig.cssFilePath);
|
|
156
|
+
deletedComponentFiles.add(deletedComponent.id);
|
|
157
|
+
|
|
158
|
+
const skeletonPath = componentConfig.importSpec.modulePath;
|
|
159
|
+
if (fileExists(context, skeletonPath)) {
|
|
160
|
+
const deleteSkeleton = await confirmWithUser(
|
|
161
|
+
`Do you want to delete ${skeletonPath}?`,
|
|
162
|
+
context.cliArgs.yes
|
|
163
|
+
);
|
|
164
|
+
if (deleteSkeleton) {
|
|
165
|
+
deleteFile(context, skeletonPath);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
project.components = project.components.filter(
|
|
171
|
+
(c) => !deletedComponentFiles.has(c.id)
|
|
172
|
+
);
|
|
173
|
+
|
|
174
|
+
const deletedComponentIds = new Set(deletedComponents.map((i) => i.id));
|
|
175
|
+
projectLock.fileLocks = projectLock.fileLocks.filter(
|
|
176
|
+
(fileLock) =>
|
|
177
|
+
(fileLock.type !== "renderModule" && fileLock.type !== "cssRules") ||
|
|
178
|
+
!deletedComponentIds.has(fileLock.assetId)
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
for (const bundle of componentBundles) {
|
|
182
|
+
const {
|
|
183
|
+
renderModule,
|
|
184
|
+
skeletonModule,
|
|
185
|
+
cssRules,
|
|
186
|
+
renderModuleFileName,
|
|
187
|
+
skeletonModuleFileName,
|
|
188
|
+
cssFileName,
|
|
189
|
+
componentName,
|
|
190
|
+
id,
|
|
191
|
+
scheme,
|
|
192
|
+
nameInIdToUuid,
|
|
193
|
+
isPage,
|
|
194
|
+
plumeType,
|
|
195
|
+
} = bundle;
|
|
196
|
+
if (context.cliArgs.quiet !== true) {
|
|
197
|
+
logger.info(
|
|
198
|
+
`Syncing component: ${componentName}@${version}\t['${project.projectName}' ${project.projectId}/${id} ${project.version}]`
|
|
199
|
+
);
|
|
200
|
+
}
|
|
201
|
+
let compConfig = allCompConfigs[id];
|
|
202
|
+
|
|
203
|
+
// A component should be regenerated if it is new or path-related information (like the name)
|
|
204
|
+
// changed.
|
|
205
|
+
const shouldRegenerate = compConfig?.name !== componentName;
|
|
206
|
+
let skeletonModuleModified = shouldRegenerate;
|
|
207
|
+
|
|
208
|
+
const skeletonPath = isPage
|
|
209
|
+
? defaultPagePath(context, skeletonModuleFileName)
|
|
210
|
+
: skeletonModuleFileName;
|
|
211
|
+
|
|
212
|
+
const defaultRenderModuleFilePath = defaultResourcePath(
|
|
213
|
+
context,
|
|
214
|
+
project,
|
|
215
|
+
renderModuleFileName
|
|
216
|
+
);
|
|
217
|
+
const defaultCssFilePath = defaultResourcePath(
|
|
218
|
+
context,
|
|
219
|
+
project,
|
|
220
|
+
cssFileName
|
|
221
|
+
);
|
|
222
|
+
|
|
223
|
+
if (shouldRegenerate) {
|
|
224
|
+
project.components = project.components.filter(
|
|
225
|
+
(existingComponent) => existingComponent.id !== id
|
|
226
|
+
);
|
|
227
|
+
compConfig = {
|
|
228
|
+
id,
|
|
229
|
+
name: componentName,
|
|
230
|
+
type: "managed",
|
|
231
|
+
projectId: project.projectId,
|
|
232
|
+
renderModuleFilePath: defaultRenderModuleFilePath,
|
|
233
|
+
importSpec: { modulePath: skeletonPath },
|
|
234
|
+
cssFilePath: defaultCssFilePath,
|
|
235
|
+
scheme: scheme as "blackbox" | "direct",
|
|
236
|
+
componentType: isPage ? "page" : "component",
|
|
237
|
+
plumeType,
|
|
238
|
+
};
|
|
239
|
+
allCompConfigs[id] = compConfig;
|
|
240
|
+
project.components.push(allCompConfigs[id]);
|
|
241
|
+
|
|
242
|
+
// Because it's the first time, we also generate the skeleton file.
|
|
243
|
+
await writeFileContent(context, skeletonPath, skeletonModule, {
|
|
244
|
+
force: false,
|
|
245
|
+
});
|
|
246
|
+
} else if (compConfig.type === "mapped") {
|
|
247
|
+
} else if (compConfig.type === "managed") {
|
|
248
|
+
// This is an existing component.
|
|
249
|
+
// We only bother touching files on disk if this component is managed.
|
|
250
|
+
|
|
251
|
+
compConfig.componentType = isPage ? "page" : "component";
|
|
252
|
+
|
|
253
|
+
// Read in the existing file
|
|
254
|
+
let editedFile: string;
|
|
255
|
+
try {
|
|
256
|
+
editedFile = readFileContent(context, compConfig.importSpec.modulePath);
|
|
257
|
+
} catch (e) {
|
|
258
|
+
logger.warn(
|
|
259
|
+
`${compConfig.importSpec.modulePath} is missing. If you deleted this component, remember to remove the component from ${CONFIG_FILE_NAME}`
|
|
260
|
+
);
|
|
261
|
+
throw e;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const renderModuleFilePath = path.join(
|
|
265
|
+
path.dirname(compConfig.renderModuleFilePath),
|
|
266
|
+
path.basename(defaultRenderModuleFilePath)
|
|
267
|
+
);
|
|
268
|
+
if (
|
|
269
|
+
compConfig.renderModuleFilePath !== renderModuleFilePath &&
|
|
270
|
+
fileExists(context, compConfig.renderModuleFilePath)
|
|
271
|
+
) {
|
|
272
|
+
if (context.cliArgs.quiet !== true) {
|
|
273
|
+
logger.info(
|
|
274
|
+
`Renaming component file: ${compConfig.renderModuleFilePath}@${version}\t['${project.projectName}' ${project.projectId}/${id} ${project.version}]`
|
|
275
|
+
);
|
|
276
|
+
}
|
|
277
|
+
renameFile(
|
|
278
|
+
context,
|
|
279
|
+
compConfig.renderModuleFilePath,
|
|
280
|
+
renderModuleFilePath
|
|
281
|
+
);
|
|
282
|
+
compConfig.renderModuleFilePath = renderModuleFilePath;
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
const cssFilePath = path.join(
|
|
286
|
+
path.dirname(compConfig.cssFilePath),
|
|
287
|
+
path.basename(defaultCssFilePath)
|
|
288
|
+
);
|
|
289
|
+
if (
|
|
290
|
+
compConfig.cssFilePath !== cssFilePath &&
|
|
291
|
+
fileExists(context, compConfig.cssFilePath)
|
|
292
|
+
) {
|
|
293
|
+
if (context.cliArgs.quiet !== true) {
|
|
294
|
+
logger.info(
|
|
295
|
+
`Renaming component css file: ${compConfig.cssFilePath}@${version}\t['${project.projectName}' ${project.projectId}/${id} ${project.version}]`
|
|
296
|
+
);
|
|
297
|
+
}
|
|
298
|
+
renameFile(context, compConfig.cssFilePath, cssFilePath);
|
|
299
|
+
compConfig.cssFilePath = cssFilePath;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
if (
|
|
303
|
+
isPage &&
|
|
304
|
+
isPageAwarePlatform(context.config.platform) &&
|
|
305
|
+
skeletonPath !== compConfig.importSpec.modulePath &&
|
|
306
|
+
fileExists(context, compConfig.importSpec.modulePath)
|
|
307
|
+
) {
|
|
308
|
+
if (context.cliArgs.quiet !== true) {
|
|
309
|
+
logger.info(
|
|
310
|
+
`Renaming page file: ${compConfig.importSpec.modulePath} -> ${skeletonPath}\t['${project.projectName}' ${project.projectId}/${id} ${project.version}]`
|
|
311
|
+
);
|
|
312
|
+
}
|
|
313
|
+
renameFile(context, compConfig.importSpec.modulePath, skeletonPath);
|
|
314
|
+
compConfig.importSpec.modulePath = skeletonPath;
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
compConfig.plumeType = plumeType;
|
|
318
|
+
|
|
319
|
+
if (scheme === "direct") {
|
|
320
|
+
// We cannot merge right now, but wait until all the imports are resolved
|
|
321
|
+
pendingMerge.push({
|
|
322
|
+
skeletonModulePath: compConfig.importSpec.modulePath,
|
|
323
|
+
editedSkeletonFile: editedFile,
|
|
324
|
+
newSkeletonFile: skeletonModule,
|
|
325
|
+
merge: async (resolvedNewFile, resolvedEditedFile) =>
|
|
326
|
+
updateDirectSkeleton(
|
|
327
|
+
resolvedNewFile,
|
|
328
|
+
resolvedEditedFile,
|
|
329
|
+
context,
|
|
330
|
+
compConfig,
|
|
331
|
+
forceOverwrite,
|
|
332
|
+
nameInIdToUuid,
|
|
333
|
+
appendJsxOnMissingBase
|
|
334
|
+
),
|
|
335
|
+
});
|
|
336
|
+
skeletonModuleModified = true;
|
|
337
|
+
} else if (/\/\/\s*plasmic-managed-jsx\/\d+/.test(editedFile)) {
|
|
338
|
+
if (forceOverwrite) {
|
|
339
|
+
skeletonModuleModified = true;
|
|
340
|
+
await writeFileContent(
|
|
341
|
+
context,
|
|
342
|
+
compConfig.importSpec.modulePath,
|
|
343
|
+
skeletonModule,
|
|
344
|
+
{
|
|
345
|
+
force: true,
|
|
346
|
+
}
|
|
347
|
+
);
|
|
348
|
+
} else {
|
|
349
|
+
logger.warn(
|
|
350
|
+
`file ${compConfig.importSpec.modulePath} is likely in "direct" scheme. If you intend to switch the code scheme from direct to blackbox, use --force-overwrite option to force the switch.`
|
|
351
|
+
);
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
assert(L.isArray(projectLock.fileLocks));
|
|
357
|
+
// Update FileLocks
|
|
358
|
+
if (renderModuleFileLocks[id]) {
|
|
359
|
+
renderModuleFileLocks[id].checksum = ensure(
|
|
360
|
+
id2RenderModuleChecksum.get(id)
|
|
361
|
+
);
|
|
362
|
+
} else {
|
|
363
|
+
projectLock.fileLocks.push({
|
|
364
|
+
type: "renderModule",
|
|
365
|
+
assetId: id,
|
|
366
|
+
checksum: ensure(id2RenderModuleChecksum.get(id)),
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
if (cssRulesFileLocks[id]) {
|
|
370
|
+
cssRulesFileLocks[id].checksum = ensure(id2CssRulesChecksum.get(id));
|
|
371
|
+
} else {
|
|
372
|
+
projectLock.fileLocks.push({
|
|
373
|
+
type: "cssRules",
|
|
374
|
+
assetId: id,
|
|
375
|
+
checksum: ensure(id2CssRulesChecksum.get(id)),
|
|
376
|
+
});
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
if (compConfig.type === "managed") {
|
|
380
|
+
// Again, only need to touch files on disk if managed
|
|
381
|
+
await writeFileContent(
|
|
382
|
+
context,
|
|
383
|
+
compConfig.renderModuleFilePath,
|
|
384
|
+
renderModule,
|
|
385
|
+
{
|
|
386
|
+
force: !shouldRegenerate,
|
|
387
|
+
}
|
|
388
|
+
);
|
|
389
|
+
const formattedCssRules = formatAsLocal(
|
|
390
|
+
cssRules,
|
|
391
|
+
compConfig.cssFilePath,
|
|
392
|
+
baseDir
|
|
393
|
+
);
|
|
394
|
+
await writeFileContent(
|
|
395
|
+
context,
|
|
396
|
+
compConfig.cssFilePath,
|
|
397
|
+
formattedCssRules,
|
|
398
|
+
{
|
|
399
|
+
force: !shouldRegenerate,
|
|
400
|
+
}
|
|
401
|
+
);
|
|
402
|
+
}
|
|
403
|
+
summary.set(id, { skeletonModuleModified });
|
|
404
|
+
}
|
|
405
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import L from "lodash";
|
|
2
|
+
import path from "upath";
|
|
3
|
+
import { ChecksumBundle, GlobalVariantBundle, ProjectMetaBundle } from "../api";
|
|
4
|
+
import { logger } from "../deps";
|
|
5
|
+
import { formatAsLocal } from "../utils/code-utils";
|
|
6
|
+
import { getOrAddProjectLock, PlasmicContext } from "../utils/config-utils";
|
|
7
|
+
import {
|
|
8
|
+
defaultResourcePath,
|
|
9
|
+
deleteFile,
|
|
10
|
+
fileExists,
|
|
11
|
+
renameFile,
|
|
12
|
+
writeFileContent,
|
|
13
|
+
} from "../utils/file-utils";
|
|
14
|
+
import { ensure } from "../utils/lang-utils";
|
|
15
|
+
|
|
16
|
+
export async function syncGlobalVariants(
|
|
17
|
+
context: PlasmicContext,
|
|
18
|
+
projectMeta: ProjectMetaBundle,
|
|
19
|
+
bundles: GlobalVariantBundle[],
|
|
20
|
+
checksums: ChecksumBundle,
|
|
21
|
+
baseDir: string,
|
|
22
|
+
) {
|
|
23
|
+
const projectId = projectMeta.projectId;
|
|
24
|
+
const projectLock = getOrAddProjectLock(context, projectId);
|
|
25
|
+
const existingVariantConfigs = L.keyBy(
|
|
26
|
+
context.config.globalVariants.variantGroups.filter(
|
|
27
|
+
(group) => group.projectId === projectId
|
|
28
|
+
),
|
|
29
|
+
(c) => c.id
|
|
30
|
+
);
|
|
31
|
+
const globalVariantFileLocks = L.keyBy(
|
|
32
|
+
projectLock.fileLocks.filter(
|
|
33
|
+
(fileLock) => fileLock.type === "globalVariant"
|
|
34
|
+
),
|
|
35
|
+
(fl) => fl.assetId
|
|
36
|
+
);
|
|
37
|
+
const id2VariantChecksum = new Map(checksums.globalVariantChecksums);
|
|
38
|
+
|
|
39
|
+
const variantBundleIds = L.keyBy(bundles, (i) => i.id);
|
|
40
|
+
const deletedGlobalVariants = L.filter(
|
|
41
|
+
existingVariantConfigs,
|
|
42
|
+
(i) => !variantBundleIds[i.id] && !id2VariantChecksum.has(i.id)
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
for (const bundle of bundles) {
|
|
46
|
+
if (context.cliArgs.quiet !== true) {
|
|
47
|
+
logger.info(
|
|
48
|
+
`Syncing global variant ${bundle.name} [${projectId}/${bundle.id}]`
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
let variantConfig = existingVariantConfigs[bundle.id];
|
|
52
|
+
const isNew = !variantConfig;
|
|
53
|
+
const defaultContextFilePath = defaultResourcePath(
|
|
54
|
+
context,
|
|
55
|
+
projectMeta,
|
|
56
|
+
bundle.contextFileName
|
|
57
|
+
);
|
|
58
|
+
if (isNew) {
|
|
59
|
+
variantConfig = {
|
|
60
|
+
id: bundle.id,
|
|
61
|
+
name: bundle.name,
|
|
62
|
+
projectId,
|
|
63
|
+
contextFilePath: defaultContextFilePath,
|
|
64
|
+
};
|
|
65
|
+
existingVariantConfigs[bundle.id] = variantConfig;
|
|
66
|
+
context.config.globalVariants.variantGroups.push(variantConfig);
|
|
67
|
+
} else {
|
|
68
|
+
const contextFilePath = path.join(
|
|
69
|
+
path.dirname(variantConfig.contextFilePath),
|
|
70
|
+
path.basename(defaultContextFilePath)
|
|
71
|
+
);
|
|
72
|
+
if (
|
|
73
|
+
variantConfig.contextFilePath !== contextFilePath &&
|
|
74
|
+
fileExists(context, variantConfig.contextFilePath)
|
|
75
|
+
) {
|
|
76
|
+
if (context.cliArgs.quiet !== true) {
|
|
77
|
+
logger.info(
|
|
78
|
+
`Renaming global variant: ${variantConfig.name} [${projectId}/${bundle.id}]`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
renameFile(context, variantConfig.contextFilePath, contextFilePath);
|
|
82
|
+
variantConfig.contextFilePath = contextFilePath;
|
|
83
|
+
}
|
|
84
|
+
variantConfig.name = bundle.name;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
// Update FileLocks
|
|
88
|
+
if (globalVariantFileLocks[bundle.id]) {
|
|
89
|
+
globalVariantFileLocks[bundle.id].checksum = ensure(
|
|
90
|
+
id2VariantChecksum.get(bundle.id)
|
|
91
|
+
);
|
|
92
|
+
} else {
|
|
93
|
+
projectLock.fileLocks.push({
|
|
94
|
+
type: "globalVariant",
|
|
95
|
+
assetId: bundle.id,
|
|
96
|
+
checksum: ensure(id2VariantChecksum.get(bundle.id)),
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
await writeFileContent(
|
|
101
|
+
context,
|
|
102
|
+
variantConfig.contextFilePath,
|
|
103
|
+
formatAsLocal(bundle.contextModule, variantConfig.contextFilePath, baseDir),
|
|
104
|
+
{ force: !isNew }
|
|
105
|
+
);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
const deletedVariantsFiles = new Set<string>();
|
|
109
|
+
for (const deletedGlobalVariant of deletedGlobalVariants) {
|
|
110
|
+
const variantConfig = existingVariantConfigs[deletedGlobalVariant.id];
|
|
111
|
+
if (fileExists(context, variantConfig.contextFilePath)) {
|
|
112
|
+
logger.info(
|
|
113
|
+
`Deleting global variant: ${variantConfig.name} [${projectId}/${deletedGlobalVariant.id}]`
|
|
114
|
+
);
|
|
115
|
+
deleteFile(context, variantConfig.contextFilePath);
|
|
116
|
+
deletedVariantsFiles.add(deletedGlobalVariant.id);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
context.config.globalVariants.variantGroups = context.config.globalVariants.variantGroups.filter(
|
|
120
|
+
(v) => !deletedVariantsFiles.has(v.id)
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
const deletedVariantIds = new Set(deletedGlobalVariants.map((i) => i.id));
|
|
124
|
+
projectLock.fileLocks = projectLock.fileLocks.filter(
|
|
125
|
+
(fileLock) =>
|
|
126
|
+
fileLock.type !== "globalVariant" ||
|
|
127
|
+
!deletedVariantIds.has(fileLock.assetId)
|
|
128
|
+
);
|
|
129
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import L from "lodash";
|
|
2
|
+
import path from "upath";
|
|
3
|
+
import { CommonArgs } from "..";
|
|
4
|
+
import { ChecksumBundle, IconBundle } from "../api";
|
|
5
|
+
import { logger } from "../deps";
|
|
6
|
+
import { formatAsLocal } from "../utils/code-utils";
|
|
7
|
+
import {
|
|
8
|
+
getOrAddProjectConfig,
|
|
9
|
+
getOrAddProjectLock,
|
|
10
|
+
PlasmicContext,
|
|
11
|
+
} from "../utils/config-utils";
|
|
12
|
+
import {
|
|
13
|
+
defaultResourcePath,
|
|
14
|
+
deleteFile,
|
|
15
|
+
fileExists,
|
|
16
|
+
renameFile,
|
|
17
|
+
writeFileContent,
|
|
18
|
+
} from "../utils/file-utils";
|
|
19
|
+
import { ensure } from "../utils/lang-utils";
|
|
20
|
+
|
|
21
|
+
export interface SyncIconsArgs extends CommonArgs {
|
|
22
|
+
projects: readonly string[];
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export async function syncProjectIconAssets(
|
|
26
|
+
context: PlasmicContext,
|
|
27
|
+
projectId: string,
|
|
28
|
+
version: string,
|
|
29
|
+
iconBundles: IconBundle[],
|
|
30
|
+
checksums: ChecksumBundle,
|
|
31
|
+
baseDir: string,
|
|
32
|
+
) {
|
|
33
|
+
const project = getOrAddProjectConfig(context, projectId);
|
|
34
|
+
if (!project.icons) {
|
|
35
|
+
project.icons = [];
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const projectLock = getOrAddProjectLock(context, projectId);
|
|
39
|
+
const knownIconConfigs = L.keyBy(project.icons, (i) => i.id);
|
|
40
|
+
const iconFileLocks = L.keyBy(
|
|
41
|
+
projectLock.fileLocks.filter((fileLock) => fileLock.type === "icon"),
|
|
42
|
+
(fl) => fl.assetId
|
|
43
|
+
);
|
|
44
|
+
const id2IconChecksum = new Map(checksums.iconChecksums);
|
|
45
|
+
|
|
46
|
+
const iconBundleIds = L.keyBy(iconBundles, (i) => i.id);
|
|
47
|
+
const deletedIcons = L.filter(
|
|
48
|
+
knownIconConfigs,
|
|
49
|
+
(i) => !iconBundleIds[i.id] && !id2IconChecksum.has(i.id)
|
|
50
|
+
);
|
|
51
|
+
|
|
52
|
+
for (const bundle of iconBundles) {
|
|
53
|
+
if (context.cliArgs.quiet !== true) {
|
|
54
|
+
logger.info(
|
|
55
|
+
`Syncing icon: ${bundle.name}@${version}\t['${project.projectName}' ${project.projectId}/${bundle.id} ${project.version}]`
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
let iconConfig = knownIconConfigs[bundle.id];
|
|
59
|
+
const isNew = !iconConfig;
|
|
60
|
+
const defaultModuleFilePath = defaultResourcePath(
|
|
61
|
+
context,
|
|
62
|
+
project,
|
|
63
|
+
"icons",
|
|
64
|
+
bundle.fileName
|
|
65
|
+
);
|
|
66
|
+
if (isNew) {
|
|
67
|
+
iconConfig = {
|
|
68
|
+
id: bundle.id,
|
|
69
|
+
name: bundle.name,
|
|
70
|
+
moduleFilePath: defaultModuleFilePath,
|
|
71
|
+
};
|
|
72
|
+
knownIconConfigs[bundle.id] = iconConfig;
|
|
73
|
+
project.icons.push(iconConfig);
|
|
74
|
+
} else {
|
|
75
|
+
const moduleFilePath = path.join(
|
|
76
|
+
path.dirname(iconConfig.moduleFilePath),
|
|
77
|
+
path.basename(defaultModuleFilePath)
|
|
78
|
+
);
|
|
79
|
+
if (
|
|
80
|
+
iconConfig.moduleFilePath !== moduleFilePath &&
|
|
81
|
+
fileExists(context, iconConfig.moduleFilePath)
|
|
82
|
+
) {
|
|
83
|
+
if (context.cliArgs.quiet !== true) {
|
|
84
|
+
logger.info(
|
|
85
|
+
`Renaming icon: ${iconConfig.name}@${version}\t['${project.projectName}' ${project.projectId}/${bundle.id} ${project.version}]`
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
renameFile(context, iconConfig.moduleFilePath, moduleFilePath);
|
|
89
|
+
iconConfig.moduleFilePath = moduleFilePath;
|
|
90
|
+
}
|
|
91
|
+
iconConfig.name = bundle.name;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Update FileLocks
|
|
95
|
+
if (iconFileLocks[bundle.id]) {
|
|
96
|
+
iconFileLocks[bundle.id].checksum = ensure(
|
|
97
|
+
id2IconChecksum.get(bundle.id)
|
|
98
|
+
);
|
|
99
|
+
} else {
|
|
100
|
+
projectLock.fileLocks.push({
|
|
101
|
+
type: "icon",
|
|
102
|
+
assetId: bundle.id,
|
|
103
|
+
checksum: ensure(id2IconChecksum.get(bundle.id)),
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
await writeFileContent(
|
|
108
|
+
context,
|
|
109
|
+
iconConfig.moduleFilePath,
|
|
110
|
+
formatAsLocal(bundle.module, iconConfig.moduleFilePath, baseDir),
|
|
111
|
+
{
|
|
112
|
+
force: !isNew,
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const deletedIconFiles = new Set<string>();
|
|
118
|
+
for (const deletedIcon of deletedIcons) {
|
|
119
|
+
const iconConfig = knownIconConfigs[deletedIcon.id];
|
|
120
|
+
if (fileExists(context, iconConfig.moduleFilePath)) {
|
|
121
|
+
logger.info(
|
|
122
|
+
`Deleting icon: ${iconConfig.name}@${version}\t['${project.projectName}' ${project.projectId}/${deletedIcon.id} ${project.version}]`
|
|
123
|
+
);
|
|
124
|
+
deleteFile(context, iconConfig.moduleFilePath);
|
|
125
|
+
deletedIconFiles.add(deletedIcon.id);
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
project.icons = project.icons.filter((i) => !deletedIconFiles.has(i.id));
|
|
129
|
+
|
|
130
|
+
const deletedIconIds = new Set(deletedIcons.map((i) => i.id));
|
|
131
|
+
projectLock.fileLocks = projectLock.fileLocks.filter(
|
|
132
|
+
(fileLock) =>
|
|
133
|
+
fileLock.type !== "icon" || !deletedIconIds.has(fileLock.assetId)
|
|
134
|
+
);
|
|
135
|
+
}
|