@kernelminds/create-enclave 0.0.1

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.
@@ -0,0 +1,616 @@
1
+ #!/usr/bin/env node
2
+ "use strict";
3
+ var __assign = (this && this.__assign) || function () {
4
+ __assign = Object.assign || function(t) {
5
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
6
+ s = arguments[i];
7
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
8
+ t[p] = s[p];
9
+ }
10
+ return t;
11
+ };
12
+ return __assign.apply(this, arguments);
13
+ };
14
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
15
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
16
+ return new (P || (P = Promise))(function (resolve, reject) {
17
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
18
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
19
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
20
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
21
+ });
22
+ };
23
+ var __generator = (this && this.__generator) || function (thisArg, body) {
24
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
25
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
26
+ function verb(n) { return function (v) { return step([n, v]); }; }
27
+ function step(op) {
28
+ if (f) throw new TypeError("Generator is already executing.");
29
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
30
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
31
+ if (y = 0, t) op = [op[0] & 2, t.value];
32
+ switch (op[0]) {
33
+ case 0: case 1: t = op; break;
34
+ case 4: _.label++; return { value: op[1], done: false };
35
+ case 5: _.label++; y = op[1]; op = [0]; continue;
36
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
37
+ default:
38
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
39
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
40
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
41
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
42
+ if (t[2]) _.ops.pop();
43
+ _.trys.pop(); continue;
44
+ }
45
+ op = body.call(thisArg, _);
46
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
47
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
48
+ }
49
+ };
50
+ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
51
+ if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
52
+ if (ar || !(i in from)) {
53
+ if (!ar) ar = Array.prototype.slice.call(from, 0, i);
54
+ ar[i] = from[i];
55
+ }
56
+ }
57
+ return to.concat(ar || Array.prototype.slice.call(from));
58
+ };
59
+ Object.defineProperty(exports, "__esModule", { value: true });
60
+ var fs = require("fs");
61
+ var path = require("path");
62
+ var child_process = require("child_process");
63
+ var ts = require("typescript");
64
+ var prompt = require("@inquirer/prompts");
65
+ var crypto = require("crypto");
66
+ var applicationIdentifier = "scailo-test-enclave";
67
+ var applicationName = "Scailo Test Enclave";
68
+ var version = "0.0.1";
69
+ var rootFolder = path.dirname(__dirname);
70
+ var selectedEnclaveRuntime = "node";
71
+ var selectedEntryPointManagement = "platform_redirect";
72
+ function acceptUserInputs() {
73
+ return __awaiter(this, void 0, void 0, function () {
74
+ return __generator(this, function (_a) {
75
+ switch (_a.label) {
76
+ case 0: return [4 /*yield*/, prompt.input({
77
+ message: "Enter the Application Name: ",
78
+ default: applicationName,
79
+ required: true,
80
+ validate: function (input) { return input.length > 0; }
81
+ })];
82
+ case 1:
83
+ applicationName = (_a.sent()).trim();
84
+ applicationIdentifier = applicationName.split(" ").join("-").toLowerCase();
85
+ return [4 /*yield*/, prompt.input({
86
+ message: "Enter the Application Identifier: ",
87
+ default: applicationIdentifier,
88
+ required: true,
89
+ validate: function (input) { return input.length > 0; }
90
+ })];
91
+ case 2:
92
+ applicationIdentifier = (_a.sent()).trim();
93
+ return [4 /*yield*/, prompt.input({
94
+ message: "Enter the Initial Version Number (Semver Format): ",
95
+ default: version,
96
+ required: true,
97
+ validate: function (input) { return input.length > 0; }
98
+ })];
99
+ case 3:
100
+ version = (_a.sent()).trim();
101
+ return [4 /*yield*/, prompt.select({
102
+ message: "Select the Enclave Runtime",
103
+ choices: [
104
+ { name: "Node", value: "node", description: "Create a Node based Enclave" },
105
+ { name: "Golang", value: "golang", description: "Create a Golang based Enclave" },
106
+ { name: "Python", value: "python", description: "Create a Python based Enclave" },
107
+ ], default: ""
108
+ })];
109
+ case 4:
110
+ selectedEnclaveRuntime = (_a.sent()).trim();
111
+ return [4 /*yield*/, prompt.select({
112
+ message: "Select the Entry Point Type",
113
+ choices: [
114
+ { name: "Platform Redirect", value: "platform_redirect", description: "Entry Point will be managed by the Platform. The application will need to implement: GET /enclave/".concat(applicationIdentifier, "/ingress/{token}") },
115
+ { name: "Direct URL", value: "direct_url", description: "Entry Point will be managed by the Application. The application will need to implement: GET /" },
116
+ ], default: "platform_redirect"
117
+ })];
118
+ case 5:
119
+ selectedEntryPointManagement = (_a.sent()).trim();
120
+ console.log("Application Name: ".concat(applicationName));
121
+ console.log("Application Identifier: ".concat(applicationIdentifier));
122
+ console.log("Version: ".concat(version));
123
+ console.log("Enclave Runtime: ".concat(selectedEnclaveRuntime));
124
+ console.log("Entry Point Type: ".concat(selectedEntryPointManagement));
125
+ return [2 /*return*/];
126
+ }
127
+ });
128
+ });
129
+ }
130
+ function spawnChildProcess(command, args, options) {
131
+ if (args === void 0) { args = []; }
132
+ if (options === void 0) { options = {}; }
133
+ return new Promise(function (resolve, reject) {
134
+ var child = child_process.spawn(command, args, __assign(__assign({}, options), { shell: process.platform === "win32" ? true : undefined }));
135
+ // Optional: Log stdout and stderr for debugging
136
+ child.stdout.on('data', function (data) {
137
+ console.log("".concat(data));
138
+ });
139
+ child.stderr.on('data', function (data) {
140
+ console.error("stderr: ".concat(data));
141
+ });
142
+ child.on('close', function (code) {
143
+ if (code === 0) {
144
+ resolve("Child process exited with code ".concat(code));
145
+ }
146
+ else {
147
+ reject(new Error("Child process exited with code ".concat(code)));
148
+ }
149
+ });
150
+ child.on('error', function (err) {
151
+ reject(err);
152
+ });
153
+ });
154
+ }
155
+ function setupGitIgnore() {
156
+ return __awaiter(this, void 0, void 0, function () {
157
+ var gitignoreList;
158
+ return __generator(this, function (_a) {
159
+ gitignoreList = [
160
+ "node_modules/",
161
+ ".env",
162
+ "tsconfig.tsbuildinfo",
163
+ ".DS_Store"
164
+ ];
165
+ fs.writeFileSync(".gitignore", gitignoreList.join("\n").trim(), { flag: "w", flush: true });
166
+ return [2 /*return*/];
167
+ });
168
+ });
169
+ }
170
+ function setupCommonNPMDependencies() {
171
+ return __awaiter(this, void 0, void 0, function () {
172
+ var npmDependencies, npmDevDependencies;
173
+ return __generator(this, function (_a) {
174
+ switch (_a.label) {
175
+ case 0:
176
+ npmDependencies = [
177
+ "@kernelminds/scailo-sdk@latest",
178
+ "@bufbuild/protobuf@1.10.0",
179
+ "@connectrpc/connect-web@1.7.0",
180
+ "path-to-regexp@6.1.0"
181
+ ];
182
+ return [4 /*yield*/, spawnChildProcess("npm", __spreadArray(__spreadArray(["install"], npmDependencies, true), ["--save"], false))];
183
+ case 1:
184
+ _a.sent();
185
+ npmDevDependencies = [
186
+ "tailwindcss",
187
+ "@tailwindcss/cli",
188
+ "daisyui@latest",
189
+ "esbuild",
190
+ "@inquirer/prompts@7.8.6",
191
+ "concurrently@9.2.1",
192
+ "semver",
193
+ "@types/semver",
194
+ "yaml",
195
+ "adm-zip",
196
+ "@types/adm-zip",
197
+ "typescript",
198
+ "@types/node",
199
+ "favicons",
200
+ ];
201
+ return [4 /*yield*/, spawnChildProcess("npm", __spreadArray(__spreadArray(["install"], npmDevDependencies, true), ["--save-dev"], false))];
202
+ case 2:
203
+ _a.sent();
204
+ return [2 /*return*/];
205
+ }
206
+ });
207
+ });
208
+ }
209
+ function setupDependencies(_a) {
210
+ return __awaiter(this, arguments, void 0, function (_b) {
211
+ var selectedEnclaveRuntime = _b.selectedEnclaveRuntime;
212
+ return __generator(this, function (_c) {
213
+ switch (_c.label) {
214
+ case 0:
215
+ if (!(selectedEnclaveRuntime == "node")) return [3 /*break*/, 2];
216
+ return [4 /*yield*/, setupDependenciesForNode()];
217
+ case 1:
218
+ _c.sent();
219
+ return [3 /*break*/, 6];
220
+ case 2:
221
+ if (!(selectedEnclaveRuntime == "golang")) return [3 /*break*/, 4];
222
+ return [4 /*yield*/, setupDependenciesForGolang()];
223
+ case 3:
224
+ _c.sent();
225
+ return [3 /*break*/, 6];
226
+ case 4:
227
+ if (!(selectedEnclaveRuntime == "python")) return [3 /*break*/, 6];
228
+ return [4 /*yield*/, setupDependenciesForPython()];
229
+ case 5:
230
+ _c.sent();
231
+ _c.label = 6;
232
+ case 6:
233
+ // Create the tsconfig.json
234
+ return [4 /*yield*/, spawnChildProcess("npx", ["tsc", "--init"])];
235
+ case 7:
236
+ // Create the tsconfig.json
237
+ _c.sent();
238
+ return [2 /*return*/];
239
+ }
240
+ });
241
+ });
242
+ }
243
+ function setupDependenciesForNode() {
244
+ return __awaiter(this, void 0, void 0, function () {
245
+ var npmDependencies;
246
+ return __generator(this, function (_a) {
247
+ switch (_a.label) {
248
+ case 0: return [4 /*yield*/, setupCommonNPMDependencies()];
249
+ case 1:
250
+ _a.sent();
251
+ npmDependencies = [
252
+ "@connectrpc/connect-node@1.7.0",
253
+ "fastify@4.28.1",
254
+ "@fastify/static@7.0.4",
255
+ "fastify-favicon@4.3.0",
256
+ "dotenv",
257
+ "redis@4.7.0",
258
+ "@fastify/cookie@9.4.0",
259
+ "pino-pretty@13.1.2"
260
+ ];
261
+ return [4 /*yield*/, spawnChildProcess("npm", __spreadArray(__spreadArray(["install"], npmDependencies, true), ["--save"], false))];
262
+ case 2:
263
+ _a.sent();
264
+ return [2 /*return*/];
265
+ }
266
+ });
267
+ });
268
+ }
269
+ function setupDependenciesForGolang() {
270
+ return __awaiter(this, void 0, void 0, function () {
271
+ return __generator(this, function (_a) {
272
+ switch (_a.label) {
273
+ case 0: return [4 /*yield*/, setupCommonNPMDependencies()];
274
+ case 1:
275
+ _a.sent();
276
+ return [2 /*return*/];
277
+ }
278
+ });
279
+ });
280
+ }
281
+ function setupDependenciesForPython() {
282
+ return __awaiter(this, void 0, void 0, function () {
283
+ return __generator(this, function (_a) {
284
+ switch (_a.label) {
285
+ case 0: return [4 /*yield*/, setupCommonNPMDependencies()];
286
+ case 1:
287
+ _a.sent();
288
+ return [2 /*return*/];
289
+ }
290
+ });
291
+ });
292
+ }
293
+ function setupScripts() {
294
+ return __awaiter(this, void 0, void 0, function () {
295
+ var scriptsFolderName, folders, _i, folders_1, folder;
296
+ return __generator(this, function (_a) {
297
+ scriptsFolderName = path.join("scripts");
298
+ folders = [
299
+ path.join(scriptsFolderName),
300
+ ];
301
+ for (_i = 0, folders_1 = folders; _i < folders_1.length; _i++) {
302
+ folder = folders_1[_i];
303
+ fs.mkdirSync(folder, { recursive: true });
304
+ }
305
+ // Copy package.ts
306
+ fs.copyFileSync(path.join(rootFolder, "src", "package.ts"), path.join(scriptsFolderName, "package.ts"));
307
+ return [2 /*return*/];
308
+ });
309
+ });
310
+ }
311
+ function createResourcesFolders() {
312
+ var resourcesFolderName = path.join("resources");
313
+ var distFolderName = path.join(resourcesFolderName, "dist");
314
+ var srcFoldername = path.join(resourcesFolderName, "src");
315
+ var resourcesFolders = [
316
+ path.join(resourcesFolderName),
317
+ path.join(distFolderName),
318
+ path.join(distFolderName, "css"),
319
+ path.join(distFolderName, "img"),
320
+ path.join(distFolderName, "js"),
321
+ path.join(srcFoldername),
322
+ path.join(srcFoldername, "ts"),
323
+ path.join(srcFoldername, "css")
324
+ ];
325
+ for (var _i = 0, resourcesFolders_1 = resourcesFolders; _i < resourcesFolders_1.length; _i++) {
326
+ var folder = resourcesFolders_1[_i];
327
+ fs.mkdirSync(folder, { recursive: true });
328
+ }
329
+ var appCSSPath = path.join(srcFoldername, "css", "app.css");
330
+ var appEntryTSPath = path.join(srcFoldername, "ts", "app.ts");
331
+ var routerEntryTSPath = path.join(srcFoldername, "ts", "router.ts");
332
+ // Copy the img folder
333
+ fs.cpSync(path.join(rootFolder, "img"), path.join(distFolderName, "img"), { recursive: true });
334
+ return {
335
+ appCSSPath: appCSSPath,
336
+ distFolderName: distFolderName,
337
+ appEntryTSPath: appEntryTSPath,
338
+ routerEntryTSPath: routerEntryTSPath
339
+ };
340
+ }
341
+ function createBuildScripts(_a) {
342
+ return __awaiter(this, arguments, void 0, function (_b) {
343
+ var packageJSON, packageJSONScripts, scripts, i, script;
344
+ var appCSSPath = _b.appCSSPath, distFolderName = _b.distFolderName, appEntryTSPath = _b.appEntryTSPath, selectedEnclaveRuntime = _b.selectedEnclaveRuntime;
345
+ return __generator(this, function (_c) {
346
+ packageJSON = JSON.parse(fs.readFileSync("package.json", "utf-8"));
347
+ packageJSONScripts = packageJSON.scripts || {};
348
+ scripts = [
349
+ ["css:build", "npx tailwindcss -i ".concat(appCSSPath, " -o ").concat(path.join(distFolderName, "css", "bundle.css"), " --minify")],
350
+ ["css:watch", "npx tailwindcss -i ".concat(appCSSPath, " -o ").concat(path.join(distFolderName, "css", "bundle.css"), " --watch")],
351
+ ["ui:build", "npx esbuild ".concat(appEntryTSPath, " --bundle --outfile=").concat(path.join(distFolderName, "js", "bundle.src.min.js"), " --minify")],
352
+ ["ui:watch", "npx esbuild ".concat(appEntryTSPath, " --bundle --outfile=").concat(path.join(distFolderName, "js", "bundle.src.min.js"), " --watch")],
353
+ ["dev:watch", "npx concurrently \"npm run ui:watch\" \"npm run css:watch\""],
354
+ ["package", "npx tsx scripts/package.ts"],
355
+ ];
356
+ if (selectedEnclaveRuntime == "node") {
357
+ scripts.push(["dev:start", "npx tsx -r dotenv/config server.ts"]);
358
+ scripts.push(["start", "npx tsx server.ts"]); // This is in production
359
+ }
360
+ else if (selectedEnclaveRuntime == "golang") {
361
+ scripts.push(["dev:start", "go run ."]);
362
+ scripts.push(["start", "go run ."]); // This is in production
363
+ }
364
+ else if (selectedEnclaveRuntime == "python") {
365
+ scripts.push(["dev:start", "uv run server.py"]);
366
+ scripts.push(["start", "uv run server.py"]); // This is in production
367
+ }
368
+ for (i = 0; i < scripts.length; i++) {
369
+ script = scripts[i];
370
+ packageJSONScripts[script[0]] = script[1];
371
+ }
372
+ packageJSON.scripts = packageJSONScripts;
373
+ packageJSON.version = version;
374
+ fs.writeFileSync("package.json", JSON.stringify(packageJSON, null, 2), { flag: "w", flush: true });
375
+ return [2 /*return*/];
376
+ });
377
+ });
378
+ }
379
+ function createIndexHTML(_a) {
380
+ return __awaiter(this, arguments, void 0, function (_b) {
381
+ var hrefPrefix, html;
382
+ var appName = _b.appName, version = _b.version, enclaveName = _b.enclaveName, selectedEntryPointManagement = _b.selectedEntryPointManagement;
383
+ return __generator(this, function (_c) {
384
+ hrefPrefix = selectedEntryPointManagement == "platform_redirect" ? "/enclave/".concat(enclaveName) : "";
385
+ html = "\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <link rel=\"shortcut icon\" href=\"".concat(hrefPrefix, "/resources/dist/img/favicon.ico\" type=\"image/x-icon\">\n <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge,chrome=1\" />\n <link rel=\"preload\" as=\"script\" href=\"").concat(hrefPrefix, "/resources/dist/js/bundle.src.min.js\">\n <link rel=\"stylesheet\" href=\"").concat(hrefPrefix, "/resources/dist/css/bundle.css\">\n <title>").concat(appName, "</title>\n</head>\n<body class=\"text-gray-800\">\n <div class=\"container text-center\">\n <h1 class=\"text-3xl font-bold\">").concat(appName, "</h1>\n </div>\n <div id=\"container\" class=\"container\"></div>\n <!-- Attach the JS bundle here -->\n <script src=\"").concat(hrefPrefix, "/resources/dist/js/bundle.src.min.js\"></script>\n</body>\n</html>\n");
386
+ // Create index.html
387
+ fs.writeFileSync("index.html", html.trim(), { flag: "w", flush: true });
388
+ return [2 /*return*/];
389
+ });
390
+ });
391
+ }
392
+ function createEntryTS(_a) {
393
+ return __awaiter(this, arguments, void 0, function (_b) {
394
+ var script;
395
+ var appEntryTSPath = _b.appEntryTSPath, enclaveName = _b.enclaveName, selectedEntryPointManagement = _b.selectedEntryPointManagement;
396
+ return __generator(this, function (_c) {
397
+ script = "\nimport { createConnectTransport } from \"@connectrpc/connect-web\";\nimport { Router } from \"./router\";\n\nexport const enclaveName = \"".concat(enclaveName, "\";\n\n/**\n * Message handler type for Scailo enclave. Receives messages from the parent application\n */\nexport type ScailoEnclaveMessage = {\n type: \"refresh\",\n payload: any\n};\n\n/**\n * Message handler for Scailo enclave\n */\nwindow.addEventListener(\"message\", (evt: MessageEvent<ScailoEnclaveMessage>) => {\n if (evt.data.type == \"refresh\") {\n location.reload();\n }\n});\n\nasync function wait(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n\n/** Starts the router */\nfunction startRouter() {\n let r = new Router();\n const routePrefix = ").concat(selectedEntryPointManagement == "platform_redirect" ? "\`/enclave/\${enclaveName}\`" : "``", ";\n r.add(`${routePrefix}/ui`, async (ctx) => {\n const container = document.getElementById(\"container\") as HTMLDivElement;\n while (true) {\n await wait(1000);\n let payload = await (await fetch(`${routePrefix}/api/random`, { method: \"GET\", headers: { \"Content-Type\": \"application/json\" } })).json() as { random: number };\n container.innerHTML = payload.random.toString();\n }\n });\n\n r.add(`${routePrefix}/404`, async (ctx) => {\n handlePageNotFound(ctx);\n });\n\n r.setDefault((ctx) => {\n location.href = `${routePrefix}/ui`;\n });\n\n r.start();\n}\n\n/** Handles page not found */\nfunction handlePageNotFound(ctx: any) {\n let content = <HTMLDivElement>document.getElementById(\"container\");\n content.innerHTML = \"Invalid page\";\n}\n\nwindow.addEventListener(\"load\", async (evt) => {\n evt.preventDefault();\n startRouter();\n});\n\nexport function getReadTransport() {\n return createConnectTransport({\n // Need to use binary format (at least for the time being)\n baseUrl: location.origin, useBinaryFormat: false, interceptors: []\n });\n}\n");
398
+ // Create index.ts
399
+ fs.writeFileSync(appEntryTSPath, script.trim(), { flag: "w", flush: true });
400
+ return [2 /*return*/];
401
+ });
402
+ });
403
+ }
404
+ function createRouterTS(_a) {
405
+ return __awaiter(this, arguments, void 0, function (_b) {
406
+ var script;
407
+ var routerEntryTSPath = _b.routerEntryTSPath;
408
+ return __generator(this, function (_c) {
409
+ script = "\n\nimport { match, MatchFunction } from \"path-to-regexp\";\n\n/**Stores the relationship between the path and the provided callback */\ninterface relation {\n path: MatchFunction<object> | null\n callback: (ctx: context) => void\n}\n\n/**Class that performs the routing */\nexport class Router {\n relationships: relation[]\n defaultRelation: relation\n\n constructor() {\n this.relationships = [];\n this.defaultRelation = <relation>{};\n }\n\n /**Adds a path along with the callback to the router */\n add(path: string, callback: (ctx: context) => void) {\n let r = <relation>{\n path: match(path),\n callback: callback\n };\n this.relationships.push(r);\n }\n\n setDefault(callback: (ctx: context) => void) {\n this.defaultRelation = {\n path: null,\n callback: callback\n }\n }\n\n /**Navigates the user to the provided href */\n private _navigate(href: string, searchParams: string) {\n if (!href.startsWith(\"tel\")) {\n history.pushState({ href: href, searchParams: searchParams }, \"\", href + searchParams);\n this.traverseRelationships(href, searchParams);\n }\n }\n\n private traverseRelationships(href: string, searchParams: string) {\n for (let i = 0; i < this.relationships.length; i++) {\n let t = this.relationships[i];\n let match = t.path!(href);\n if (match) {\n let c = <context>{\n querystring: searchParams,\n pathname: href,\n path: href + searchParams,\n params: match.params\n }\n t.callback(c);\n return\n }\n }\n this.defaultRelation.callback({\n querystring: location.search,\n pathname: location.pathname,\n path: location.pathname + location.search,\n params: null\n });\n }\n\n _handleAnchorTag(t: HTMLAnchorElement, e: MouseEvent) {\n if (t.getAttribute(\"download\") != null || t.getAttribute(\"target\") != null || t.getAttribute(\"href\") == null) {\n return true\n } else {\n // Prevent default only in the case where the default functionality of the link is being overridden\n e.preventDefault();\n let tempHref = t.href.replace(location.origin, \"\");\n let split = tempHref.split(\"?\");\n let href = \"\";\n let searchParams = \"\";\n if (split.length == 1) {\n href = split[0];\n } else {\n href = split[0];\n searchParams = \"?\" + split[1];\n }\n this._navigate(href, searchParams);\n }\n }\n\n /**Starts the router */\n start() {\n let localThis = this;\n document.addEventListener(\"click\", e => {\n if (e.ctrlKey || e.metaKey) {\n // If control key or any other modifier key has been clicked, do not handle it wih this library\n return true\n }\n let el = <HTMLElement>e.target;\n if (el.nodeName.toLowerCase() == \"a\") {\n this._handleAnchorTag(<HTMLAnchorElement>el, e);\n } else if (el.nodeName.toLowerCase() == \"button\") {\n return true\n } else {\n let parentAnchor: HTMLAnchorElement | null = null;\n let parentEl = el.parentElement;\n if (parentEl == null) {\n return true\n }\n while (parentEl != null) {\n if (parentEl.nodeName.toLowerCase() == \"body\") {\n break\n }\n if (parentEl.nodeName.toLowerCase() == \"a\") {\n parentAnchor = <HTMLAnchorElement>parentEl;\n break\n }\n parentEl = parentEl.parentElement;\n }\n if (parentAnchor == null) {\n return true\n }\n // Handle click of the parent element here\n this._handleAnchorTag(parentAnchor, e);\n }\n });\n\n window.addEventListener(\"popstate\", function (e) {\n e.preventDefault();\n localThis.traverseRelationships(location.pathname, location.search)\n });\n\n /**Create the global function to route to a certain URL */\n (<any>window).routeTo = function (url: string) {\n let t = new URL(location.origin + url);\n localThis._navigate(t.pathname, t.search);\n }\n\n this._navigate(location.pathname, location.search);\n }\n}\n\n/**Stores the router parameters */\nexport interface context {\n querystring: string\n /**Is the object that consists of the matched parameters */\n params: any\n /**The pathname void of query string \"/login\" */\n pathname: string\n /**Pathname and query string \"/login?foo=bar\" */\n path: string\n}\n \n";
410
+ // Create router.ts
411
+ fs.writeFileSync(routerEntryTSPath, script.trim(), { flag: "w", flush: true });
412
+ return [2 /*return*/];
413
+ });
414
+ });
415
+ }
416
+ function createManifest(_a) {
417
+ return __awaiter(this, arguments, void 0, function (_b) {
418
+ var startExec, manifest;
419
+ var appName = _b.appName, version = _b.version, enclaveName = _b.enclaveName, appIdentifier = _b.appIdentifier, selectedEnclaveRuntime = _b.selectedEnclaveRuntime, selectedEntryPointManagement = _b.selectedEntryPointManagement;
420
+ return __generator(this, function (_c) {
421
+ startExec = "";
422
+ if (selectedEnclaveRuntime == "node") {
423
+ startExec = "npm start";
424
+ }
425
+ else if (selectedEnclaveRuntime == "golang") {
426
+ startExec = "go run .";
427
+ }
428
+ else if (selectedEnclaveRuntime == "python") {
429
+ startExec = "uv run server.py";
430
+ }
431
+ manifest = "\nmanifest_version: 1\nenclave_runtime: ".concat(selectedEnclaveRuntime, "\napp_version: ").concat(version, "\napp_name: ").concat(appName, "\nenclave_name: ").concat(enclaveName, "\napp_unique_identifier: \"").concat(appIdentifier, "\"\nstart_exec: \"").concat(startExec, "\"\nentry_point_management: \"").concat(selectedEntryPointManagement, "\"\nenv_variables:\n - name: APP_NAME\n value: \"").concat(appName, "\"\n is_secret: false\n - name: ENCLAVE_NAME\n value: \"").concat(enclaveName, "\"\n is_secret: false\n - name: APP_UNIQUE_IDENTIFIER\n value: \"").concat(appIdentifier, "\"\n is_secret: false\nresources:\n logos:\n - resources/dist/img/logo.png\n folders: []");
432
+ if (selectedEnclaveRuntime == "node") {
433
+ manifest += "\n files:\n - index.html\n - server.ts\n - utils.ts\n ";
434
+ }
435
+ else if (selectedEnclaveRuntime == "golang") {
436
+ manifest += "\n files:\n - index.html\n - server.go\n - utils.go\n - go.mod\n - go.sum\n ";
437
+ }
438
+ else if (selectedEnclaveRuntime == "python") {
439
+ manifest += "\n files:\n - index.html\n - server.py\n - utils.py\n - pyproject.toml\n - uv.lock\n - .python-version\n ";
440
+ }
441
+ // Create MANIFEST.yaml
442
+ fs.writeFileSync("MANIFEST.yaml", manifest.trim(), { flag: "w", flush: true });
443
+ return [2 /*return*/];
444
+ });
445
+ });
446
+ }
447
+ function getUtilsForNode(entryPoint) {
448
+ var f = "\nexport function getEnclavePrefix(enclaveName: string): string {\n return ".concat(entryPoint == "platform_redirect" ? '`/enclave/${enclaveName}`' : "\"\"", "\n}\n");
449
+ return f;
450
+ }
451
+ function getUtilsForGolang(entryPoint) {
452
+ var f = "\npackage main\n\nimport \"fmt\"\n\nfunc getEnclavePrefix(enclaveName string) string {\n\treturn ".concat(entryPoint == "platform_redirect" ? "fmt.Sprintf(\"/enclave/%s\", enclaveName)" : "\"\"", "\n}\n");
453
+ return f;
454
+ }
455
+ function getUtilsForPython(entryPoint) {
456
+ var f = "\ndef get_enclave_prefix(enclave_name: str) -> str:\n return ".concat(entryPoint == "platform_redirect" ? 'f"/enclave/{enclave_name}"' : "\"\"", "\n");
457
+ return f;
458
+ }
459
+ function createTestServer(_a) {
460
+ return __awaiter(this, arguments, void 0, function (_b) {
461
+ var envFile;
462
+ var selectedEnclaveRuntime = _b.selectedEnclaveRuntime, enclaveName = _b.enclaveName, entryPoint = _b.entryPoint;
463
+ return __generator(this, function (_c) {
464
+ if (selectedEnclaveRuntime == "node") {
465
+ fs.copyFileSync(path.join(rootFolder, "server", "node", "server.ts"), "server.ts");
466
+ fs.writeFileSync("utils.ts", getUtilsForNode(entryPoint).trim(), { flag: "w", flush: true });
467
+ }
468
+ else if (selectedEnclaveRuntime == "golang") {
469
+ fs.copyFileSync(path.join(rootFolder, "server", "golang", "server.go"), "server.go");
470
+ fs.writeFileSync("utils.go", getUtilsForGolang(entryPoint).trim(), { flag: "w", flush: true });
471
+ fs.copyFileSync(path.join(rootFolder, "server", "golang", "go.mod"), "go.mod");
472
+ fs.copyFileSync(path.join(rootFolder, "server", "golang", "go.sum"), "go.sum");
473
+ }
474
+ else if (selectedEnclaveRuntime == "python") {
475
+ fs.copyFileSync(path.join(rootFolder, "server", "python", "server.py"), "server.py");
476
+ fs.writeFileSync("utils.py", getUtilsForPython(entryPoint).trim(), { flag: "w", flush: true });
477
+ fs.copyFileSync(path.join(rootFolder, "server", "python", "pyproject.toml"), "pyproject.toml");
478
+ fs.copyFileSync(path.join(rootFolder, "server", "python", "uv.lock"), "uv.lock");
479
+ fs.copyFileSync(path.join(rootFolder, "server", "python", ".python-version"), ".python-version");
480
+ }
481
+ envFile = "\nENCLAVE_NAME=".concat(enclaveName, "\nSCAILO_API=http://127.0.0.1:21000\nPORT=9090\nPRODUCTION=false\nUSERNAME=\nPASSWORD=\n\n# Redis\nREDIS_USERNAME=\nREDIS_PASSWORD=\nREDIS_URL=localhost:6379\n\nWORKFLOW_EVENTS_CHANNEL=GENESIS-WORKFLOW-EVENTS\nCOOKIE_SIGNATURE_SECRET=").concat(crypto.randomBytes(32).toString('hex'));
482
+ fs.writeFileSync(".env", envFile.trim(), { flag: "w", flush: true });
483
+ return [2 /*return*/];
484
+ });
485
+ });
486
+ }
487
+ function fixTSConfig() {
488
+ return __awaiter(this, void 0, void 0, function () {
489
+ var configFileName, configFileText, _a, config, error, parsedCommandLine;
490
+ return __generator(this, function (_b) {
491
+ configFileName = ts.findConfigFile("tsconfig.json", ts.sys.fileExists);
492
+ if (!configFileName) {
493
+ throw new Error("Could not find a valid tsconfig.json");
494
+ }
495
+ configFileText = ts.sys.readFile(configFileName);
496
+ if (!configFileText) {
497
+ throw new Error("Could not read file ".concat(configFileName));
498
+ }
499
+ _a = ts.parseConfigFileTextToJson(configFileName, configFileText), config = _a.config, error = _a.error;
500
+ if (error) {
501
+ throw new Error("Error parsing tsconfig.json: ".concat(error.messageText));
502
+ }
503
+ parsedCommandLine = ts.parseJsonConfigFileContent(config, ts.sys, path.dirname(configFileName));
504
+ parsedCommandLine.options.verbatimModuleSyntax = false;
505
+ parsedCommandLine.options.sourceMap = false;
506
+ parsedCommandLine.options.declaration = false;
507
+ parsedCommandLine.options.declarationMap = false;
508
+ fs.writeFileSync("tsconfig.json", JSON.stringify(parsedCommandLine, null, 4), { flag: "w", flush: true });
509
+ return [2 /*return*/];
510
+ });
511
+ });
512
+ }
513
+ function runPostSetupScripts(_a) {
514
+ return __awaiter(this, arguments, void 0, function (_b) {
515
+ var selectedEnclaveRuntime = _b.selectedEnclaveRuntime;
516
+ return __generator(this, function (_c) {
517
+ switch (_c.label) {
518
+ case 0:
519
+ // Run the first CSS build
520
+ return [4 /*yield*/, spawnChildProcess("npm", ["run", "css:build"])];
521
+ case 1:
522
+ // Run the first CSS build
523
+ _c.sent();
524
+ return [4 /*yield*/, spawnChildProcess("npm", ["run", "ui:build"])];
525
+ case 2:
526
+ _c.sent();
527
+ if (!(selectedEnclaveRuntime == "node")) return [3 /*break*/, 3];
528
+ return [3 /*break*/, 8];
529
+ case 3:
530
+ if (!(selectedEnclaveRuntime == "golang")) return [3 /*break*/, 6];
531
+ return [4 /*yield*/, spawnChildProcess("go", ["mod", "tidy"])];
532
+ case 4:
533
+ _c.sent();
534
+ return [4 /*yield*/, spawnChildProcess("goimports", ["-w", "."])];
535
+ case 5:
536
+ _c.sent();
537
+ return [3 /*break*/, 8];
538
+ case 6:
539
+ if (!(selectedEnclaveRuntime == "python")) return [3 /*break*/, 8];
540
+ return [4 /*yield*/, spawnChildProcess("uv", ["sync", "--all-groups"])];
541
+ case 7:
542
+ _c.sent();
543
+ _c.label = 8;
544
+ case 8: return [2 /*return*/];
545
+ }
546
+ });
547
+ });
548
+ }
549
+ /**
550
+ * Constant that stores the daisyUI plugin
551
+ */
552
+ var daisyUiPlugin = "\n@plugin \"daisyui\" {\n themes: light --default, dark --prefersdark;\n}";
553
+ function main() {
554
+ return __awaiter(this, void 0, void 0, function () {
555
+ var _a, appCSSPath, distFolderName, appEntryTSPath, routerEntryTSPath;
556
+ return __generator(this, function (_b) {
557
+ switch (_b.label) {
558
+ case 0: return [4 /*yield*/, acceptUserInputs()];
559
+ case 1:
560
+ _b.sent();
561
+ // Create the destination folder
562
+ fs.mkdirSync(applicationIdentifier, { recursive: true });
563
+ // Copy the .vscode folder
564
+ fs.mkdirSync(path.join(applicationIdentifier, ".vscode"), { recursive: true });
565
+ fs.cpSync(path.join(rootFolder, ".vscode"), path.join(applicationIdentifier, ".vscode"), { recursive: true });
566
+ fs.copyFileSync(path.join(rootFolder, "README.md"), path.join(applicationIdentifier, "README.md"));
567
+ // Change the directory
568
+ process.chdir(applicationIdentifier);
569
+ // Create the package.json
570
+ return [4 /*yield*/, spawnChildProcess("npm", ["init", "-y"])];
571
+ case 2:
572
+ // Create the package.json
573
+ _b.sent();
574
+ return [4 /*yield*/, setupGitIgnore()];
575
+ case 3:
576
+ _b.sent();
577
+ return [4 /*yield*/, setupDependencies({ selectedEnclaveRuntime: selectedEnclaveRuntime })];
578
+ case 4:
579
+ _b.sent();
580
+ return [4 /*yield*/, setupScripts()];
581
+ case 5:
582
+ _b.sent();
583
+ _a = createResourcesFolders(), appCSSPath = _a.appCSSPath, distFolderName = _a.distFolderName, appEntryTSPath = _a.appEntryTSPath, routerEntryTSPath = _a.routerEntryTSPath;
584
+ // Create the input css
585
+ fs.writeFileSync(appCSSPath, ["@import \"tailwindcss\"", daisyUiPlugin].map(function (a) { return "".concat(a, ";"); }).join("\n"), { flag: "w", flush: true });
586
+ return [4 /*yield*/, createIndexHTML({ appName: applicationName, version: version, enclaveName: applicationIdentifier, selectedEntryPointManagement: selectedEntryPointManagement })];
587
+ case 6:
588
+ _b.sent();
589
+ return [4 /*yield*/, createEntryTS({ appEntryTSPath: appEntryTSPath, enclaveName: applicationIdentifier, selectedEntryPointManagement: selectedEntryPointManagement })];
590
+ case 7:
591
+ _b.sent();
592
+ return [4 /*yield*/, createRouterTS({ routerEntryTSPath: routerEntryTSPath })];
593
+ case 8:
594
+ _b.sent();
595
+ return [4 /*yield*/, createManifest({ appName: applicationName, version: version, enclaveName: applicationIdentifier, appIdentifier: "".concat(applicationIdentifier, ".enc"), selectedEnclaveRuntime: selectedEnclaveRuntime, selectedEntryPointManagement: selectedEntryPointManagement })];
596
+ case 9:
597
+ _b.sent();
598
+ return [4 /*yield*/, createTestServer({ selectedEnclaveRuntime: selectedEnclaveRuntime, enclaveName: applicationIdentifier, entryPoint: selectedEntryPointManagement })];
599
+ case 10:
600
+ _b.sent();
601
+ return [4 /*yield*/, createBuildScripts({ appCSSPath: appCSSPath, distFolderName: distFolderName, appEntryTSPath: appEntryTSPath, selectedEnclaveRuntime: selectedEnclaveRuntime })];
602
+ case 11:
603
+ _b.sent();
604
+ return [4 /*yield*/, fixTSConfig()];
605
+ case 12:
606
+ _b.sent();
607
+ return [4 /*yield*/, runPostSetupScripts({ selectedEnclaveRuntime: selectedEnclaveRuntime })];
608
+ case 13:
609
+ _b.sent();
610
+ console.log("Your app is ready! What are you going to build?");
611
+ return [2 /*return*/];
612
+ }
613
+ });
614
+ });
615
+ }
616
+ main();
Binary file
package/img/logo.png ADDED
Binary file