@embeddable.com/sdk-core 0.2.0 → 2.0.0
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/bin/embeddable +1 -1
- package/configs/stencil.config.ts +5 -5
- package/dist/build.d.ts +2 -0
- package/dist/buildTypes.d.ts +2 -0
- package/dist/cleanup.d.ts +2 -0
- package/dist/createContext.d.ts +20 -0
- package/dist/generate.d.ts +2 -0
- package/dist/globalCleanup.d.ts +2 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +416 -0
- package/dist/login.d.ts +3 -0
- package/dist/prepare.d.ts +2 -0
- package/dist/push.d.ts +2 -0
- package/dist/validate.d.ts +2 -0
- package/lib/defineConfig.d.ts +22 -0
- package/lib/embedType.d.ts +15 -2
- package/lib/index.cjs.js +113 -30
- package/lib/index.d.ts +6 -4
- package/lib/index.esm.js +111 -31
- package/lib/index.umd.js +116 -33
- package/lib/loadData.d.ts +61 -9
- package/lib/operations.d.ts +11 -0
- package/lib/untils.d.ts +9 -0
- package/package.json +13 -4
- package/templates/component.tsx.template +4 -0
- package/scripts/build.js +0 -20
- package/scripts/buildTypes.js +0 -54
- package/scripts/cleanup.js +0 -30
- package/scripts/createContext.js +0 -22
- package/scripts/findEmbFiles.js +0 -33
- package/scripts/generate.js +0 -67
- package/scripts/index.js +0 -13
- package/scripts/login.js +0 -76
- package/scripts/prepare.js +0 -26
- package/scripts/push.js +0 -97
package/bin/embeddable
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { Config } from
|
|
1
|
+
import { Config } from "@stencil/core";
|
|
2
2
|
|
|
3
3
|
export const config: Config = {
|
|
4
|
-
namespace:
|
|
5
|
-
srcDir:
|
|
4
|
+
namespace: "embeddable-wrapper",
|
|
5
|
+
srcDir: "component",
|
|
6
6
|
outputTargets: [
|
|
7
7
|
{
|
|
8
|
-
type:
|
|
8
|
+
type: "dist",
|
|
9
9
|
},
|
|
10
10
|
],
|
|
11
|
-
};
|
|
11
|
+
};
|
package/dist/build.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
declare const _default: (coreRoot: string, clientRoot: string) => {
|
|
2
|
+
core: {
|
|
3
|
+
rootDir: string;
|
|
4
|
+
templatesDir: string;
|
|
5
|
+
configsDir: string;
|
|
6
|
+
};
|
|
7
|
+
client: {
|
|
8
|
+
rootDir: string;
|
|
9
|
+
buildDir: string;
|
|
10
|
+
srcDir: string;
|
|
11
|
+
tmpDir: string;
|
|
12
|
+
componentDir: string;
|
|
13
|
+
stencilBuild: string;
|
|
14
|
+
archiveFile: string;
|
|
15
|
+
};
|
|
16
|
+
outputOptions: {
|
|
17
|
+
typesEntryPointFilename: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
export default _default;
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var fs = require('node:fs/promises');
|
|
4
|
+
var path = require('node:path');
|
|
5
|
+
var vite = require('vite');
|
|
6
|
+
var sdkUtils = require('@embeddable.com/sdk-utils');
|
|
7
|
+
var fsSync = require('node:fs');
|
|
8
|
+
var stencilNodeApi = require('@stencil/core/sys/node');
|
|
9
|
+
var stencil = require('@stencil/core/cli');
|
|
10
|
+
var fs$1 = require('fs/promises');
|
|
11
|
+
var path$1 = require('path');
|
|
12
|
+
var YAML = require('yaml');
|
|
13
|
+
var os = require('node:os');
|
|
14
|
+
var axios = require('axios');
|
|
15
|
+
var archiver = require('archiver');
|
|
16
|
+
|
|
17
|
+
function _interopNamespaceDefault(e) {
|
|
18
|
+
var n = Object.create(null);
|
|
19
|
+
if (e) {
|
|
20
|
+
Object.keys(e).forEach(function (k) {
|
|
21
|
+
if (k !== 'default') {
|
|
22
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
23
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
24
|
+
enumerable: true,
|
|
25
|
+
get: function () { return e[k]; }
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
n.default = e;
|
|
31
|
+
return Object.freeze(n);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
var fs__namespace = /*#__PURE__*/_interopNamespaceDefault(fs);
|
|
35
|
+
var path__namespace = /*#__PURE__*/_interopNamespaceDefault(path);
|
|
36
|
+
var vite__namespace = /*#__PURE__*/_interopNamespaceDefault(vite);
|
|
37
|
+
var fsSync__namespace = /*#__PURE__*/_interopNamespaceDefault(fsSync);
|
|
38
|
+
var stencilNodeApi__namespace = /*#__PURE__*/_interopNamespaceDefault(stencilNodeApi);
|
|
39
|
+
var stencil__namespace = /*#__PURE__*/_interopNamespaceDefault(stencil);
|
|
40
|
+
var fs__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(fs$1);
|
|
41
|
+
var path__namespace$1 = /*#__PURE__*/_interopNamespaceDefault(path$1);
|
|
42
|
+
var YAML__namespace = /*#__PURE__*/_interopNamespaceDefault(YAML);
|
|
43
|
+
var os__namespace = /*#__PURE__*/_interopNamespaceDefault(os);
|
|
44
|
+
var archiver__namespace = /*#__PURE__*/_interopNamespaceDefault(archiver);
|
|
45
|
+
|
|
46
|
+
const oraP$2 = import('ora');
|
|
47
|
+
const EMB_TYPE_FILE_REGEX = /^(.*)\.type\.emb\.[jt]s$/;
|
|
48
|
+
const EMB_OPTIONS_FILE_REGEX = /^(.*)\.options\.emb\.[jt]s$/;
|
|
49
|
+
var buildTypes = async (ctx) => {
|
|
50
|
+
const ora = (await oraP$2).default;
|
|
51
|
+
const progress = ora("building types...").start();
|
|
52
|
+
await generate$1(ctx);
|
|
53
|
+
await build$1(ctx);
|
|
54
|
+
await cleanup$1(ctx);
|
|
55
|
+
progress.succeed("types built completed");
|
|
56
|
+
};
|
|
57
|
+
async function generate$1(ctx) {
|
|
58
|
+
const typeFiles = await sdkUtils.findFiles(ctx.client.srcDir, EMB_TYPE_FILE_REGEX);
|
|
59
|
+
const optionsFiles = await sdkUtils.findFiles(ctx.client.srcDir, EMB_OPTIONS_FILE_REGEX);
|
|
60
|
+
const typeImports = typeFiles
|
|
61
|
+
.concat(optionsFiles)
|
|
62
|
+
.map(([_fileName, filePath]) => `import './${path__namespace.relative(ctx.client.rootDir, filePath)}';`)
|
|
63
|
+
.join("\n");
|
|
64
|
+
await fs__namespace.writeFile(path__namespace.resolve(ctx.client.rootDir, ctx.outputOptions.typesEntryPointFilename), typeImports);
|
|
65
|
+
}
|
|
66
|
+
async function build$1(ctx) {
|
|
67
|
+
process.chdir(ctx.client.rootDir);
|
|
68
|
+
await vite__namespace.build({
|
|
69
|
+
logLevel: "error",
|
|
70
|
+
build: {
|
|
71
|
+
emptyOutDir: false,
|
|
72
|
+
lib: {
|
|
73
|
+
entry: `./${ctx.outputOptions.typesEntryPointFilename}`,
|
|
74
|
+
formats: ["es"],
|
|
75
|
+
fileName: "embeddable-types",
|
|
76
|
+
},
|
|
77
|
+
outDir: ".embeddable-build/",
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
async function cleanup$1(ctx) {
|
|
82
|
+
await fs__namespace.rm(path__namespace.resolve(ctx.client.rootDir, "embeddable-types-entry-point.js"));
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
var prepare = async (ctx) => {
|
|
86
|
+
await removeIfExists(ctx);
|
|
87
|
+
await copyStencilConfigsToClient(ctx);
|
|
88
|
+
await createComponentDir(ctx.client.componentDir);
|
|
89
|
+
};
|
|
90
|
+
async function removeIfExists(ctx) {
|
|
91
|
+
if (fsSync__namespace.existsSync(ctx.client.buildDir))
|
|
92
|
+
await fs__namespace.rm(ctx.client.buildDir, { recursive: true });
|
|
93
|
+
}
|
|
94
|
+
async function copyStencilConfigsToClient(ctx) {
|
|
95
|
+
await fs__namespace.cp(ctx.core.configsDir, ctx.client.buildDir, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
async function createComponentDir(dir) {
|
|
98
|
+
await fs__namespace.mkdir(dir);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const STYLE_IMPORTS_TOKEN = "{{STYLES_IMPORT}}";
|
|
102
|
+
const RENDER_IMPORT_TOKEN = "{{RENDER_IMPORT}}";
|
|
103
|
+
const NODE_LOGGER = stencilNodeApi__namespace.createNodeLogger({ process: process });
|
|
104
|
+
const NODE_SYS = stencilNodeApi__namespace.createNodeSys({
|
|
105
|
+
process: process,
|
|
106
|
+
// @ts-ignore
|
|
107
|
+
logger: NODE_LOGGER,
|
|
108
|
+
});
|
|
109
|
+
var generate = async (ctx, pluginName) => {
|
|
110
|
+
await injectCSS(ctx, pluginName);
|
|
111
|
+
await injectBundleRender(ctx, pluginName);
|
|
112
|
+
await runStencil(ctx);
|
|
113
|
+
};
|
|
114
|
+
async function injectCSS(ctx, pluginName) {
|
|
115
|
+
const CUSTOMER_BUILD = path__namespace.resolve(ctx.client.buildDir, ctx[pluginName].outputOptions.buildName);
|
|
116
|
+
const allFiles = await fs__namespace.readdir(CUSTOMER_BUILD);
|
|
117
|
+
const cssFilesImportsStr = allFiles
|
|
118
|
+
.filter((fileName) => fileName.endsWith(".css"))
|
|
119
|
+
.map((fileName) => `@import '../${ctx[pluginName].outputOptions.buildName}/${fileName}';`)
|
|
120
|
+
.join("\n");
|
|
121
|
+
const content = await fs__namespace.readFile(path__namespace.resolve(ctx.core.templatesDir, "style.css.template"), "utf8");
|
|
122
|
+
await fs__namespace.writeFile(path__namespace.resolve(ctx.client.componentDir, "style.css"), content.replace(STYLE_IMPORTS_TOKEN, cssFilesImportsStr));
|
|
123
|
+
}
|
|
124
|
+
async function injectBundleRender(ctx, pluginName) {
|
|
125
|
+
const importStr = `import render from '../${ctx[pluginName].outputOptions.buildName}/${ctx[pluginName].outputOptions.fileName}';`;
|
|
126
|
+
const content = await fs__namespace.readFile(path__namespace.resolve(ctx.core.templatesDir, "component.tsx.template"), "utf8");
|
|
127
|
+
await fs__namespace.writeFile(path__namespace.resolve(ctx.client.componentDir, "component.tsx"), content.replace(RENDER_IMPORT_TOKEN, importStr));
|
|
128
|
+
}
|
|
129
|
+
async function runStencil(ctx) {
|
|
130
|
+
process.chdir(ctx.client.buildDir);
|
|
131
|
+
await stencil__namespace.run({
|
|
132
|
+
args: ["build"],
|
|
133
|
+
logger: NODE_LOGGER,
|
|
134
|
+
sys: NODE_SYS,
|
|
135
|
+
// @ts-ignore
|
|
136
|
+
checkVersion: stencilNodeApi__namespace.checkVersion,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
var cleanup = async (ctx) => {
|
|
141
|
+
await extractBuild(ctx);
|
|
142
|
+
await removeObsoleteDir(ctx.client.buildDir);
|
|
143
|
+
await moveBuildTOBuildDir(ctx);
|
|
144
|
+
};
|
|
145
|
+
async function extractBuild(ctx) {
|
|
146
|
+
await fs__namespace$1.rename(path__namespace$1.resolve(ctx.client.buildDir, ctx.client.stencilBuild), ctx.client.tmpDir);
|
|
147
|
+
await fs__namespace$1.rename(path__namespace$1.resolve(ctx.client.buildDir, "embeddable-types.js"), path__namespace$1.join(ctx.client.tmpDir, "embeddable-types.js"));
|
|
148
|
+
await fs__namespace$1.rename(path__namespace$1.resolve(ctx.client.buildDir, "embeddable-components-meta.js"), path__namespace$1.join(ctx.client.tmpDir, "embeddable-components-meta.js"));
|
|
149
|
+
await fs__namespace$1.rename(path__namespace$1.resolve(ctx.client.buildDir, "embeddable-editors-meta.js"), path__namespace$1.join(ctx.client.tmpDir, "embeddable-editors-meta.js"));
|
|
150
|
+
}
|
|
151
|
+
async function removeObsoleteDir(dir) {
|
|
152
|
+
await fs__namespace$1.rm(dir, { recursive: true });
|
|
153
|
+
}
|
|
154
|
+
async function moveBuildTOBuildDir(ctx) {
|
|
155
|
+
await fs__namespace$1.rename(ctx.client.tmpDir, ctx.client.buildDir);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
const EMB_YAML_FILE_REGEX$1 = /^(.*)\.emb\.ya?ml$/;
|
|
159
|
+
var validate = async (ctx) => {
|
|
160
|
+
const ora = (await import('ora')).default;
|
|
161
|
+
const spinnerValidate = ora("validation...").start();
|
|
162
|
+
const filesList = await sdkUtils.findFiles(ctx.client.srcDir, EMB_YAML_FILE_REGEX$1);
|
|
163
|
+
const componentConfigErrors = await componentConfigValidation(filesList);
|
|
164
|
+
if (componentConfigErrors.length) {
|
|
165
|
+
spinnerValidate.fail("One or more component.emb.yaml files are invalid:");
|
|
166
|
+
componentConfigErrors.forEach((errorMessage) => spinnerValidate.info(errorMessage));
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
spinnerValidate.succeed("validation completed");
|
|
170
|
+
};
|
|
171
|
+
async function componentConfigValidation(filesList) {
|
|
172
|
+
const ARRAY_ALLOWED_TYPES = ["Dimension", "Measure"];
|
|
173
|
+
const errors = [];
|
|
174
|
+
for (const [fileName, filePath] of filesList) {
|
|
175
|
+
if (!fileName.endsWith(".component"))
|
|
176
|
+
continue;
|
|
177
|
+
const fileContentRaw = await fs__namespace.readFile(filePath, "utf8");
|
|
178
|
+
const config = YAML__namespace.parse(fileContentRaw);
|
|
179
|
+
if (!("inputs" in config) || config.inputs.length === 0)
|
|
180
|
+
continue;
|
|
181
|
+
config.inputs
|
|
182
|
+
.filter((inputConfig) => inputConfig === null || inputConfig === void 0 ? void 0 : inputConfig.array)
|
|
183
|
+
.forEach((inputConfig) => {
|
|
184
|
+
if (!ARRAY_ALLOWED_TYPES.includes(inputConfig === null || inputConfig === void 0 ? void 0 : inputConfig.type)) {
|
|
185
|
+
const errorMessage = `${fileName} contains invalid type value for \x1b[33m${inputConfig.name}\x1b[0m input.
|
|
186
|
+
\x1b[33m${inputConfig.name}\x1b[0m is marked as \x1b[33marray\x1b[0m. Inputs marked as array support the following types: ${ARRAY_ALLOWED_TYPES.join(", ")}.
|
|
187
|
+
Specified \x1b[33m${inputConfig === null || inputConfig === void 0 ? void 0 : inputConfig.type}\x1b[0m type is not supported.
|
|
188
|
+
Please check the following file: \x1b[33m${filePath}\x1b[0m\n`;
|
|
189
|
+
errors.push(errorMessage);
|
|
190
|
+
}
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
return errors;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
var build = async () => {
|
|
197
|
+
const config = (await import(`${process.cwd()}/embeddable.config.js`))
|
|
198
|
+
.default;
|
|
199
|
+
await validate(config);
|
|
200
|
+
await prepare(config);
|
|
201
|
+
await buildTypes(config);
|
|
202
|
+
for (const getPlugin of config.plugins) {
|
|
203
|
+
const plugin = getPlugin();
|
|
204
|
+
await plugin.validate(config);
|
|
205
|
+
await plugin.build(config);
|
|
206
|
+
await plugin.cleanup(config);
|
|
207
|
+
}
|
|
208
|
+
// NOTE: likely this will be called inside the loop above if we decide to support clients with mixed frameworks simultaneously.
|
|
209
|
+
await generate(config, "sdk-react");
|
|
210
|
+
await cleanup(config);
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
const oraP$1 = import('ora');
|
|
214
|
+
const openP = import('open');
|
|
215
|
+
const CREDENTIALS_DIR = path__namespace.resolve(os__namespace.homedir(), ".embeddable");
|
|
216
|
+
const CREDENTIALS_FILE = path__namespace.resolve(CREDENTIALS_DIR, "credentials");
|
|
217
|
+
const AUTH0_DOMAIN = "embeddable-dev.eu.auth0.com";
|
|
218
|
+
const AUTH0_CLIENT_ID = "xOKco5ztFCpWn54bJbFkAcT8mV4LLcpG";
|
|
219
|
+
var login = async () => {
|
|
220
|
+
var _a;
|
|
221
|
+
const ora = (await oraP$1).default;
|
|
222
|
+
const open = (await openP).default;
|
|
223
|
+
await resolveFiles();
|
|
224
|
+
const deviceCodePayload = {
|
|
225
|
+
client_id: AUTH0_CLIENT_ID,
|
|
226
|
+
audience: "https://api.embeddable.com/",
|
|
227
|
+
};
|
|
228
|
+
const deviceCodeResponse = await axios.post(`https://${AUTH0_DOMAIN}/oauth/device/code`, deviceCodePayload);
|
|
229
|
+
const tokenPayload = {
|
|
230
|
+
grant_type: "urn:ietf:params:oauth:grant-type:device_code",
|
|
231
|
+
device_code: deviceCodeResponse.data["device_code"],
|
|
232
|
+
client_id: AUTH0_CLIENT_ID,
|
|
233
|
+
};
|
|
234
|
+
const authenticationSpinner = ora("waiting for code verification...").start();
|
|
235
|
+
await open(deviceCodeResponse.data["verification_uri_complete"]);
|
|
236
|
+
/**
|
|
237
|
+
* This is a recommended way to poll, since it take some time for a user to enter a `user_code` in a browser.
|
|
238
|
+
* deviceCodeResponse.data['interval'] is a recommended/calculated polling interval specified in seconds.
|
|
239
|
+
*/
|
|
240
|
+
while (true) {
|
|
241
|
+
try {
|
|
242
|
+
const tokenResponse = await axios.post(`https://${AUTH0_DOMAIN}/oauth/token`, tokenPayload);
|
|
243
|
+
await fs__namespace.writeFile(CREDENTIALS_FILE, JSON.stringify(tokenResponse.data));
|
|
244
|
+
authenticationSpinner.succeed("you are successfully authenticated now!");
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
catch (e) {
|
|
248
|
+
if (((_a = e.response.data) === null || _a === void 0 ? void 0 : _a.error) !== "authorization_pending") {
|
|
249
|
+
authenticationSpinner.fail("authentication failed. please try again.");
|
|
250
|
+
process.exit(1);
|
|
251
|
+
}
|
|
252
|
+
await sleep(deviceCodeResponse.data["interval"] * 1000);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
};
|
|
256
|
+
async function getToken() {
|
|
257
|
+
var _a;
|
|
258
|
+
try {
|
|
259
|
+
const rawCredentials = await fs__namespace.readFile(CREDENTIALS_FILE, "utf-8");
|
|
260
|
+
const credentials = JSON.parse(rawCredentials.toString());
|
|
261
|
+
return (_a = credentials === null || credentials === void 0 ? void 0 : credentials.access_token) !== null && _a !== void 0 ? _a : "";
|
|
262
|
+
}
|
|
263
|
+
catch (_e) {
|
|
264
|
+
return "";
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function sleep(ms) {
|
|
268
|
+
return new Promise((res) => setTimeout(res, ms));
|
|
269
|
+
}
|
|
270
|
+
async function resolveFiles() {
|
|
271
|
+
try {
|
|
272
|
+
await fs__namespace.access(CREDENTIALS_DIR);
|
|
273
|
+
}
|
|
274
|
+
catch (_e) {
|
|
275
|
+
await fs__namespace.mkdir(CREDENTIALS_DIR);
|
|
276
|
+
}
|
|
277
|
+
try {
|
|
278
|
+
await fs__namespace.access(CREDENTIALS_FILE);
|
|
279
|
+
}
|
|
280
|
+
catch (e) {
|
|
281
|
+
await fs__namespace.writeFile(CREDENTIALS_FILE, "");
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
var createContext = (coreRoot, clientRoot) => ({
|
|
286
|
+
core: {
|
|
287
|
+
rootDir: coreRoot,
|
|
288
|
+
templatesDir: path__namespace.resolve(coreRoot, "templates"),
|
|
289
|
+
configsDir: path__namespace.resolve(coreRoot, "configs"),
|
|
290
|
+
},
|
|
291
|
+
client: {
|
|
292
|
+
rootDir: clientRoot,
|
|
293
|
+
buildDir: path__namespace.resolve(clientRoot, ".embeddable-build"),
|
|
294
|
+
srcDir: path__namespace.resolve(clientRoot, "src"),
|
|
295
|
+
tmpDir: path__namespace.resolve(clientRoot, ".embeddable-tmp"),
|
|
296
|
+
componentDir: path__namespace.resolve(clientRoot, ".embeddable-build", "component"),
|
|
297
|
+
stencilBuild: path__namespace.resolve(clientRoot, ".embeddable-build", "dist", "embeddable-wrapper"),
|
|
298
|
+
archiveFile: path__namespace.resolve(clientRoot, "embeddable-build.zip"),
|
|
299
|
+
},
|
|
300
|
+
outputOptions: {
|
|
301
|
+
typesEntryPointFilename: "embeddable-types-entry-point.js",
|
|
302
|
+
},
|
|
303
|
+
});
|
|
304
|
+
|
|
305
|
+
const oraP = import('ora');
|
|
306
|
+
const inquirerSelect = import('@inquirer/select');
|
|
307
|
+
const EMB_YAML_FILE_REGEX = /^(.*)\.emb\.ya?ml$/;
|
|
308
|
+
let ora;
|
|
309
|
+
var push = async () => {
|
|
310
|
+
ora = (await oraP).default;
|
|
311
|
+
const ctx = createContext(path__namespace.resolve(__dirname, ".."), process.cwd());
|
|
312
|
+
const token = await verify(ctx);
|
|
313
|
+
const { workspaceId, name: workspaceName } = await selectWorkspace(token);
|
|
314
|
+
const spinnerArchive = ora("archivation...").start();
|
|
315
|
+
const filesList = await sdkUtils.findFiles(ctx.client.srcDir, EMB_YAML_FILE_REGEX);
|
|
316
|
+
await archive(ctx, filesList);
|
|
317
|
+
spinnerArchive.succeed("archivation competed");
|
|
318
|
+
const spinnerPushing = ora("publishing...").start();
|
|
319
|
+
await sendBuild(ctx, { workspaceId, token });
|
|
320
|
+
spinnerPushing.succeed(`published to ${workspaceName}`);
|
|
321
|
+
};
|
|
322
|
+
async function selectWorkspace(token) {
|
|
323
|
+
const workspaceSpinner = ora({
|
|
324
|
+
text: "Fetching workspaces...",
|
|
325
|
+
color: "green",
|
|
326
|
+
discardStdin: false,
|
|
327
|
+
}).start();
|
|
328
|
+
const availableWorkspaces = await getWorkspaces(token);
|
|
329
|
+
let selectedWorkspace;
|
|
330
|
+
if (availableWorkspaces.length === 0) {
|
|
331
|
+
workspaceSpinner.fail("No workspaces found");
|
|
332
|
+
process.exit(1);
|
|
333
|
+
}
|
|
334
|
+
workspaceSpinner.info(`Found ${availableWorkspaces.length} workspace(s)`);
|
|
335
|
+
if (availableWorkspaces.length === 1) {
|
|
336
|
+
selectedWorkspace = availableWorkspaces[0];
|
|
337
|
+
}
|
|
338
|
+
else {
|
|
339
|
+
const select = (await inquirerSelect).default;
|
|
340
|
+
selectedWorkspace = await select({
|
|
341
|
+
message: "Select workspace to push changes",
|
|
342
|
+
choices: availableWorkspaces.map((workspace) => ({
|
|
343
|
+
name: `${workspace.name} (${workspace.workspaceId})`,
|
|
344
|
+
value: workspace,
|
|
345
|
+
})),
|
|
346
|
+
});
|
|
347
|
+
}
|
|
348
|
+
workspaceSpinner.succeed(`Workspace: ${selectedWorkspace.name} (${selectedWorkspace.workspaceId})`);
|
|
349
|
+
return selectedWorkspace;
|
|
350
|
+
}
|
|
351
|
+
async function verify(ctx) {
|
|
352
|
+
try {
|
|
353
|
+
await fs__namespace.access(ctx.client.buildDir);
|
|
354
|
+
}
|
|
355
|
+
catch (_e) {
|
|
356
|
+
console.error("No embeddable build was produced.");
|
|
357
|
+
process.exit(1);
|
|
358
|
+
}
|
|
359
|
+
// TODO: initiate login if no/invalid token.
|
|
360
|
+
const token = await getToken();
|
|
361
|
+
if (!token) {
|
|
362
|
+
console.error("Expired token. Please login again.");
|
|
363
|
+
process.exit(1);
|
|
364
|
+
}
|
|
365
|
+
return token;
|
|
366
|
+
}
|
|
367
|
+
async function archive(ctx, yamlFiles) {
|
|
368
|
+
const output = fsSync__namespace.createWriteStream(ctx.client.archiveFile);
|
|
369
|
+
const _archiver = archiver__namespace.create("zip", {
|
|
370
|
+
zlib: { level: 9 },
|
|
371
|
+
});
|
|
372
|
+
_archiver.pipe(output);
|
|
373
|
+
_archiver.directory(ctx.client.buildDir, false);
|
|
374
|
+
for (const fileData of yamlFiles) {
|
|
375
|
+
_archiver.file(fileData[1], { name: `${fileData[0]}.emb.yaml` });
|
|
376
|
+
}
|
|
377
|
+
await _archiver.finalize();
|
|
378
|
+
return new Promise((resolve, _reject) => {
|
|
379
|
+
output.on("close", resolve);
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
async function sendBuild(ctx, { workspaceId, token }) {
|
|
383
|
+
const { FormData } = await import('formdata-node');
|
|
384
|
+
const { fileFromPath } = await import('formdata-node/file-from-path');
|
|
385
|
+
const file = await fileFromPath(ctx.client.archiveFile, "embeddable-build.zip");
|
|
386
|
+
const form = new FormData();
|
|
387
|
+
form.set("file", file, "embeddable-build.zip");
|
|
388
|
+
await axios.post(`https://api.embeddable.com/sdk/upload-files?workspaceId=${workspaceId}`, form, {
|
|
389
|
+
headers: {
|
|
390
|
+
"Content-Type": "multipart/form-data",
|
|
391
|
+
Authorization: `Bearer ${token}`,
|
|
392
|
+
},
|
|
393
|
+
maxContentLength: Infinity,
|
|
394
|
+
maxBodyLength: Infinity,
|
|
395
|
+
});
|
|
396
|
+
await fs__namespace.rm(ctx.client.archiveFile);
|
|
397
|
+
}
|
|
398
|
+
async function getWorkspaces(token) {
|
|
399
|
+
try {
|
|
400
|
+
return axios
|
|
401
|
+
.get("https://api.embeddable.com/workspace", {
|
|
402
|
+
headers: {
|
|
403
|
+
Authorization: `Bearer ${token}`,
|
|
404
|
+
},
|
|
405
|
+
})
|
|
406
|
+
.then((res) => res.data);
|
|
407
|
+
}
|
|
408
|
+
catch (e) {
|
|
409
|
+
console.error(e);
|
|
410
|
+
return [];
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
exports.build = build;
|
|
415
|
+
exports.login = login;
|
|
416
|
+
exports.push = push;
|
package/dist/login.d.ts
ADDED
package/dist/push.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export declare const defineConfig: ({ plugins }: {
|
|
2
|
+
plugins: any;
|
|
3
|
+
}) => {
|
|
4
|
+
core: {
|
|
5
|
+
rootDir: string;
|
|
6
|
+
templatesDir: string;
|
|
7
|
+
configsDir: string;
|
|
8
|
+
};
|
|
9
|
+
client: {
|
|
10
|
+
rootDir: string;
|
|
11
|
+
buildDir: string;
|
|
12
|
+
srcDir: string;
|
|
13
|
+
tmpDir: string;
|
|
14
|
+
componentDir: string;
|
|
15
|
+
stencilBuild: string;
|
|
16
|
+
archiveFile: string;
|
|
17
|
+
};
|
|
18
|
+
outputOptions: {
|
|
19
|
+
typesEntryPointFilename: string;
|
|
20
|
+
};
|
|
21
|
+
plugins: any;
|
|
22
|
+
};
|
package/lib/embedType.d.ts
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
|
-
export declare const embedType: (typeName: string, typeConfig: {
|
|
1
|
+
export declare const embedType: (typeName: string, typeConfig: TypeConfig) => {
|
|
2
|
+
toString: () => string;
|
|
3
|
+
typeConfig: TypeConfig;
|
|
4
|
+
};
|
|
5
|
+
export type TypeConfig = {
|
|
2
6
|
label: string;
|
|
7
|
+
embeddableDataType?: typeof STRING | typeof NUMBER | typeof BOOLEAN | typeof DATE | typeof DATE_RANGE;
|
|
3
8
|
toString: (_: any) => string;
|
|
4
|
-
|
|
9
|
+
deserialize?: (_: any) => any;
|
|
10
|
+
toEmbeddableDataType?: (_: any) => any;
|
|
11
|
+
};
|
|
12
|
+
declare const STRING = "string";
|
|
13
|
+
declare const NUMBER = "number";
|
|
14
|
+
declare const BOOLEAN = "boolean";
|
|
15
|
+
declare const DATE = "date";
|
|
16
|
+
declare const DATE_RANGE = "dateRange";
|
|
17
|
+
export {};
|