@plasmicapp/cli 0.1.304 → 0.1.305
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/actions/export.d.ts +16 -0
- package/dist/actions/localization-strings.d.ts +9 -0
- package/dist/actions/sync-global-contexts.d.ts +1 -0
- package/dist/actions/sync-images.d.ts +1 -0
- package/dist/actions/sync.d.ts +0 -1
- package/dist/api.d.ts +22 -1
- package/dist/index.js +3581 -3320
- package/dist/lib.js +23 -44
- package/dist/utils/config-utils.d.ts +1 -11
- package/dist/utils/get-context.d.ts +6 -1
- package/dist/utils/test-utils.d.ts +1 -3
- package/package.json +2 -2
- package/src/__tests__/project-api-token-spec.ts +0 -51
- package/src/actions/export.ts +326 -0
- package/src/actions/localization-strings.ts +19 -0
- package/src/actions/sync-components.ts +1 -1
- package/src/actions/sync-global-contexts.ts +1 -0
- package/src/actions/sync-images.ts +1 -1
- package/src/actions/sync.ts +2 -55
- package/src/api.ts +34 -1
- package/src/index.ts +34 -20
- package/src/test-common/fixtures.ts +3 -4
- package/src/utils/config-utils.ts +0 -11
- package/src/utils/error.ts +2 -2
- package/src/utils/get-context.ts +7 -2
- package/src/utils/test-utils.ts +0 -10
package/dist/lib.js
CHANGED
|
@@ -731539,7 +731539,7 @@ var handleError = (p) => {
|
|
|
731539
731539
|
return p.catch((e) => {
|
|
731540
731540
|
if (e.message) {
|
|
731541
731541
|
logger.error(
|
|
731542
|
-
import_chalk.default.bold(import_chalk.default.redBright("\nPlasmic error: ")) + e.message
|
|
731542
|
+
import_chalk.default.bold(import_chalk.default.redBright("\nPlasmic error: ")) + e.message + e.stack
|
|
731543
731543
|
);
|
|
731544
731544
|
}
|
|
731545
731545
|
if (checkEngineStrict()) {
|
|
@@ -731557,7 +731557,6 @@ var DEFAULT_HOST = process.env.PLASMIC_DEFAULT_HOST || "https://studio.plasmic.a
|
|
|
731557
731557
|
var AUTH_FILE_NAME = ".plasmic.auth";
|
|
731558
731558
|
var CONFIG_FILE_NAME = "plasmic.json";
|
|
731559
731559
|
var LOCK_FILE_NAME = "plasmic.lock";
|
|
731560
|
-
var LOADER_CONFIG_FILE_NAME = "plasmic-loader.json";
|
|
731561
731560
|
var ENV_AUTH_HOST = "PLASMIC_AUTH_HOST";
|
|
731562
731561
|
var ENV_AUTH_USER = "PLASMIC_AUTH_USER";
|
|
731563
731562
|
var ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
|
|
@@ -731782,6 +731781,20 @@ var PlasmicApi = class {
|
|
|
731782
731781
|
);
|
|
731783
731782
|
return result.data;
|
|
731784
731783
|
}
|
|
731784
|
+
/**
|
|
731785
|
+
* Code-gen endpoint.
|
|
731786
|
+
* This will fetch components from a given branch at an exact specified version
|
|
731787
|
+
* using the "plain" scheme
|
|
731788
|
+
*/
|
|
731789
|
+
async exportProject(projectId, branchName, opts) {
|
|
731790
|
+
const result = await this.post(
|
|
731791
|
+
`${this.codegenHost}/api/v1/projects/${projectId}/code/components?branchName=${branchName}&export=true`,
|
|
731792
|
+
{
|
|
731793
|
+
...opts
|
|
731794
|
+
}
|
|
731795
|
+
);
|
|
731796
|
+
return result.data;
|
|
731797
|
+
}
|
|
731785
731798
|
async projectMeta(projectId) {
|
|
731786
731799
|
const result = await this.post(
|
|
731787
731800
|
`${this.codegenHost}/api/v1/projects/${projectId}/code/meta`
|
|
@@ -733060,7 +733073,8 @@ async function resolveMissingFilesInConfig(context, config) {
|
|
|
733060
733073
|
}
|
|
733061
733074
|
async function getContext(args, {
|
|
733062
733075
|
enableSkipAuth = false,
|
|
733063
|
-
skipMissingFiles = false
|
|
733076
|
+
skipMissingFiles = false,
|
|
733077
|
+
skipInit = false
|
|
733064
733078
|
} = {}) {
|
|
733065
733079
|
if (!args.baseDir)
|
|
733066
733080
|
args.baseDir = process.cwd();
|
|
@@ -734149,25 +734163,7 @@ async function ensureRequiredPackages(context, baseDir, yes) {
|
|
|
734149
734163
|
}
|
|
734150
734164
|
}
|
|
734151
734165
|
}
|
|
734152
|
-
function getLoaderConfigPath(opts) {
|
|
734153
|
-
return opts.loaderConfig || LOADER_CONFIG_FILE_NAME;
|
|
734154
|
-
}
|
|
734155
|
-
function maybeReadLoaderConfig(opts) {
|
|
734156
|
-
const path14 = getLoaderConfigPath(opts);
|
|
734157
|
-
if (!existsBuffered(path14)) {
|
|
734158
|
-
return {};
|
|
734159
|
-
}
|
|
734160
|
-
return JSON.parse(readFileText(path14));
|
|
734161
|
-
}
|
|
734162
|
-
function writeLoaderConfig(opts, config) {
|
|
734163
|
-
const loaderConfigPath = getLoaderConfigPath(opts);
|
|
734164
|
-
writeFileText(
|
|
734165
|
-
loaderConfigPath,
|
|
734166
|
-
formatAsLocal(JSON.stringify(config), loaderConfigPath, opts.baseDir)
|
|
734167
|
-
);
|
|
734168
|
-
}
|
|
734169
734166
|
async function sync(opts, metadataDefaults) {
|
|
734170
|
-
var _a;
|
|
734171
734167
|
if (!opts.baseDir)
|
|
734172
734168
|
opts.baseDir = process.cwd();
|
|
734173
734169
|
const baseDir = opts.baseDir;
|
|
@@ -734181,18 +734177,17 @@ async function sync(opts, metadataDefaults) {
|
|
|
734181
734177
|
}
|
|
734182
734178
|
fixFileExtension(context);
|
|
734183
734179
|
assertAllPathsInRootDir(context);
|
|
734184
|
-
const loaderConfig = process.env.PLASMIC_LOADER ? maybeReadLoaderConfig(opts) : {};
|
|
734185
734180
|
const projectIdToToken = new Map(
|
|
734186
|
-
[...context.config.projects
|
|
734181
|
+
[...context.config.projects].filter((p) => p.projectApiToken).map((p) => tuple(p.projectId, p.projectApiToken))
|
|
734187
734182
|
);
|
|
734188
734183
|
const projectConfigMap = import_lodash17.default.keyBy(context.config.projects, (p) => p.projectId);
|
|
734189
734184
|
const projectWithVersion = opts.projects.map((p) => {
|
|
734190
|
-
var
|
|
734185
|
+
var _a, _b, _c;
|
|
734191
734186
|
const [projectIdToken, versionRange] = p.split("@");
|
|
734192
734187
|
const [projectId, projectApiToken] = projectIdToken.split(":");
|
|
734193
734188
|
return {
|
|
734194
734189
|
projectId,
|
|
734195
|
-
branchName: (_b = (
|
|
734190
|
+
branchName: (_b = (_a = projectConfigMap[projectId]) == null ? void 0 : _a.projectBranchName) != null ? _b : "main",
|
|
734196
734191
|
versionRange: versionRange || ((_c = projectConfigMap[projectId]) == null ? void 0 : _c.version) || "latest",
|
|
734197
734192
|
componentIdOrNames: void 0,
|
|
734198
734193
|
// Get all components!
|
|
@@ -734201,10 +734196,10 @@ async function sync(opts, metadataDefaults) {
|
|
|
734201
734196
|
};
|
|
734202
734197
|
});
|
|
734203
734198
|
const projectSyncParams = projectWithVersion.length ? projectWithVersion : context.config.projects.map((p) => {
|
|
734204
|
-
var
|
|
734199
|
+
var _a;
|
|
734205
734200
|
return {
|
|
734206
734201
|
projectId: p.projectId,
|
|
734207
|
-
branchName: (
|
|
734202
|
+
branchName: (_a = p.projectBranchName) != null ? _a : "main",
|
|
734208
734203
|
versionRange: p.version,
|
|
734209
734204
|
componentIdOrNames: void 0,
|
|
734210
734205
|
// Get all components!
|
|
@@ -734222,7 +734217,7 @@ async function sync(opts, metadataDefaults) {
|
|
|
734222
734217
|
context = await getContext(opts);
|
|
734223
734218
|
} catch (e) {
|
|
734224
734219
|
if (e.message.includes("Unable to authenticate Plasmic")) {
|
|
734225
|
-
const configFileName =
|
|
734220
|
+
const configFileName = CONFIG_FILE_NAME;
|
|
734226
734221
|
throw new HandledError(
|
|
734227
734222
|
`Unable to authenticate Plasmic. Please run 'plasmic auth' or check the projectApiTokens in your ${configFileName}, and try again.`
|
|
734228
734223
|
);
|
|
@@ -734259,7 +734254,6 @@ async function sync(opts, metadataDefaults) {
|
|
|
734259
734254
|
const externalNpmPackages = /* @__PURE__ */ new Set();
|
|
734260
734255
|
const externalCssImports = /* @__PURE__ */ new Set();
|
|
734261
734256
|
const doSync = async () => {
|
|
734262
|
-
var _a2;
|
|
734263
734257
|
for (const projectMeta of projectsToSync) {
|
|
734264
734258
|
await syncProject(
|
|
734265
734259
|
context,
|
|
@@ -734303,21 +734297,6 @@ async function sync(opts, metadataDefaults) {
|
|
|
734303
734297
|
});
|
|
734304
734298
|
}
|
|
734305
734299
|
await fixAllImportStatements(context, opts.baseDir, summary);
|
|
734306
|
-
if (process.env.PLASMIC_LOADER) {
|
|
734307
|
-
const rootProjectIds = new Set(projectSyncParams.map((p) => p.projectId));
|
|
734308
|
-
const freshIdsAndTokens = projectIdsAndTokens.filter((p) => rootProjectIds.has(p.projectId)).map((p) => import_lodash17.default.pick(p, "projectId", "projectApiToken"));
|
|
734309
|
-
const config = {
|
|
734310
|
-
...loaderConfig,
|
|
734311
|
-
projects: import_lodash17.default.sortBy(
|
|
734312
|
-
import_lodash17.default.uniqBy(
|
|
734313
|
-
[...freshIdsAndTokens, ...(_a2 = loaderConfig == null ? void 0 : loaderConfig.projects) != null ? _a2 : []],
|
|
734314
|
-
(p) => p.projectId
|
|
734315
|
-
),
|
|
734316
|
-
(p) => p.projectId
|
|
734317
|
-
)
|
|
734318
|
-
};
|
|
734319
|
-
writeLoaderConfig(opts, config);
|
|
734320
|
-
}
|
|
734321
734300
|
const codegenVersion = await context.api.latestCodegenVersion();
|
|
734322
734301
|
context.lock.projects.forEach((p) => {
|
|
734323
734302
|
if (projectsToSync.some(
|
|
@@ -1,23 +1,13 @@
|
|
|
1
1
|
import { DeepPartial } from "utility-types";
|
|
2
|
-
import { PlasmicApi
|
|
2
|
+
import { PlasmicApi } from "../api";
|
|
3
3
|
export declare const DEFAULT_HOST: string;
|
|
4
4
|
export declare const AUTH_FILE_NAME = ".plasmic.auth";
|
|
5
5
|
export declare const CONFIG_FILE_NAME = "plasmic.json";
|
|
6
6
|
export declare const LOCK_FILE_NAME = "plasmic.lock";
|
|
7
|
-
export declare const LOADER_CONFIG_FILE_NAME = "plasmic-loader.json";
|
|
8
7
|
export declare const CONFIG_SCHEMA_FILE_NAME = "plasmic.schema.json";
|
|
9
8
|
export declare const ENV_AUTH_HOST = "PLASMIC_AUTH_HOST";
|
|
10
9
|
export declare const ENV_AUTH_USER = "PLASMIC_AUTH_USER";
|
|
11
10
|
export declare const ENV_AUTH_TOKEN = "PLASMIC_AUTH_TOKEN";
|
|
12
|
-
export interface PlasmicLoaderConfig {
|
|
13
|
-
projects: ProjectIdAndToken[];
|
|
14
|
-
aboutThisFile: string;
|
|
15
|
-
dir: string;
|
|
16
|
-
plasmicDir: string;
|
|
17
|
-
pageDir: string;
|
|
18
|
-
initArgs: Record<string, string>;
|
|
19
|
-
substitutions?: Record<string, any>;
|
|
20
|
-
}
|
|
21
11
|
export interface PlasmicConfig {
|
|
22
12
|
/** Target platform to generate code for */
|
|
23
13
|
platform: "react" | "nextjs" | "gatsby";
|
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { CommonArgs } from "../index";
|
|
2
2
|
import { PlasmicContext, PlasmicLock } from "./config-utils";
|
|
3
3
|
export declare function readLock(lockFile: string): PlasmicLock;
|
|
4
|
-
export declare function getContext(args: CommonArgs, { enableSkipAuth, skipMissingFiles, }?: {
|
|
4
|
+
export declare function getContext(args: CommonArgs, { enableSkipAuth, skipMissingFiles, skipInit, }?: {
|
|
5
5
|
enableSkipAuth?: boolean;
|
|
6
6
|
skipMissingFiles?: boolean;
|
|
7
|
+
skipInit?: boolean;
|
|
7
8
|
}): Promise<PlasmicContext>;
|
|
9
|
+
/**
|
|
10
|
+
* Use empty user/token to signify no auth (only returning to provide a default host).
|
|
11
|
+
*/
|
|
12
|
+
export declare function getCurrentOrDefaultAuth(args: CommonArgs): Promise<import("./config-utils").AuthConfig>;
|
|
8
13
|
/**
|
|
9
14
|
* Table of where this metadata will be set
|
|
10
15
|
*
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as tmp from "tmp";
|
|
2
|
-
import { AuthConfig, PlasmicConfig
|
|
2
|
+
import { AuthConfig, PlasmicConfig } from "../utils/config-utils";
|
|
3
3
|
export declare class TempRepo {
|
|
4
4
|
tmpDir: tmp.DirResult;
|
|
5
5
|
constructor();
|
|
@@ -17,6 +17,4 @@ export declare class TempRepo {
|
|
|
17
17
|
readPlasmicJson(): PlasmicConfig;
|
|
18
18
|
writePlasmicJson(json: PlasmicConfig): void;
|
|
19
19
|
deletePlasmicJson(): void;
|
|
20
|
-
plasmicLoaderJsonPath(): string;
|
|
21
|
-
readPlasmicLoaderJson(): PlasmicLoaderConfig;
|
|
22
20
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@plasmicapp/cli",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.305",
|
|
4
4
|
"description": "plasmic cli for syncing local code with Plasmic designs",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=12"
|
|
@@ -78,5 +78,5 @@
|
|
|
78
78
|
"wrap-ansi": "^7.0.0",
|
|
79
79
|
"yargs": "^15.4.1"
|
|
80
80
|
},
|
|
81
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "f1d5f4fddc0f8d528cffb91a803501e51c877b42"
|
|
82
82
|
}
|
|
@@ -158,55 +158,4 @@ describe("Project API tokens", () => {
|
|
|
158
158
|
});
|
|
159
159
|
await expect(sync(opts)).rejects.toThrow("Unable to authenticate");
|
|
160
160
|
});
|
|
161
|
-
|
|
162
|
-
test("should use plasmic-loader.json for API tokens in loader mode", async () => {
|
|
163
|
-
process.env.PLASMIC_LOADER = "1";
|
|
164
|
-
|
|
165
|
-
opts.projects = ["projectId1"];
|
|
166
|
-
await expect(sync(opts)).resolves.toBeUndefined();
|
|
167
|
-
|
|
168
|
-
const loaderConfig = tmpRepo.readPlasmicLoaderJson();
|
|
169
|
-
expect(loaderConfig).toEqual({
|
|
170
|
-
projects: [
|
|
171
|
-
{
|
|
172
|
-
projectId: "projectId1",
|
|
173
|
-
projectApiToken: "abc",
|
|
174
|
-
},
|
|
175
|
-
],
|
|
176
|
-
});
|
|
177
|
-
|
|
178
|
-
// Re-run, this time with no auth and no tokens in plasmic.json, only in plasmic-loader.json.
|
|
179
|
-
removeAuth();
|
|
180
|
-
tmpRepo.writePlasmicJson(defaultPlasmicJson);
|
|
181
|
-
await expect(sync(opts)).resolves.toBeUndefined();
|
|
182
|
-
|
|
183
|
-
delete process.env["PLASMIC_LOADER"];
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
test("works in PlasmicLoader mode even if root project was determined to not need an update", async () => {
|
|
187
|
-
process.env.PLASMIC_LOADER = "1";
|
|
188
|
-
|
|
189
|
-
// Make project1 have a dependency.
|
|
190
|
-
standardTestSetup();
|
|
191
|
-
|
|
192
|
-
// Explicitly sync both - we had a bug writing back the plasmic-loader.json in this case.
|
|
193
|
-
opts.projects = ["projectId1", "dependencyId1"];
|
|
194
|
-
await expect(sync(opts)).resolves.toBeUndefined();
|
|
195
|
-
|
|
196
|
-
// We sync project1 which got updated, but the dependency is still same version.
|
|
197
|
-
opts.force = false;
|
|
198
|
-
removeAuth();
|
|
199
|
-
mockApi.getMockProject("projectId1", "main", "1.2.3").version = "1.2.4";
|
|
200
|
-
await expect(sync(opts)).resolves.toBeUndefined();
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("should fail in loader mode if not available", async () => {
|
|
204
|
-
process.env.PLASMIC_LOADER = "1";
|
|
205
|
-
|
|
206
|
-
opts.projects = ["projectId1"];
|
|
207
|
-
removeAuth();
|
|
208
|
-
await expect(sync(opts)).rejects.toThrow();
|
|
209
|
-
|
|
210
|
-
delete process.env["PLASMIC_LOADER"];
|
|
211
|
-
});
|
|
212
161
|
});
|
|
@@ -0,0 +1,326 @@
|
|
|
1
|
+
import { keyBy, snakeCase } from "lodash";
|
|
2
|
+
import { CommonArgs } from "..";
|
|
3
|
+
import { ComponentBundle, PlasmicApi, ProjectBundle } from "../api";
|
|
4
|
+
import {
|
|
5
|
+
CodeConfig,
|
|
6
|
+
I18NConfig,
|
|
7
|
+
ImagesConfig,
|
|
8
|
+
PlasmicConfig,
|
|
9
|
+
StyleConfig,
|
|
10
|
+
findConfigFile,
|
|
11
|
+
} from "../utils/config-utils";
|
|
12
|
+
import { getContext, getCurrentOrDefaultAuth } from "../utils/get-context";
|
|
13
|
+
import { tuple } from "../utils/lang-utils";
|
|
14
|
+
import {
|
|
15
|
+
fixAllImportStatements,
|
|
16
|
+
formatAsLocal,
|
|
17
|
+
maybeConvertTsxToJsx,
|
|
18
|
+
} from "../utils/code-utils";
|
|
19
|
+
import { promises as fs, write } from "fs";
|
|
20
|
+
import path from "path";
|
|
21
|
+
import { DEFAULT_GLOBAL_CONTEXTS_NAME } from "./sync-global-contexts";
|
|
22
|
+
import { ensureImageAssetContents } from "./sync-images";
|
|
23
|
+
import { logger } from "../deps";
|
|
24
|
+
|
|
25
|
+
export interface ExportArgs extends CommonArgs {
|
|
26
|
+
projects: readonly string[];
|
|
27
|
+
platform: "" | "react" | "nextjs" | "gatsby";
|
|
28
|
+
codeLang: "" | "ts" | "js";
|
|
29
|
+
styleScheme: "" | "css" | "css-modules";
|
|
30
|
+
imagesScheme: "" | "inlined" | "files" | "public-files";
|
|
31
|
+
imagesPublicDir: string;
|
|
32
|
+
imagesPublicUrlPrefix: string;
|
|
33
|
+
i18nKeyScheme: "" | I18NConfig["keyScheme"];
|
|
34
|
+
i18nTagPrefix: "" | I18NConfig["tagPrefix"];
|
|
35
|
+
|
|
36
|
+
skipFormatting?: boolean;
|
|
37
|
+
|
|
38
|
+
outDir: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export async function exportProjectsCli(opts: ExportArgs): Promise<void> {
|
|
42
|
+
if (!opts.baseDir) opts.baseDir = process.cwd();
|
|
43
|
+
let configFile =
|
|
44
|
+
opts.config || findConfigFile(opts.baseDir, { traverseParents: true });
|
|
45
|
+
let context = configFile
|
|
46
|
+
? await getContext(opts, { enableSkipAuth: true })
|
|
47
|
+
: undefined;
|
|
48
|
+
const projectConfigMap = keyBy(
|
|
49
|
+
context?.config.projects ?? [],
|
|
50
|
+
(p) => p.projectId
|
|
51
|
+
);
|
|
52
|
+
const projectIdToToken = new Map(
|
|
53
|
+
[...(context?.config.projects ?? [])]
|
|
54
|
+
.filter((p) => p.projectApiToken)
|
|
55
|
+
.map((p) => tuple(p.projectId, p.projectApiToken))
|
|
56
|
+
);
|
|
57
|
+
const projectWithVersion = opts.projects.map((p) => {
|
|
58
|
+
const [projectIdToken, versionRange] = p.split("@");
|
|
59
|
+
const [projectId, projectApiToken] = projectIdToken.split(":");
|
|
60
|
+
return {
|
|
61
|
+
projectId,
|
|
62
|
+
branchName: projectConfigMap[projectId]?.projectBranchName ?? "main",
|
|
63
|
+
versionRange:
|
|
64
|
+
versionRange || projectConfigMap[projectId]?.version || "latest",
|
|
65
|
+
componentIdOrNames: undefined, // Get all components!
|
|
66
|
+
projectApiToken: projectApiToken || projectIdToToken.get(projectId),
|
|
67
|
+
indirect: false,
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
const auth = await getCurrentOrDefaultAuth(opts);
|
|
72
|
+
const api = new PlasmicApi(auth);
|
|
73
|
+
const result = await exportProjects(api, {
|
|
74
|
+
projects: projectWithVersion.map((p) => ({
|
|
75
|
+
id: p.projectId,
|
|
76
|
+
token: p.projectApiToken,
|
|
77
|
+
branchName: p.branchName,
|
|
78
|
+
version: p.versionRange,
|
|
79
|
+
})),
|
|
80
|
+
platform: opts.platform || "react",
|
|
81
|
+
codeOpts: { lang: opts.codeLang || "ts" },
|
|
82
|
+
stylesOpts: { scheme: opts.styleScheme || "css-modules" },
|
|
83
|
+
imageOpts: { scheme: opts.imagesScheme || "files" },
|
|
84
|
+
i18nOpts: opts.i18nKeyScheme
|
|
85
|
+
? { keyScheme: opts.i18nKeyScheme, tagPrefix: opts.i18nTagPrefix }
|
|
86
|
+
: undefined,
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
const extx = opts.codeLang === "js" ? "jsx" : "tsx";
|
|
90
|
+
|
|
91
|
+
const writeProj = async (bundle: ProjectBundle) => {
|
|
92
|
+
await ensureImageAssetContents(bundle.imageAssets);
|
|
93
|
+
const outPath = path.resolve(opts.outDir);
|
|
94
|
+
const promises: Promise<void>[] = [];
|
|
95
|
+
const writeFile = (fileName: string, content: string | Buffer) => {
|
|
96
|
+
if (typeof content === "string" && !opts.skipFormatting) {
|
|
97
|
+
content = formatAsLocal(content, fileName, opts.outDir);
|
|
98
|
+
}
|
|
99
|
+
const projectName = snakeCase(bundle.projectConfig.projectName);
|
|
100
|
+
promises.push(
|
|
101
|
+
(async () => {
|
|
102
|
+
await fs.mkdir(path.join(outPath, projectName), { recursive: true });
|
|
103
|
+
await fs.writeFile(
|
|
104
|
+
path.join(outPath, projectName, fileName),
|
|
105
|
+
content
|
|
106
|
+
);
|
|
107
|
+
})()
|
|
108
|
+
);
|
|
109
|
+
};
|
|
110
|
+
for (const comp of bundle.components) {
|
|
111
|
+
writeFile(comp.skeletonModuleFileName, comp.skeletonModule);
|
|
112
|
+
writeFile(comp.cssFileName, comp.cssRules);
|
|
113
|
+
}
|
|
114
|
+
for (const icon of bundle.iconAssets) {
|
|
115
|
+
writeFile(icon.fileName, icon.module);
|
|
116
|
+
}
|
|
117
|
+
for (const gv of bundle.globalVariants) {
|
|
118
|
+
writeFile(gv.contextFileName, gv.contextModule);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
for (const img of bundle.imageAssets) {
|
|
122
|
+
writeFile(img.fileName, Buffer.from(img.blob, "base64"));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
writeFile(bundle.projectConfig.cssFileName, bundle.projectConfig.cssRules);
|
|
126
|
+
if (bundle.projectConfig.globalContextBundle) {
|
|
127
|
+
writeFile(
|
|
128
|
+
`${DEFAULT_GLOBAL_CONTEXTS_NAME}.${extx}`,
|
|
129
|
+
bundle.projectConfig.globalContextBundle.contextModule
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
await Promise.all(promises);
|
|
134
|
+
};
|
|
135
|
+
|
|
136
|
+
await Promise.all(result.map((res) => writeProj(res)));
|
|
137
|
+
|
|
138
|
+
await fixAllImportStatements(
|
|
139
|
+
{
|
|
140
|
+
configFile: "",
|
|
141
|
+
lockFile: "",
|
|
142
|
+
rootDir: path.resolve(opts.outDir),
|
|
143
|
+
absoluteSrcDir: path.resolve(opts.outDir),
|
|
144
|
+
config: {
|
|
145
|
+
platform: opts.platform || "react",
|
|
146
|
+
srcDir: "./",
|
|
147
|
+
defaultPlasmicDir: "./",
|
|
148
|
+
code: {
|
|
149
|
+
lang: opts.codeLang || "ts",
|
|
150
|
+
scheme: "blackbox",
|
|
151
|
+
reactRuntime: "classic",
|
|
152
|
+
},
|
|
153
|
+
images: {
|
|
154
|
+
scheme: opts.imagesScheme || "files",
|
|
155
|
+
publicDir: opts.imagesPublicDir,
|
|
156
|
+
publicUrlPrefix: opts.imagesPublicUrlPrefix,
|
|
157
|
+
},
|
|
158
|
+
style: {
|
|
159
|
+
scheme: opts.styleScheme || "css-modules",
|
|
160
|
+
defaultStyleCssFilePath: "",
|
|
161
|
+
},
|
|
162
|
+
tokens: {} as any,
|
|
163
|
+
globalVariants: {
|
|
164
|
+
variantGroups: result.flatMap((bundle) => {
|
|
165
|
+
const projectName = snakeCase(bundle.projectConfig.projectName);
|
|
166
|
+
return bundle.globalVariants.map((gv) => ({
|
|
167
|
+
id: gv.id,
|
|
168
|
+
name: gv.name,
|
|
169
|
+
projectId: bundle.projectConfig.projectId,
|
|
170
|
+
contextFilePath: `./${projectName}/${gv.contextFileName}`,
|
|
171
|
+
}));
|
|
172
|
+
}),
|
|
173
|
+
},
|
|
174
|
+
projects: result.map((bundle) => {
|
|
175
|
+
const projectName = snakeCase(bundle.projectConfig.projectName);
|
|
176
|
+
return {
|
|
177
|
+
projectId: bundle.projectConfig.projectId,
|
|
178
|
+
projectName: bundle.projectConfig.projectName,
|
|
179
|
+
version: "latest",
|
|
180
|
+
cssFilePath: `${projectName}/${bundle.projectConfig.cssFileName}`,
|
|
181
|
+
globalContextsFilePath: bundle.projectConfig.globalContextBundle
|
|
182
|
+
? `${projectName}/${DEFAULT_GLOBAL_CONTEXTS_NAME}.${extx}`
|
|
183
|
+
: "",
|
|
184
|
+
components: bundle.components.map((comp) => ({
|
|
185
|
+
id: comp.id,
|
|
186
|
+
name: comp.componentName,
|
|
187
|
+
projectId: bundle.projectConfig.projectId,
|
|
188
|
+
type: "managed",
|
|
189
|
+
importSpec: {
|
|
190
|
+
modulePath: `${projectName}/${comp.skeletonModuleFileName}`,
|
|
191
|
+
},
|
|
192
|
+
renderModuleFilePath: `${projectName}/${comp.skeletonModuleFileName}`,
|
|
193
|
+
cssFilePath: `${projectName}/${comp.cssFileName}`,
|
|
194
|
+
scheme: "blackbox",
|
|
195
|
+
componentType: `${comp.isPage ? "page" : "component"}`,
|
|
196
|
+
plumeType: comp.plumeType,
|
|
197
|
+
})),
|
|
198
|
+
codeComponents: bundle.codeComponentMetas.map((comp) => ({
|
|
199
|
+
id: comp.id,
|
|
200
|
+
name: comp.name,
|
|
201
|
+
displayName: comp.displayName,
|
|
202
|
+
componentImportPath: comp.importPath,
|
|
203
|
+
helper: comp.helper,
|
|
204
|
+
})),
|
|
205
|
+
icons: bundle.iconAssets.map((icon) => ({
|
|
206
|
+
id: icon.id,
|
|
207
|
+
name: icon.name,
|
|
208
|
+
moduleFilePath: `${projectName}/${icon.fileName}`,
|
|
209
|
+
})),
|
|
210
|
+
images: bundle.imageAssets.map((image) => ({
|
|
211
|
+
id: image.id,
|
|
212
|
+
name: image.name,
|
|
213
|
+
filePath: `${projectName}/${image.fileName}`,
|
|
214
|
+
})),
|
|
215
|
+
indirect: false,
|
|
216
|
+
};
|
|
217
|
+
}),
|
|
218
|
+
wrapPagesWithGlobalContexts: true,
|
|
219
|
+
},
|
|
220
|
+
lock: {} as any,
|
|
221
|
+
auth: {} as any,
|
|
222
|
+
api: api,
|
|
223
|
+
cliArgs: {} as any,
|
|
224
|
+
},
|
|
225
|
+
opts.outDir
|
|
226
|
+
);
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
interface ExportOpts {
|
|
230
|
+
projects: {
|
|
231
|
+
id: string;
|
|
232
|
+
token?: string;
|
|
233
|
+
branchName?: string;
|
|
234
|
+
version?: string;
|
|
235
|
+
}[];
|
|
236
|
+
platform?: PlasmicConfig["platform"];
|
|
237
|
+
imageOpts?: ImagesConfig;
|
|
238
|
+
stylesOpts?: Omit<StyleConfig, "defaultStyleCssFilePath">;
|
|
239
|
+
i18nOpts?: I18NConfig;
|
|
240
|
+
codeOpts?: Omit<CodeConfig, "scheme" | "reactRuntime">;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
async function exportProjects(api: PlasmicApi, opts: ExportOpts) {
|
|
244
|
+
api.attachProjectIdsAndTokens(
|
|
245
|
+
opts.projects.map((proj) => ({
|
|
246
|
+
projectId: proj.id,
|
|
247
|
+
projectApiToken: proj.token,
|
|
248
|
+
}))
|
|
249
|
+
);
|
|
250
|
+
|
|
251
|
+
const versionResolution = await api.resolveSync(
|
|
252
|
+
opts.projects.map((p) => ({
|
|
253
|
+
projectId: p.id,
|
|
254
|
+
branchName: p.branchName ?? "main",
|
|
255
|
+
versionRange: p.version,
|
|
256
|
+
componentIdOrNames: undefined,
|
|
257
|
+
projectApiToken: p.token,
|
|
258
|
+
indirect: false,
|
|
259
|
+
})),
|
|
260
|
+
true
|
|
261
|
+
);
|
|
262
|
+
|
|
263
|
+
const versionsToSync = [
|
|
264
|
+
...versionResolution.dependencies,
|
|
265
|
+
...versionResolution.projects,
|
|
266
|
+
];
|
|
267
|
+
|
|
268
|
+
const result = await Promise.all(
|
|
269
|
+
versionsToSync.map(async (v) => {
|
|
270
|
+
return api.exportProject(v.projectId, v.branchName, {
|
|
271
|
+
platform: opts.platform ?? "react",
|
|
272
|
+
platformOptions: {},
|
|
273
|
+
version: v.version,
|
|
274
|
+
imageOpts: opts.imageOpts ?? {
|
|
275
|
+
scheme: "files",
|
|
276
|
+
},
|
|
277
|
+
stylesOpts: {
|
|
278
|
+
defaultStyleCssFilePath: "",
|
|
279
|
+
scheme: "css-modules",
|
|
280
|
+
...opts.stylesOpts,
|
|
281
|
+
},
|
|
282
|
+
i18nOpts: opts.i18nOpts,
|
|
283
|
+
codeOpts: opts.codeOpts ?? { lang: "ts" },
|
|
284
|
+
indirect: v.indirect,
|
|
285
|
+
wrapPagesWithGlobalContexts: true,
|
|
286
|
+
});
|
|
287
|
+
})
|
|
288
|
+
);
|
|
289
|
+
|
|
290
|
+
if (opts.codeOpts?.lang === "js") {
|
|
291
|
+
for (const proj of result) {
|
|
292
|
+
for (const comp of proj.components) {
|
|
293
|
+
[comp.skeletonModuleFileName, comp.skeletonModule] =
|
|
294
|
+
maybeConvertTsxToJsx(
|
|
295
|
+
comp.skeletonModuleFileName,
|
|
296
|
+
comp.skeletonModule,
|
|
297
|
+
"."
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
for (const icon of proj.iconAssets) {
|
|
301
|
+
[icon.fileName, icon.module] = maybeConvertTsxToJsx(
|
|
302
|
+
icon.fileName,
|
|
303
|
+
icon.module,
|
|
304
|
+
"."
|
|
305
|
+
);
|
|
306
|
+
}
|
|
307
|
+
for (const gv of proj.globalVariants) {
|
|
308
|
+
[gv.contextFileName, gv.contextModule] = maybeConvertTsxToJsx(
|
|
309
|
+
gv.contextFileName,
|
|
310
|
+
gv.contextModule,
|
|
311
|
+
"."
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
if (proj.projectConfig.globalContextBundle) {
|
|
315
|
+
const res = maybeConvertTsxToJsx(
|
|
316
|
+
`${DEFAULT_GLOBAL_CONTEXTS_NAME}.tsx`,
|
|
317
|
+
proj.projectConfig.globalContextBundle.contextModule,
|
|
318
|
+
"."
|
|
319
|
+
);
|
|
320
|
+
proj.projectConfig.globalContextBundle.contextModule = res[1];
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
return result;
|
|
326
|
+
}
|
|
@@ -22,6 +22,25 @@ export interface LocalizationStringsArgs extends CommonArgs {
|
|
|
22
22
|
excludeDeps: boolean | undefined;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
export function getLocalizationYargs(key: "key-scheme" | "tag-prefix") {
|
|
26
|
+
if (key === "key-scheme") {
|
|
27
|
+
return {
|
|
28
|
+
describe:
|
|
29
|
+
"What value to use as message keys; `content` uses the message content itself, `hash` uses a hash of the content, and `path` uses a a hierarchical string containing the project id, component name, element name, and related variants, and does not encode the text content in the key. Defaults to whatever is specified in plasmic.json, or `content`",
|
|
30
|
+
type: "string" as const,
|
|
31
|
+
choices: ["content", "hash", "path"],
|
|
32
|
+
};
|
|
33
|
+
} else if (key === "tag-prefix") {
|
|
34
|
+
return {
|
|
35
|
+
describe:
|
|
36
|
+
"By default, rich text with markup tags look like '<0>hello</0>'. If your localization framework requires num-numeric tags, then specify a prefix; for example a prefix of 'n' turns it into '<n0>hello</n0>'.",
|
|
37
|
+
type: "string" as const,
|
|
38
|
+
};
|
|
39
|
+
} else {
|
|
40
|
+
throw new Error(`Unexpected localization option ${key}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
|
|
25
44
|
export async function localizationStrings(
|
|
26
45
|
opts: LocalizationStringsArgs
|
|
27
46
|
): Promise<void> {
|
|
@@ -233,7 +233,7 @@ export async function syncProjectComponents(
|
|
|
233
233
|
|
|
234
234
|
compConfig.plumeType = plumeType;
|
|
235
235
|
|
|
236
|
-
if (scheme === "direct") {
|
|
236
|
+
if ((scheme as any) === "direct") {
|
|
237
237
|
throw new Error(`Direct update codegen scheme is no longer supported`);
|
|
238
238
|
} else if (/\/\/\s*plasmic-managed-jsx\/\d+/.test(editedFile)) {
|
|
239
239
|
if (forceOverwrite) {
|
|
@@ -130,7 +130,7 @@ export async function syncProjectImageAssets(
|
|
|
130
130
|
);
|
|
131
131
|
}
|
|
132
132
|
|
|
133
|
-
async function ensureImageAssetContents(bundles: ImageBundle[]) {
|
|
133
|
+
export async function ensureImageAssetContents(bundles: ImageBundle[]) {
|
|
134
134
|
// The server may send images as a url instead of a base64 blob. In that
|
|
135
135
|
// case, we fetch the images here in the cli, instead of on the server.
|
|
136
136
|
// If you have a lot of images, this moves the expensive / long fetch
|