@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,106 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
|
|
5
|
+
}) : (function(o, m, k, k2) {
|
|
6
|
+
if (k2 === undefined) k2 = k;
|
|
7
|
+
o[k2] = m[k];
|
|
8
|
+
}));
|
|
9
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
10
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
11
|
+
}) : function(o, v) {
|
|
12
|
+
o["default"] = v;
|
|
13
|
+
});
|
|
14
|
+
var __importStar = (this && this.__importStar) || function (mod) {
|
|
15
|
+
if (mod && mod.__esModule) return mod;
|
|
16
|
+
var result = {};
|
|
17
|
+
if (mod != null) for (var k in mod) if (k !== "default" && Object.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
|
18
|
+
__setModuleDefault(result, mod);
|
|
19
|
+
return result;
|
|
20
|
+
};
|
|
21
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
22
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
23
|
+
};
|
|
24
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
25
|
+
exports.TempRepo = void 0;
|
|
26
|
+
const fs_1 = __importDefault(require("fs"));
|
|
27
|
+
const path = __importStar(require("path"));
|
|
28
|
+
const tmp = __importStar(require("tmp"));
|
|
29
|
+
const config_utils_1 = require("../utils/config-utils");
|
|
30
|
+
const file_utils_1 = require("./file-utils");
|
|
31
|
+
class TempRepo {
|
|
32
|
+
constructor() {
|
|
33
|
+
this.tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
|
34
|
+
}
|
|
35
|
+
destroy() {
|
|
36
|
+
this.tmpDir.removeCallback();
|
|
37
|
+
}
|
|
38
|
+
resolveFile(relativePath) {
|
|
39
|
+
return path.resolve(this.tmpDir.name, relativePath);
|
|
40
|
+
}
|
|
41
|
+
readFile(relativePath) {
|
|
42
|
+
const absPath = this.resolveFile(relativePath);
|
|
43
|
+
const buf = file_utils_1.readFileText(absPath);
|
|
44
|
+
return buf.toString();
|
|
45
|
+
}
|
|
46
|
+
writeFile(relativePath, data) {
|
|
47
|
+
const absPath = this.resolveFile(relativePath);
|
|
48
|
+
file_utils_1.writeFileText(absPath, data);
|
|
49
|
+
}
|
|
50
|
+
deleteFile(relativePath) {
|
|
51
|
+
const absPath = this.resolveFile(relativePath);
|
|
52
|
+
file_utils_1.deleteFileBuffered(absPath);
|
|
53
|
+
}
|
|
54
|
+
checkFile(relativePath) {
|
|
55
|
+
const absPath = this.resolveFile(relativePath);
|
|
56
|
+
try {
|
|
57
|
+
const stats = fs_1.default.statSync(absPath);
|
|
58
|
+
return !!stats ? true : false;
|
|
59
|
+
}
|
|
60
|
+
catch (e) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
getComponentFileContents(projectId, componentId) {
|
|
65
|
+
const plasmicJson = JSON.parse(this.readFile(config_utils_1.CONFIG_FILE_NAME));
|
|
66
|
+
const srcDir = plasmicJson.srcDir;
|
|
67
|
+
const projectConfig = plasmicJson.projects.find((p) => p.projectId === projectId);
|
|
68
|
+
if (!projectConfig) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const componentConfig = projectConfig.components.find((c) => c.id === componentId);
|
|
72
|
+
if (!componentConfig) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
const data = this.readFile(path.join(srcDir, componentConfig.renderModuleFilePath));
|
|
76
|
+
return data;
|
|
77
|
+
}
|
|
78
|
+
plasmicAuthPath() {
|
|
79
|
+
return this.resolveFile(config_utils_1.AUTH_FILE_NAME);
|
|
80
|
+
}
|
|
81
|
+
writePlasmicAuth(json) {
|
|
82
|
+
this.writeFile(config_utils_1.AUTH_FILE_NAME, JSON.stringify(json));
|
|
83
|
+
}
|
|
84
|
+
deletePlasmicAuth() {
|
|
85
|
+
this.deleteFile(config_utils_1.AUTH_FILE_NAME);
|
|
86
|
+
}
|
|
87
|
+
plasmicJsonPath() {
|
|
88
|
+
return this.resolveFile(config_utils_1.CONFIG_FILE_NAME);
|
|
89
|
+
}
|
|
90
|
+
readPlasmicJson() {
|
|
91
|
+
return JSON.parse(this.readFile(config_utils_1.CONFIG_FILE_NAME));
|
|
92
|
+
}
|
|
93
|
+
writePlasmicJson(json) {
|
|
94
|
+
this.writeFile(config_utils_1.CONFIG_FILE_NAME, JSON.stringify(json));
|
|
95
|
+
}
|
|
96
|
+
deletePlasmicJson() {
|
|
97
|
+
this.deleteFile(config_utils_1.CONFIG_FILE_NAME);
|
|
98
|
+
}
|
|
99
|
+
plasmicLoaderJsonPath() {
|
|
100
|
+
return this.resolveFile(config_utils_1.LOADER_CONFIG_FILE_NAME);
|
|
101
|
+
}
|
|
102
|
+
readPlasmicLoaderJson() {
|
|
103
|
+
return JSON.parse(this.readFile(config_utils_1.LOADER_CONFIG_FILE_NAME));
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
exports.TempRepo = TempRepo;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provide a standardized way to ask user to continue
|
|
3
|
+
* @param message
|
|
4
|
+
* @param yes - If true, always return true without prompting.
|
|
5
|
+
* @param default - Override the default value returned if the user presses enter
|
|
6
|
+
*/
|
|
7
|
+
export declare function confirmWithUser(message: string, yes?: boolean, defaultAnswer?: "y" | "n"): Promise<boolean>;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.confirmWithUser = void 0;
|
|
16
|
+
const inquirer_1 = __importDefault(require("inquirer"));
|
|
17
|
+
const deps_1 = require("../deps");
|
|
18
|
+
/**
|
|
19
|
+
* Provide a standardized way to ask user to continue
|
|
20
|
+
* @param message
|
|
21
|
+
* @param yes - If true, always return true without prompting.
|
|
22
|
+
* @param default - Override the default value returned if the user presses enter
|
|
23
|
+
*/
|
|
24
|
+
function confirmWithUser(message, yes, defaultAnswer) {
|
|
25
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
26
|
+
if (process.env.QUIET) {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
if (!!yes) {
|
|
30
|
+
if (!process.env.QUIET) {
|
|
31
|
+
deps_1.logger.info(`${message} (Y/n): y`);
|
|
32
|
+
}
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
defaultAnswer = defaultAnswer !== null && defaultAnswer !== void 0 ? defaultAnswer : "y";
|
|
36
|
+
const isDefaultYes = defaultAnswer === "y";
|
|
37
|
+
const choices = `(${isDefaultYes ? "Y" : "y"}/${isDefaultYes ? "n" : "N"})`;
|
|
38
|
+
const res = yield inquirer_1.default.prompt([
|
|
39
|
+
{
|
|
40
|
+
name: "continue",
|
|
41
|
+
message: `${message} ${choices}`,
|
|
42
|
+
default: defaultAnswer,
|
|
43
|
+
},
|
|
44
|
+
]);
|
|
45
|
+
return ["y", "yes"].includes(res.continue.toLowerCase());
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
exports.confirmWithUser = confirmWithUser;
|
package/jest.config.js
ADDED
package/package.json
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@plasmicapp/cli",
|
|
3
|
+
"version": "0.1.162",
|
|
4
|
+
"description": "plasmic cli for syncing local code with Plasmic designs",
|
|
5
|
+
"engines": {
|
|
6
|
+
"node": ">=12"
|
|
7
|
+
},
|
|
8
|
+
"main": "./dist/lib.js",
|
|
9
|
+
"types": "./dist/lib.d.ts",
|
|
10
|
+
"bin": {
|
|
11
|
+
"plasmic": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"scripts": {
|
|
14
|
+
"wtest": "jest --colors --watchAll",
|
|
15
|
+
"test": "jest --colors",
|
|
16
|
+
"test:debug": "node --inspect-brk node_modules/.bin/jest --runInBand --watch",
|
|
17
|
+
"build": "bash build.sh",
|
|
18
|
+
"plasmic": "ts-node src/index.ts",
|
|
19
|
+
"prepare": "yarn build"
|
|
20
|
+
},
|
|
21
|
+
"devDependencies": {
|
|
22
|
+
"@babel/preset-typescript": "^7.12.1",
|
|
23
|
+
"@plasmicapp/react-web": "^0.2.18",
|
|
24
|
+
"@types/findup-sync": "^2.0.2",
|
|
25
|
+
"@types/glob": "^7.1.3",
|
|
26
|
+
"@types/inquirer": "^6.5.0",
|
|
27
|
+
"@types/jest": "^26.0.4",
|
|
28
|
+
"@types/latest-version": "^4.0.1",
|
|
29
|
+
"@types/lodash": "^4.14.157",
|
|
30
|
+
"@types/node": "^14.0.23",
|
|
31
|
+
"@types/pako": "^1.0.1",
|
|
32
|
+
"@types/prettier": "^2.0.2",
|
|
33
|
+
"@types/semver": "^7.3.1",
|
|
34
|
+
"@types/tmp": "^0.2.0",
|
|
35
|
+
"@types/update-notifier": "^4.1.0",
|
|
36
|
+
"@types/uuid": "^8.3.0",
|
|
37
|
+
"@types/wrap-ansi": "^3.0.0",
|
|
38
|
+
"@types/yargs": "^15.0.5",
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "^3.8.0",
|
|
40
|
+
"@typescript-eslint/parser": "^3.8.0",
|
|
41
|
+
"eslint": "^7.7.0",
|
|
42
|
+
"jest": "^26.1.0",
|
|
43
|
+
"jest-circus": "^26.1.0",
|
|
44
|
+
"tmp": "^0.2.1",
|
|
45
|
+
"ts-jest": "^26.1.2",
|
|
46
|
+
"ts-node": "^8.10.2",
|
|
47
|
+
"typescript-json-schema": "^0.45.0"
|
|
48
|
+
},
|
|
49
|
+
"dependencies": {
|
|
50
|
+
"@babel/core": "^7.12.3",
|
|
51
|
+
"@babel/generator": "^7.12.1",
|
|
52
|
+
"@plasmicapp/code-merger": "^0.0.31",
|
|
53
|
+
"@sentry/node": "^5.19.2",
|
|
54
|
+
"@types/socket.io-client": "^1.4.34",
|
|
55
|
+
"axios": "^0.21.1",
|
|
56
|
+
"chalk": "^4.1.0",
|
|
57
|
+
"fast-glob": "^3.2.4",
|
|
58
|
+
"findup-sync": "^4.0.0",
|
|
59
|
+
"fs": "^0.0.1-security",
|
|
60
|
+
"glob": "^7.1.6",
|
|
61
|
+
"inquirer": "^7.3.2",
|
|
62
|
+
"latest-version": "^5.1.0",
|
|
63
|
+
"lodash": "^4.17.19",
|
|
64
|
+
"moment": "^2.27.0",
|
|
65
|
+
"open": "^8.0.9",
|
|
66
|
+
"pako": "^1.0.11",
|
|
67
|
+
"path": "^0.12.7",
|
|
68
|
+
"prettier": "^2.0.5",
|
|
69
|
+
"semver": "^7.3.2",
|
|
70
|
+
"socket.io-client": "^3.0.3",
|
|
71
|
+
"typescript": "^3.9.6",
|
|
72
|
+
"upath": "^1.2.0",
|
|
73
|
+
"update-notifier": "^4.1.0",
|
|
74
|
+
"utility-types": "^3.10.0",
|
|
75
|
+
"uuid": "^8.3.1",
|
|
76
|
+
"winston": "^3.3.3",
|
|
77
|
+
"wrap-ansi": "^7.0.0",
|
|
78
|
+
"yargs": "^15.4.1"
|
|
79
|
+
}
|
|
80
|
+
}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { ProjectSyncMetadataModel } from "@plasmicapp/code-merger";
|
|
2
|
+
import L from "lodash";
|
|
3
|
+
import {
|
|
4
|
+
ChecksumBundle,
|
|
5
|
+
ComponentBundle,
|
|
6
|
+
ProjectBundle,
|
|
7
|
+
ProjectIconsResponse,
|
|
8
|
+
ProjectIdAndToken,
|
|
9
|
+
ProjectMetaBundle,
|
|
10
|
+
ProjectVersionMeta,
|
|
11
|
+
RequiredPackages,
|
|
12
|
+
StyleConfigResponse,
|
|
13
|
+
StyleTokensMap,
|
|
14
|
+
VersionResolution,
|
|
15
|
+
} from "../api";
|
|
16
|
+
import { AuthConfig } from "../utils/config-utils";
|
|
17
|
+
import { ensure } from "../utils/lang-utils";
|
|
18
|
+
import * as semver from "../utils/semver";
|
|
19
|
+
|
|
20
|
+
const api: any = jest.genMockFromModule("../api");
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Store a simplified data model for use with testing
|
|
24
|
+
*/
|
|
25
|
+
// Keyed by (projectId, version)
|
|
26
|
+
const PROJECTS: MockProject[] = [];
|
|
27
|
+
export interface MockProject {
|
|
28
|
+
projectId: string;
|
|
29
|
+
projectApiToken: string;
|
|
30
|
+
version: string;
|
|
31
|
+
projectName: string;
|
|
32
|
+
components: MockComponent[];
|
|
33
|
+
dependencies: {
|
|
34
|
+
[projectId: string]: string;
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
export interface MockComponent {
|
|
38
|
+
id: string;
|
|
39
|
+
name: string;
|
|
40
|
+
projectId?: string;
|
|
41
|
+
version?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function clear() {
|
|
45
|
+
while (PROJECTS.length > 0) {
|
|
46
|
+
PROJECTS.shift();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function mockProjectToProjectVersionMeta(
|
|
51
|
+
mock: MockProject,
|
|
52
|
+
componentIdOrNames?: readonly string[]
|
|
53
|
+
): ProjectVersionMeta {
|
|
54
|
+
return {
|
|
55
|
+
...mock,
|
|
56
|
+
componentIds: mock.components
|
|
57
|
+
.filter(
|
|
58
|
+
(c) =>
|
|
59
|
+
!componentIdOrNames ||
|
|
60
|
+
componentIdOrNames.includes(c.name) ||
|
|
61
|
+
componentIdOrNames.includes(c.id)
|
|
62
|
+
)
|
|
63
|
+
.map((c) => c.id),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Call this in test to setup the data model
|
|
69
|
+
* @param id componentId
|
|
70
|
+
* @param comp MockComponent
|
|
71
|
+
*/
|
|
72
|
+
function addMockProject(proj: MockProject) {
|
|
73
|
+
const projectId = proj.projectId;
|
|
74
|
+
const version = proj.version;
|
|
75
|
+
// Populate projectId and version into each component
|
|
76
|
+
// will be useful when reading / writing components to files
|
|
77
|
+
proj.components = proj.components.map((c) => {
|
|
78
|
+
return {
|
|
79
|
+
...c,
|
|
80
|
+
projectId,
|
|
81
|
+
version,
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
const existing = getMockProject(projectId, version);
|
|
86
|
+
if (!existing) {
|
|
87
|
+
PROJECTS.push(proj);
|
|
88
|
+
} else {
|
|
89
|
+
existing.components = proj.components;
|
|
90
|
+
existing.dependencies = proj.dependencies;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Used to interpret data that's stored in the "codegen" files from the Mock server
|
|
96
|
+
* @param data
|
|
97
|
+
*/
|
|
98
|
+
function stringToMockComponent(data?: string): MockComponent | undefined {
|
|
99
|
+
if (!data) {
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
const withoutComments = data.startsWith("//") ? data.slice(2) : data;
|
|
103
|
+
const cleaned = withoutComments.trim();
|
|
104
|
+
return JSON.parse(cleaned);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Used to write mock data into files for testing.
|
|
109
|
+
* Useful to see what version was written
|
|
110
|
+
* Need to prefix with a comment to satisfy the parser used in `fixAllImports`
|
|
111
|
+
* @param component
|
|
112
|
+
*/
|
|
113
|
+
function mockComponentToString(component: MockComponent): string {
|
|
114
|
+
return "// " + JSON.stringify(component);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
function getMockProject(
|
|
118
|
+
projectId: string,
|
|
119
|
+
version: string
|
|
120
|
+
): MockProject | undefined {
|
|
121
|
+
return PROJECTS.find(
|
|
122
|
+
(m) => m.projectId === projectId && m.version === version
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Only fetch top-level components that match the projectId (optionally also componentIdOrNames + version)
|
|
128
|
+
* Does not crawl the dependency tree
|
|
129
|
+
* @param projectId
|
|
130
|
+
* @param componentIdOrNames
|
|
131
|
+
* @param versionRange
|
|
132
|
+
*/
|
|
133
|
+
function getMockComponents(
|
|
134
|
+
projectId: string,
|
|
135
|
+
version: string,
|
|
136
|
+
componentIdOrNames: readonly string[] | undefined
|
|
137
|
+
): MockComponent[] {
|
|
138
|
+
const project = getMockProject(projectId, version);
|
|
139
|
+
return !project
|
|
140
|
+
? []
|
|
141
|
+
: project.components.filter(
|
|
142
|
+
(c) =>
|
|
143
|
+
!componentIdOrNames ||
|
|
144
|
+
componentIdOrNames.includes(c.id) ||
|
|
145
|
+
componentIdOrNames.includes(c.name)
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
function genFilename(base: string, suffix: string) {
|
|
150
|
+
return "Plasmic" + base + "." + suffix;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function genComponentBundle(component: MockComponent): ComponentBundle {
|
|
154
|
+
return {
|
|
155
|
+
renderModule: mockComponentToString(component),
|
|
156
|
+
skeletonModule: mockComponentToString(component),
|
|
157
|
+
cssRules: `theClass {color: blue;}`,
|
|
158
|
+
renderModuleFileName: genFilename(component.name, "tsx"),
|
|
159
|
+
skeletonModuleFileName: component.name + ".tsx",
|
|
160
|
+
cssFileName: genFilename(component.name, "css"),
|
|
161
|
+
componentName: component.name,
|
|
162
|
+
id: component.id,
|
|
163
|
+
scheme: "blackbox",
|
|
164
|
+
nameInIdToUuid: [],
|
|
165
|
+
isPage: false,
|
|
166
|
+
};
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function genEmptyStyleTokensMap() {
|
|
170
|
+
return {
|
|
171
|
+
props: [],
|
|
172
|
+
global: {
|
|
173
|
+
meta: {
|
|
174
|
+
source: "plasmic.app" as "plasmic.app",
|
|
175
|
+
},
|
|
176
|
+
},
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
function genProjectMetaBundle(projectId: string): ProjectMetaBundle {
|
|
181
|
+
return {
|
|
182
|
+
projectId,
|
|
183
|
+
projectName: projectId,
|
|
184
|
+
cssFileName: genFilename(projectId, "css"),
|
|
185
|
+
cssRules: `theClass {color: green;}`,
|
|
186
|
+
jsBundleThemes: [],
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
function* getDeps(projects: ProjectVersionMeta[]) {
|
|
191
|
+
const queue: ProjectVersionMeta[] = [...projects];
|
|
192
|
+
while (queue.length > 0) {
|
|
193
|
+
const curr = ensure(queue.shift());
|
|
194
|
+
for (const [projectId, version] of L.toPairs(curr.dependencies)) {
|
|
195
|
+
const mockProject = ensure(getMockProject(projectId, version));
|
|
196
|
+
const projectMeta = mockProjectToProjectVersionMeta(mockProject);
|
|
197
|
+
yield projectMeta;
|
|
198
|
+
queue.push(projectMeta);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
class PlasmicApi {
|
|
204
|
+
constructor(private auth: AuthConfig) {}
|
|
205
|
+
|
|
206
|
+
async genStyleConfig(): Promise<StyleConfigResponse> {
|
|
207
|
+
const result = {
|
|
208
|
+
defaultStyleCssFileName: genFilename("default", "css"),
|
|
209
|
+
defaultStyleCssRules: `theClass {color: red;}`,
|
|
210
|
+
};
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
async resolveSync(
|
|
215
|
+
projects: {
|
|
216
|
+
projectId: string;
|
|
217
|
+
versionRange: string;
|
|
218
|
+
componentIdOrNames: readonly string[] | undefined;
|
|
219
|
+
projectApiToken?: string;
|
|
220
|
+
}[],
|
|
221
|
+
recursive?: boolean
|
|
222
|
+
): Promise<VersionResolution> {
|
|
223
|
+
const results: VersionResolution = {
|
|
224
|
+
projects: [],
|
|
225
|
+
dependencies: [],
|
|
226
|
+
conflicts: [],
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
// Get top level projects
|
|
230
|
+
projects.forEach((proj) => {
|
|
231
|
+
const availableProjects = Array.from(PROJECTS.values()).filter(
|
|
232
|
+
(p) => p.projectId === proj.projectId
|
|
233
|
+
);
|
|
234
|
+
if (
|
|
235
|
+
!(
|
|
236
|
+
(this.auth.user && this.auth.token) ||
|
|
237
|
+
availableProjects.every(
|
|
238
|
+
(p) => p.projectApiToken === proj.projectApiToken
|
|
239
|
+
)
|
|
240
|
+
)
|
|
241
|
+
) {
|
|
242
|
+
throw new Error("No user+token, and project API tokens don't match");
|
|
243
|
+
}
|
|
244
|
+
const availableVersions = availableProjects.map((p) => p.version);
|
|
245
|
+
const version = semver.maxSatisfying(
|
|
246
|
+
availableVersions,
|
|
247
|
+
proj.versionRange
|
|
248
|
+
);
|
|
249
|
+
if (version) {
|
|
250
|
+
const mockProject = ensure(getMockProject(proj.projectId, version));
|
|
251
|
+
const projectMeta = mockProjectToProjectVersionMeta(
|
|
252
|
+
mockProject,
|
|
253
|
+
proj.componentIdOrNames
|
|
254
|
+
);
|
|
255
|
+
results.projects.push(projectMeta);
|
|
256
|
+
}
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Get dependencies
|
|
260
|
+
if (!!recursive) {
|
|
261
|
+
const deps = [...getDeps(results.projects)];
|
|
262
|
+
results.dependencies.push(...deps);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
return results;
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
async getCurrentUser() {
|
|
269
|
+
return true;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
async projectComponents(
|
|
273
|
+
projectId: string,
|
|
274
|
+
opts: {
|
|
275
|
+
platform: string;
|
|
276
|
+
newCompScheme: "blackbox" | "direct";
|
|
277
|
+
// The list of existing components as [componentUuid, codeScheme]
|
|
278
|
+
existingCompScheme: Array<[string, "blackbox" | "direct"]>;
|
|
279
|
+
componentIdOrNames: readonly string[] | undefined;
|
|
280
|
+
version: string;
|
|
281
|
+
}
|
|
282
|
+
): Promise<ProjectBundle> {
|
|
283
|
+
const { componentIdOrNames, version } = opts;
|
|
284
|
+
if (PROJECTS.length <= 0) {
|
|
285
|
+
throw new Error("Remember to call __addMockProject first!");
|
|
286
|
+
}
|
|
287
|
+
const maybeTokenPair = this.lastProjectIdsAndTokens.find(
|
|
288
|
+
(pair) => pair.projectId === projectId
|
|
289
|
+
);
|
|
290
|
+
const project = ensure(PROJECTS.find((p) => p.projectId === projectId));
|
|
291
|
+
if (
|
|
292
|
+
!(
|
|
293
|
+
(this.auth.user && this.auth.token) ||
|
|
294
|
+
project.projectApiToken === maybeTokenPair?.projectApiToken
|
|
295
|
+
)
|
|
296
|
+
) {
|
|
297
|
+
throw new Error("No user+token and project API tokens don't match");
|
|
298
|
+
}
|
|
299
|
+
// Server also require tokens for the dependencies.
|
|
300
|
+
const deps = [...getDeps([mockProjectToProjectVersionMeta(project)])];
|
|
301
|
+
if (
|
|
302
|
+
!deps.every((dep) =>
|
|
303
|
+
this.lastProjectIdsAndTokens.find((p) => p.projectId === dep.projectId)
|
|
304
|
+
)
|
|
305
|
+
) {
|
|
306
|
+
throw new Error(
|
|
307
|
+
"No user+token and project API tokens don't match on a dependency"
|
|
308
|
+
);
|
|
309
|
+
}
|
|
310
|
+
const mockComponents = getMockComponents(
|
|
311
|
+
projectId,
|
|
312
|
+
version,
|
|
313
|
+
componentIdOrNames
|
|
314
|
+
);
|
|
315
|
+
if (mockComponents.length <= 0) {
|
|
316
|
+
throw new Error(
|
|
317
|
+
`Code gen failed: no components match the parameters ${JSON.stringify(
|
|
318
|
+
{ projectId, version, componentIdOrNames },
|
|
319
|
+
undefined,
|
|
320
|
+
2
|
|
321
|
+
)}`
|
|
322
|
+
);
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
const components = mockComponents.map((c) => genComponentBundle(c));
|
|
326
|
+
const result = {
|
|
327
|
+
components,
|
|
328
|
+
codeComponentMetas: [],
|
|
329
|
+
projectConfig: genProjectMetaBundle(projectId),
|
|
330
|
+
globalVariants: [],
|
|
331
|
+
usedTokens: genEmptyStyleTokensMap(),
|
|
332
|
+
iconAssets: [],
|
|
333
|
+
imageAssets: [],
|
|
334
|
+
checksums: {
|
|
335
|
+
renderModuleChecksums: components.map((c) => [c.id, c.renderModule]),
|
|
336
|
+
cssRulesChecksums: components.map((c) => [c.id, c.cssRules]),
|
|
337
|
+
imageChecksums: [],
|
|
338
|
+
iconChecksums: [],
|
|
339
|
+
globalVariantChecksums: [],
|
|
340
|
+
projectCssChecksum: "",
|
|
341
|
+
} as ChecksumBundle,
|
|
342
|
+
};
|
|
343
|
+
return result;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
async uploadBundle(
|
|
347
|
+
projectId: string,
|
|
348
|
+
bundleName: string,
|
|
349
|
+
bundleJs: string,
|
|
350
|
+
css: string[],
|
|
351
|
+
metaJson: string
|
|
352
|
+
): Promise<StyleTokensMap> {
|
|
353
|
+
throw new Error("Unimplemented");
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
async projectStyleTokens(projectId: string): Promise<StyleTokensMap> {
|
|
357
|
+
throw new Error("Unimplemented");
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async projectIcons(projectId: string): Promise<ProjectIconsResponse> {
|
|
361
|
+
throw new Error("Unimplemented");
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
async projectSyncMetadata(
|
|
365
|
+
projectId: string,
|
|
366
|
+
revision: number,
|
|
367
|
+
rethrowAppError: boolean
|
|
368
|
+
): Promise<ProjectSyncMetadataModel> {
|
|
369
|
+
throw new Error("Unimplemented");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
async requiredPackages(): Promise<RequiredPackages> {
|
|
373
|
+
return {
|
|
374
|
+
"@plasmicapp/loader": "0.0.1",
|
|
375
|
+
"@plasmicapp/cli": "0.0.1",
|
|
376
|
+
"@plasmicapp/react-web": "0.0.1",
|
|
377
|
+
"@plasmicapp/react-web-runtime": "0.0.1",
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
connectSocket() {}
|
|
382
|
+
|
|
383
|
+
lastProjectIdsAndTokens: ProjectIdAndToken[] = [];
|
|
384
|
+
attachProjectIdsAndTokens(idsAndTokens: ProjectIdAndToken[]) {
|
|
385
|
+
this.lastProjectIdsAndTokens = idsAndTokens;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
api.PlasmicApi = PlasmicApi;
|
|
390
|
+
api.clear = clear;
|
|
391
|
+
api.getMockProject = getMockProject;
|
|
392
|
+
api.addMockProject = addMockProject;
|
|
393
|
+
api.stringToMockComponent = stringToMockComponent;
|
|
394
|
+
module.exports = api;
|