diff --git a/bin/compile.ts b/bin/compile.ts new file mode 100644 index 0000000..0c3c049 --- /dev/null +++ b/bin/compile.ts @@ -0,0 +1,99 @@ +#!/usr/bin/env node + +/* eslint-disable @typescript-eslint/no-var-requires */ + +'use strict'; + +import { createRequire } from 'module'; +import path from 'path'; + +import meow from 'meow'; +import * as TS from 'typescript'; + +import { AppsCompiler } from '../src'; + +const { promises: fs, constants: { R_OK: READ_ACCESS } } = require('fs'); + + +const log = require('simple-node-logger').createSimpleLogger({ + timestampFormat: 'YYYY-MM-DD HH:mm:ss.SSS', +}); + +type CLIFlagTypes = { + sourceDir: meow.StringFlag, + outputFile: meow.StringFlag, +}; + +const CLIResult = meow(` +USAGE + $ compile -s [path/to/source/app] -o [path/to/output/file] +`, +{ + flags: { + outputFile: { + type: 'string', + alias: 'o', + isRequired: true, + }, + sourceDir: { + type: 'string', + alias: 's', + isRequired: true, + }, + }, +}); + +log.setLevel(process.env.LOG_LEVEL || 'info'); + +async function run(cli: typeof CLIResult) { + const sourceDir = path.resolve(cli.flags.sourceDir as string); + const outputFile = path.resolve(cli.flags.outputFile as string); + + log.info('Compiling app at ', sourceDir); + + const sourceAppManifest = path.format({ dir: sourceDir, base: 'app.json' }); + + try { + log.debug('Checking access to app\'s source folder'); + + await fs.access(sourceAppManifest, READ_ACCESS); + } catch (error) { + log.error(`Can't read app's manifest in "${ sourceAppManifest }". Are you sure there is an app there?`); + throw error; + } + + const appRequire = createRequire(sourceAppManifest); + + log.debug('Created require function for the app\'s folder scope'); + + let appTs: typeof TS; + + try { + appTs = appRequire('typescript'); + + log.debug(`Using TypeScript ${ appTs.version } as specified in app's dependencies`); + } catch { + log.debug("App doesn't have the typescript package as a dependency - compiler will fall back to TypeScript 2.9.2"); + } + + try { + const compiler = new AppsCompiler(appTs); + + log.debug('Starting compilation...'); + + const diag = await compiler.compile(sourceDir); + + log.debug('Compilation complete, diagnostics: ', diag); + log.debug('Starting packaging...'); + + await compiler.outputZip(outputFile); + } catch (error) { + log.error('Compilation was unsuccessful'); + throw error; + } + + log.info('Compilation successful! Package saved at ', outputFile); +} + +// eslint-disable-next-line +run(CLIResult).catch(err => (console.error(err), process.exitCode = 1)); diff --git a/custom-scripts/compile.ts b/custom-scripts/compile.ts deleted file mode 100644 index e6e7134..0000000 --- a/custom-scripts/compile.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { join, normalize } from 'path'; - -import { AppsCompiler } from '../src/AppsCompiler'; - -function getPath() { - const dir = process.argv[2]; - const resolved = normalize(join(process.cwd(), dir)); - return resolved; -} - -(async () => { - const compiler = new AppsCompiler(); - await compiler.compile(getPath()); - await compiler.outputZip('./testing.zip'); -})(); diff --git a/package-lock.json b/package-lock.json index d22abd9..5e599b1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,7 +8,6 @@ "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.4.tgz", "integrity": "sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg==", - "dev": true, "requires": { "@babel/highlight": "^7.10.4" } @@ -16,14 +15,12 @@ "@babel/helper-validator-identifier": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz", - "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==", - "dev": true + "integrity": "sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw==" }, "@babel/highlight": { "version": "7.10.4", "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.4.tgz", "integrity": "sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA==", - "dev": true, "requires": { "@babel/helper-validator-identifier": "^7.10.4", "chalk": "^2.0.0", @@ -31,16 +28,15 @@ } }, "@rocket.chat/apps-engine": { - "version": "1.16.0", - "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.16.0.tgz", - "integrity": "sha512-hUqctTnf2g4aD3zBC3ou9nsLdKvM88m4yz8hfon1xaMEu0KScByiVESOSH0AmzfEDnkUw9DECxhURA9gsrL2KQ==", + "version": "1.18.0-alpha.3754", + "resolved": "https://registry.npmjs.org/@rocket.chat/apps-engine/-/apps-engine-1.18.0-alpha.3754.tgz", + "integrity": "sha512-R8TsCtQ9s63YfofHkNs9MucXPXAcz8lhHi0t1CF3nJPyg5Nh93Hgq0kktqqQE6Awd/fWgMBDX46S83x8JHgLFg==", "requires": { "adm-zip": "^0.4.9", "cryptiles": "^4.1.3", "lodash.clonedeep": "^4.5.0", "semver": "^5.5.0", "stack-trace": "0.0.10", - "typescript": "^2.9.2", "uuid": "^3.2.1" }, "dependencies": { @@ -145,6 +141,11 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=" + }, "@types/mocha": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-8.0.0.tgz", @@ -157,6 +158,11 @@ "integrity": "sha512-mikldZQitV94akrc4sCcSjtJfsTKt4p+e/s0AGscVA6XArQ9kFclP+ZiYUMnq987rc6QlYxXv/EivqlfSLxpKA==", "dev": true }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==" + }, "@types/parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", @@ -359,7 +365,6 @@ "version": "3.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -422,6 +427,11 @@ "is-string": "^1.0.4" } }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + }, "assertion-error": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", @@ -620,8 +630,17 @@ "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==" + }, + "camelcase-keys": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", + "requires": { + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" + } }, "chai": { "version": "4.2.0", @@ -641,7 +660,6 @@ "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -652,7 +670,6 @@ "version": "5.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -745,7 +762,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -753,8 +769,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "compare-versions": { "version": "3.6.0", @@ -857,8 +872,23 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + } + } }, "decompress-response": { "version": "3.3.0", @@ -963,7 +993,6 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, "requires": { "is-arrayish": "^0.2.1" } @@ -1377,7 +1406,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, "requires": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -1543,6 +1571,11 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==" + }, "has": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", @@ -1555,8 +1588,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.1", @@ -1584,8 +1616,7 @@ "hosted-git-info": { "version": "2.8.8", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.8.tgz", - "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==", - "dev": true + "integrity": "sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==" }, "http-cache-semantics": { "version": "4.1.0", @@ -1691,6 +1722,11 @@ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", "dev": true }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==" + }, "inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -1720,8 +1756,7 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-binary-path": { "version": "2.1.0", @@ -1820,6 +1855,11 @@ "integrity": "sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg==", "dev": true }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=" + }, "is-regex": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", @@ -1893,8 +1933,7 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.13.1", @@ -1918,6 +1957,11 @@ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", "dev": true }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1956,6 +2000,11 @@ "json-buffer": "3.0.0" } }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==" + }, "latest-version": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-5.1.0.tgz", @@ -1978,8 +2027,7 @@ "lines-and-columns": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz", - "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", - "dev": true + "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=" }, "load-json-file": { "version": "2.0.0", @@ -1997,7 +2045,6 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, "requires": { "p-locate": "^4.1.0" } @@ -2005,8 +2052,7 @@ "lodash": { "version": "4.17.19", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", - "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==", - "dev": true + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash.clonedeep": { "version": "4.5.0", @@ -2051,12 +2097,102 @@ "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", "dev": true }, + "map-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==" + }, + "meow": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "requires": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "dependencies": { + "parse-json": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.1.0.tgz", + "integrity": "sha512-+mi/lmVVNKFNVyLXV31ERiy2CY5E1/F6QtJFEzoChPRwwngMNXRDQ9GJ5WdE2Z2P4AujsOi0/+2qHID68KwfIQ==", + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "requires": { + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==" + } + } + }, + "read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "requires": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" + } + } + }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==" + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "mimic-response": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==" + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -2071,6 +2207,16 @@ "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true }, + "minimist-options": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + } + }, "mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -2113,6 +2259,11 @@ "yargs-unparser": "1.6.0" } }, + "moment": { + "version": "2.27.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.27.0.tgz", + "integrity": "sha512-al0MUK7cpIcglMv3YF13qSgdAIqxHTO7brRtaz3DlSULbqfazqkc5kEjNrLDOM7fsjshoFIihnU8snrP7zUvhQ==" + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -2173,7 +2324,6 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, "requires": { "hosted-git-info": "^2.1.4", "resolve": "^1.10.0", @@ -2184,8 +2334,7 @@ "semver": { "version": "5.7.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -2275,7 +2424,6 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, "requires": { "p-try": "^2.0.0" } @@ -2284,7 +2432,6 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, "requires": { "p-limit": "^2.2.0" } @@ -2292,8 +2439,7 @@ "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==" }, "package-json": { "version": "6.5.0", @@ -2336,8 +2482,7 @@ "path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" }, "path-is-absolute": { "version": "1.0.1", @@ -2353,8 +2498,7 @@ "path-parse": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", - "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", - "dev": true + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==" }, "path-type": { "version": "2.0.0", @@ -2514,6 +2658,11 @@ "escape-goat": "^2.0.0" } }, + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==" + }, "rc": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", @@ -2615,6 +2764,15 @@ "picomatch": "^2.0.7" } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, "regexpp": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", @@ -2655,7 +2813,6 @@ "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", - "dev": true, "requires": { "path-parse": "^1.0.6" } @@ -2752,6 +2909,15 @@ "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", "dev": true }, + "simple-node-logger": { + "version": "18.12.24", + "resolved": "https://registry.npmjs.org/simple-node-logger/-/simple-node-logger-18.12.24.tgz", + "integrity": "sha512-4dTqpYecHsvPjWo+i+J3pLty8WJDNbxOVesNj5ch8pYH95LIGAFH4dxMSqyf+Os0RTchXifEtI/mfm3AVJftmg==", + "requires": { + "lodash": "^4.17.12", + "moment": "^2.20.1" + } + }, "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -2789,7 +2955,6 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -2798,14 +2963,12 @@ "spdx-exceptions": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true + "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==" }, "spdx-expression-parse": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -2814,8 +2977,7 @@ "spdx-license-ids": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.5.tgz", - "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==", - "dev": true + "integrity": "sha512-J+FWzZoynJEXGphVIS+XEh3kFSjZX/1i9gFBaWQcB+/tmpe2qUsSBABpcxqxnAxFdiUFEgAX1bjYGQvIZmoz9Q==" }, "sprintf-js": { "version": "1.0.3", @@ -2873,6 +3035,14 @@ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "requires": { + "min-indent": "^1.0.0" + } + }, "strip-json-comments": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", @@ -2972,6 +3142,11 @@ "nopt": "~1.0.10" } }, + "trim-newlines": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==" + }, "ts-node": { "version": "8.10.2", "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.2.tgz", @@ -3050,7 +3225,8 @@ "typescript": { "version": "2.9.2", "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.9.2.tgz", - "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==" + "integrity": "sha512-Gr4p6nFNaoufRIY4NMdpQRNmgxVIGMs4Fcu/ujdYk3nAZqk7supzBE9idmvfZIlH/Cuj//dvi+019qEue9lV0w==", + "dev": true }, "undefsafe": { "version": "2.0.3", @@ -3183,7 +3359,6 @@ "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", - "dev": true, "requires": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" diff --git a/package.json b/package.json index 43067f3..4d0590f 100644 --- a/package.json +++ b/package.json @@ -2,15 +2,16 @@ "name": "@rocket.chat/apps-compiler", "version": "0.0.1", "description": "The Rocket.Chat apps compiler", + "type": "module", "main": "dist/index.js", "scripts": { "test": "mocha -r ts-node/register './tests/**/*.spec.ts'", "test:watch": "mocha --require ts-node/register --watch --watch-files src, 'tests/**/*.ts'", "build": "tsc", "lint": "npx eslint src/**/*.ts", - "dev": "nodemon", - "compile": "node -r ts-node/register ./custom-scripts/compile.ts", - "compile:debug": "node -r ts-node/register --inspect ./custom-scripts/compile.ts" + "dev": "nodemon --watch 'src/**/*.ts' --exec 'ts-node' ./index.ts", + "dev:debug": "nodemon --watch 'src/**/*.ts' --exec node -r ts-node/register --inspect --inspect=0.0.0.0:9229 ./index.ts ", + "compile": "node -r ts-node/register bin/compile.ts" }, "repository": { "type": "git", @@ -30,31 +31,33 @@ "devDependencies": { "@rocket.chat/eslint-config": "^0.4.0", "@types/chai": "^4.2.12", + "@types/fs-extra": "^8.0.0", + "@types/glob": "^7.1.1", + "@types/lodash.clonedeep": "^4.5.3", "@types/mocha": "^8.0.0", "@types/node": "^14.0.26", - "@types/glob": "^7.1.1", "@types/tv4": "^1.2.29", + "@types/yazl": "^2.4.1", "@typescript-eslint/eslint-plugin": "^3.7.1", "@typescript-eslint/parser": "^3.7.1", - "@types/lodash.clonedeep": "^4.5.3", "chai": "^4.2.0", "eslint": "^7.5.0", "husky": "^4.2.5", "mocha": "^8.0.1", - "ts-node": "^8.10.2", "nodemon": "^2.0.4", - "@types/fs-extra": "^8.0.0", - "@types/yazl": "^2.4.1" + "ts-node": "^8.10.2" }, "dependencies": { + "@rocket.chat/apps-engine": "^1.18.0-alpha.3754", + "figures": "^3.0.0", "fs-extra": "^8.1.0", - "lodash.clonedeep": "^4.5.0", - "typescript": "^2.9.2", - "@rocket.chat/apps-engine": "1.16.0", - "yazl": "^2.5.1", "glob": "^7.1.4", + "lodash.clonedeep": "^4.5.0", + "meow": "^7.1.1", + "simple-node-logger": "^18.12.24", "tv4": "^1.3.0", - "figures": "^3.0.0" + "typescript": "^2.9.2", + "yazl": "^2.5.1" }, "husky": { "hooks": { diff --git a/src/AppsCompiler.ts b/src/AppsCompiler.ts index af2223a..10d3209 100644 --- a/src/AppsCompiler.ts +++ b/src/AppsCompiler.ts @@ -1,11 +1,12 @@ import * as fs from 'fs'; import * as path from 'path'; -import fallbackTypescript, { +import * as fallbackTypescript from 'typescript'; +import { CompilerOptions, Diagnostic, EmitOutput, HeritageClause, LanguageServiceHost, ModuleResolutionHost, ResolvedModule, SourceFile } from 'typescript'; import { promisify } from 'util'; -import { getAppSource } from './compiler/getAppSouce'; +import { getAppSource } from './compiler/getAppSource'; import { IAppsCompiler, IAppSource, ICompilerFile, ICompilerResult, IMapCompilerFile } from './definition'; import { IFiles } from './definition/IFiles'; import { Utilities } from './misc/Utilities'; @@ -51,7 +52,7 @@ export class AppsCompiler implements IAppsCompiler { try { const source = await getAppSource(path); - const { files, implemented, diagnostics } = this.toJs(source, path); + const { files, implemented, diagnostics } = this.toJs(source); this.compiled = Object.entries(files) .map(([, { name, compiled }]) => ({ [name]: compiled })) @@ -81,12 +82,12 @@ export class AppsCompiler implements IAppsCompiler { return; } - const packager = new AppPackager(fd, this.compiled, outputPath); + const packager = new AppPackager(fd, this, outputPath); const readFile = promisify(fs.readFile); return readFile(await packager.zipItUp()); } - private toJs({ appInfo, files }: IAppSource, appPath: string): ICompilerResult { + private toJs({ appInfo, sourceFiles: files }: IAppSource): ICompilerResult { if (!appInfo.classFile || !files[appInfo.classFile] || !this.isValidFile(files[appInfo.classFile])) { throw new Error(`Invalid App package. Could not find the classFile (${ appInfo.classFile }) file.`); } @@ -121,7 +122,7 @@ export class AppsCompiler implements IAppsCompiler { return this.ts.ScriptSnapshot.fromString(file.content); }, getCompilationSettings: () => this.compilerOptions, - getCurrentDirectory: () => appPath, + getCurrentDirectory: () => this.wd, getDefaultLibFileName: () => this.ts.getDefaultLibFilePath(this.compilerOptions), fileExists: (fileName: string): boolean => this.ts.sys.fileExists(fileName), readFile: (fileName: string): string | undefined => this.ts.sys.readFile(fileName), @@ -132,7 +133,7 @@ export class AppsCompiler implements IAppsCompiler { }; for (const moduleName of moduleNames) { - this.resolver(moduleName, resolvedModules, containingFile, result, appPath, moduleResHost); + this.resolver(moduleName, resolvedModules, containingFile, result, this.wd, moduleResHost); } // @TODO deal with this later @@ -190,14 +191,19 @@ export class AppsCompiler implements IAppsCompiler { if (diagnostic.file) { const { line, character } = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start); - console.log(`Error ${ diagnostic.file.fileName } (${ line + 1 },${ character + 1 }): ${ message }`); + console.error(`Error ${ diagnostic.file.fileName } (${ line + 1 },${ character + 1 }): ${ message }`); } else { - console.log(`Error: ${ message }`); + console.error(`Error: ${ message }`); } }); } - result.diagnostics = this.ts.getPreEmitDiagnostics(languageService.getProgram()); + // TypeScript alerted for `readonly` value from `getPreEmitDiagnostics` being assigned to the mutable `result.diagnostics` + Object.defineProperty(result, 'diagnostics', { + value: this.ts.getPreEmitDiagnostics(languageService.getProgram()), + configurable: false, + writable: false, + }); Object.keys(result.files).forEach((key) => { const file: ICompilerFile = result.files[key]; @@ -208,6 +214,11 @@ export class AppsCompiler implements IAppsCompiler { logErrors(file.name); } + file.name = key.replace(/\.ts/g, '.js'); + + delete result.files[key]; + result.files[file.name] = file; + file.compiled = output.outputFiles[0].text; }); diff --git a/src/compiler/getAppSouce.ts b/src/compiler/getAppSource.ts similarity index 98% rename from src/compiler/getAppSouce.ts rename to src/compiler/getAppSource.ts index 3a98bea..7cbd3eb 100644 --- a/src/compiler/getAppSouce.ts +++ b/src/compiler/getAppSource.ts @@ -86,5 +86,5 @@ export async function getAppSource(path: string): Promise { const appInfo: IAppInfo = getAppInfo(projectFiles); const files: IMapCompilerFile = makeICompilerFileMap(tsFiles); - return { appInfo, files }; + return { appInfo, sourceFiles: files }; } diff --git a/src/definition/IAppSource.ts b/src/definition/IAppSource.ts index 31f2f9d..11c3e45 100644 --- a/src/definition/IAppSource.ts +++ b/src/definition/IAppSource.ts @@ -3,5 +3,5 @@ import { IAppInfo } from './IAppInfo'; export interface IAppSource { appInfo: IAppInfo; - files: { [filename: string]: ICompilerFile }; + sourceFiles: { [filename: string]: ICompilerFile }; } diff --git a/src/definition/metadata/AppInterface.ts b/src/definition/metadata/AppInterface.ts deleted file mode 100644 index 4208311..0000000 --- a/src/definition/metadata/AppInterface.ts +++ /dev/null @@ -1,36 +0,0 @@ -export enum AppInterface { - // Messages - IPreMessageSentPrevent = 'IPreMessageSentPrevent', - IPreMessageSentExtend = 'IPreMessageSentExtend', - IPreMessageSentModify = 'IPreMessageSentModify', - IPostMessageSent = 'IPostMessageSent', - IPreMessageDeletePrevent = 'IPreMessageDeletePrevent', - IPostMessageDeleted = 'IPostMessageDeleted', - IPreMessageUpdatedPrevent = 'IPreMessageUpdatedPrevent', - IPreMessageUpdatedExtend = 'IPreMessageUpdatedExtend', - IPreMessageUpdatedModify = 'IPreMessageUpdatedModify', - IPostMessageUpdated = 'IPostMessageUpdated', - // Rooms - IPreRoomCreatePrevent = 'IPreRoomCreatePrevent', - IPreRoomCreateExtend = 'IPreRoomCreateExtend', - IPreRoomCreateModify = 'IPreRoomCreateModify', - IPostRoomCreate = 'IPostRoomCreate', - IPreRoomDeletePrevent = 'IPreRoomDeletePrevent', - IPostRoomDeleted = 'IPostRoomDeleted', - IPreRoomUserJoined = 'IPreRoomUserJoined', - IPostRoomUserJoined = 'IPostRoomUserJoined', - // External Components - IPostExternalComponentOpened = 'IPostExternalComponentOpened', - IPostExternalComponentClosed = 'IPostExternalComponentClosed', - // Blocks - IUIKitInteractionHandler = 'IUIKitInteractionHandler', - // Livechat - IPostLivechatRoomStarted = 'IPostLivechatRoomStarted', - IPostLivechatRoomClosed = 'IPostLivechatRoomClosed', - /** - * @deprecated please use the AppMethod.EXECUTE_POST_LIVECHAT_ROOM_CLOSED method - */ - ILivechatRoomClosedHandler = 'ILivechatRoomClosedHandler', - IPostLivechatAgentAssigned = 'IPostLivechatAgentAssigned', - IPostLivechatAgentUnassigned = 'IPostLivechatAgentUnassigned', -} diff --git a/src/misc/appPackager.ts b/src/misc/appPackager.ts index 08ea4e6..2b756bd 100644 --- a/src/misc/appPackager.ts +++ b/src/misc/appPackager.ts @@ -3,10 +3,11 @@ import * as path from 'path'; import * as fs from 'fs-extra'; import * as Yazl from 'yazl'; import glob, { IOptions } from 'glob'; +import { AppInterface } from '@rocket.chat/apps-engine/definition/metadata'; import { FolderDetails } from './folderDetails'; -import { IFiles } from '../definition/IFiles'; import packageInfo from '../../package.json'; +import { AppsCompiler } from '../AppsCompiler'; export class AppPackager { public static GlobOptions: IOptions = { @@ -32,16 +33,18 @@ export class AppPackager { private zip: Yazl.ZipFile = new Yazl.ZipFile(); - constructor(private fd: FolderDetails, private compiledFiles: IFiles, private outputFilename: string) {} + constructor(private fd: FolderDetails, private compiledApp: AppsCompiler, private outputFilename: string) {} public async zipItUp(): Promise { const zipName = this.outputFilename; this.zip.addBuffer(Buffer.from(JSON.stringify(AppPackager.PackagerInfo)), '.packagedby', { compress: true }); - this.zipFromCompiledSource(this.compiledFiles); + this.overwriteAppManifest(); - await this.zipSupportFiles(this.fd); + this.zipFromCompiledSource(); + + await this.zipSupportFiles(); this.zip.end(); @@ -50,7 +53,14 @@ export class AppPackager { return zipName; } - private async zipSupportFiles(fd: FolderDetails): Promise { + private overwriteAppManifest(): void { + this.fd.info.implements = this.compiledApp.getImplemented() + .filter((interfaceName) => !!AppInterface[interfaceName as AppInterface]) as Array; + + fs.writeFileSync(this.fd.infoFile, JSON.stringify(this.fd.info, null, 4)); + } + + private async zipSupportFiles(): Promise { let matches; try { @@ -67,7 +77,7 @@ export class AppPackager { await Promise.all( matches.map(async (realPath) => { - const zipPath = path.relative(fd.folder, realPath); + const zipPath = path.relative(this.fd.folder, realPath); const fileStat = await fs.stat(realPath); @@ -81,9 +91,9 @@ export class AppPackager { })); } - private zipFromCompiledSource(compiledFiles: IFiles): void { - Object.keys(compiledFiles) - .map((fileName) => this.zip.addBuffer(Buffer.from(compiledFiles[fileName]), fileName, { compress: true })); + private zipFromCompiledSource(): void { + Object.entries(this.compiledApp.output()) + .map(([filename, contents]) => this.zip.addBuffer(Buffer.from(contents), filename, { compress: true })); } // tslint:disable-next-line:promise-function-async diff --git a/src/misc/folderDetails.ts b/src/misc/folderDetails.ts index 68289e2..16fd5c3 100644 --- a/src/misc/folderDetails.ts +++ b/src/misc/folderDetails.ts @@ -54,13 +54,13 @@ export class FolderDetails { } try { - this.info = await import(this.infoFile); + this.info = JSON.parse(fs.readFileSync(this.infoFile, { encoding: 'utf-8' })); } catch (e) { throw new Error('The "app.json" file is invalid.'); } // This errors out if it fails - this.validateAppDotJson(); + this.validateAppManifest(); if (!this.info.classFile) { throw new Error('Invalid "app.json" file. The "classFile" is required.'); @@ -73,7 +73,7 @@ export class FolderDetails { } } - private validateAppDotJson(): void { + private validateAppManifest(): void { const result = tv4.validateMultiple(this.info, appJsonSchema); // We only care if the result is invalid, as it should pass successfully diff --git a/tsconfig.json b/tsconfig.json index 169f26c..0d2bcfc 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -23,7 +23,7 @@ "outDir": "./dist" }, "exclude": [ - "node_modules", + "node_modules" ], "include": [ "src"