piral-cli 0.15.0-beta.4672 → 0.15.0-beta.4699

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "piral-cli",
3
- "version": "0.15.0-beta.4672",
3
+ "version": "0.15.0-beta.4699",
4
4
  "description": "The standard CLI for creating and building a Piral instance or a Pilet.",
5
5
  "keywords": [
6
6
  "portal",
@@ -42,11 +42,12 @@
42
42
  },
43
43
  "scripts": {
44
44
  "cleanup": "rimraf lib",
45
- "build": "tsc --declaration && rimraf lib/external && ncc build src/external/index.ts -o lib/external",
45
+ "build": "yarn build:source && rimraf lib/external && yarn build:external",
46
+ "build:source": "tsc --declaration",
47
+ "build:external": "esbuild src/external/index.ts --bundle --outfile=lib/external/index.js --format=cjs --platform=node --external:pnpapi",
46
48
  "test": "echo \"Error: run tests from root\" && exit 1"
47
49
  },
48
50
  "devDependencies": {
49
- "@parcel/logger": "^1.11.1",
50
51
  "@types/express": "^4.16.1",
51
52
  "@types/glob": "^7.1.1",
52
53
  "@types/inquirer": "^6.0.0",
@@ -57,26 +58,27 @@
57
58
  "@types/rimraf": "^2.0.2",
58
59
  "@types/tar": "^4.0.0",
59
60
  "@types/yargs": "^15.0.4",
60
- "@zeit/ncc": "^0.22.3",
61
61
  "axios": "^0.21.1",
62
+ "chalk": "^4.0.0",
63
+ "enhanced-resolve": "^5.10.0",
62
64
  "form-data": "^3.0.0",
63
65
  "get-port": "^5.0.0",
64
66
  "glob": "^7.1.3",
65
67
  "inquirer": "^6.2.2",
68
+ "is-interactive": "^2.0.0",
66
69
  "jju": "^1.4.0",
67
70
  "mime": "^2.5.2",
68
71
  "open": "^7.1.0",
72
+ "ora": "^6.1.2",
69
73
  "rc": "^1.2.8",
70
- "strip-ansi": "^5.2.0",
71
74
  "tar": "^4.4.8"
72
75
  },
73
76
  "dependencies": {
74
- "chalk": "^2.4.2",
75
77
  "dets": "^0.12.0",
76
78
  "kras": "^0.15.1",
77
79
  "rimraf": "^3.0.0",
78
80
  "typescript": "^4.7.3",
79
81
  "yargs": "^15.4.1"
80
82
  },
81
- "gitHead": "cd1026b70c90290fa5ba3f9b86c038eb852595be"
83
+ "gitHead": "1d7d09c7a953009ade1470abf74b5e7e627f2bc2"
82
84
  }
@@ -305,7 +305,7 @@ export async function debugPilet(baseDir = process.cwd(), options: DebugPiletOpt
305
305
  checkSanity(pilets);
306
306
 
307
307
  await hooks.beforeApp?.({ appInstanceDir, pilets });
308
- const appDirs = [appInstanceDir] || (await getOrMakeApps(pilets[0], logLevel));
308
+ const appDirs = appInstanceDir ? [appInstanceDir] : (await getOrMakeApps(pilets[0], logLevel));
309
309
 
310
310
  await Promise.all(
311
311
  appDirs.map(async (appDir) => {
@@ -45,52 +45,58 @@ jest.mock('path', () =>
45
45
  );
46
46
 
47
47
  const fileNotFoundError = 'File not found!';
48
- jest.mock('tar', () => ({
49
- create: (options: CreateOptions & FileOptions, fileList: ReadonlyArray<string>) => {
50
- return new Promise((resolve, reject) => {
51
- if (options.file && options.file == 'foo.txt') {
52
- resolve(true);
53
- } else {
54
- reject(fileNotFoundError);
55
- }
56
- });
57
- },
58
- extract: (options: ExtractOptions & FileOptions, fileList?: ReadonlyArray<string>) => {
59
- return new Promise((resolve, reject) => {
60
- if (options.file && options.file.includes('foo.tgz')) {
61
- resolve(true);
62
- } else {
63
- reject(fileNotFoundError);
64
- }
65
- });
66
- },
67
- Parse: () => {
68
- return {
69
- position: 0,
70
- _stream: new Stream(),
71
- _ended: false,
72
- _streamEnd: () => {
73
- this._ended = true;
74
- console.log('_streamEnd');
75
- },
76
- process: (c: Buffer) => {
77
- console.log('process');
78
- },
79
- _startEntry: (c: Buffer) => {
80
- console.log('_startEntry');
81
- },
82
- on: (event: string, listener: (...args: any[]) => {}) => {
83
- console.log(`on event: ${event}`);
84
- },
85
- once: (event: string, listener: (...args: any[]) => {}) => {
86
- console.log(`once event: ${event}`);
87
- },
88
- emit: (event: string | symbol, ...args: any[]) => {
89
- console.log(`emit event: ${event.toString()}`);
90
- return true;
91
- },
92
- } as any;
48
+
49
+ jest.mock('../external', () => ({
50
+ ora() {
51
+ return {};
93
52
  },
53
+ tar: {
54
+ create: (options: CreateOptions & FileOptions, fileList: ReadonlyArray<string>) => {
55
+ return new Promise((resolve, reject) => {
56
+ if (options.file && options.file == 'foo.txt') {
57
+ resolve(true);
58
+ } else {
59
+ reject(fileNotFoundError);
60
+ }
61
+ });
62
+ },
63
+ extract: (options: ExtractOptions & FileOptions, fileList?: ReadonlyArray<string>) => {
64
+ return new Promise((resolve, reject) => {
65
+ if (options.file && options.file.includes('foo.tgz')) {
66
+ resolve(true);
67
+ } else {
68
+ reject(fileNotFoundError);
69
+ }
70
+ });
71
+ },
72
+ Parse: () => {
73
+ return {
74
+ position: 0,
75
+ _stream: new Stream(),
76
+ _ended: false,
77
+ _streamEnd: () => {
78
+ this._ended = true;
79
+ console.log('_streamEnd');
80
+ },
81
+ process: (c: Buffer) => {
82
+ console.log('process');
83
+ },
84
+ _startEntry: (c: Buffer) => {
85
+ console.log('_startEntry');
86
+ },
87
+ on: (event: string, listener: (...args: any[]) => {}) => {
88
+ console.log(`on event: ${event}`);
89
+ },
90
+ once: (event: string, listener: (...args: any[]) => {}) => {
91
+ console.log(`once event: ${event}`);
92
+ },
93
+ emit: (event: string | symbol, ...args: any[]) => {
94
+ console.log(`emit event: ${event.toString()}`);
95
+ return true;
96
+ },
97
+ } as any;
98
+ },
99
+ }
94
100
  }));
95
101
 
96
102
  describe('Archive Module', () => {
@@ -2,13 +2,23 @@ import { openBrowser } from './browser';
2
2
 
3
3
  let error = false;
4
4
 
5
- jest.mock('open', () => (...args) => {
6
- if (error) {
7
- throw new Error('Error occured');
8
- } else {
9
- return null;
10
- }
11
- });
5
+ jest.mock('../external', () => ({
6
+ rc(_, cfg) {
7
+ return cfg;
8
+ },
9
+ ora() {
10
+ return {
11
+ fail() {},
12
+ };
13
+ },
14
+ open() {
15
+ if (error) {
16
+ throw new Error('Error occured');
17
+ } else {
18
+ return null;
19
+ }
20
+ },
21
+ }));
12
22
 
13
23
  describe('Browser Module', () => {
14
24
  it('opens browser successfully', async () => {
@@ -3,6 +3,8 @@ export const filesTar = 'files';
3
3
  export const filesOnceTar = 'files_once';
4
4
  export const piralBaseRoot = 'piral-base/package.json';
5
5
  export const frameworkLibs = ['piral-native' as const, 'piral' as const, 'piral-core' as const, 'piral-base' as const];
6
+ export const piletJsonSchemaUrl = 'https://schema.piral.io/v0/pilet.json';
7
+ export const piralJsonSchemaUrl = 'https://schema.piral.io/v0/piral.json';
6
8
  export const entryModuleExtensions = ['.ts', '.tsx', '.js', '.jsx'];
7
9
  export const bundlerNames = [
8
10
  'esbuild' as const,
@@ -7,66 +7,78 @@ let errorOther = false;
7
7
  let errorResponse = false;
8
8
  let errorResponse2 = false;
9
9
 
10
- jest.mock('axios', () => ({
11
- default: {
12
- post(url, _, options) {
13
- const found = url === apiUrl;
14
- const auth = options.headers.authorization === 'Basic 123';
10
+ jest.mock('../external', () => ({
11
+ rc(_, cfg) {
12
+ return cfg;
13
+ },
14
+ ora() {
15
+ return {
16
+ warn() {},
17
+ fail() {},
18
+ };
19
+ },
20
+ axios: {
21
+ default: {
22
+ post(url, _, options) {
23
+ const found = url === apiUrl;
24
+ const auth = options.headers.authorization === 'Basic 123';
15
25
 
16
- if (errorRequest) {
17
- return Promise.reject({
18
- request: {},
19
- });
20
- } else if (errorOther) {
21
- return Promise.reject({
22
- message: 'error',
23
- });
24
- } else if (errorResponse) {
25
- return Promise.reject({
26
- response: {
27
- status: 410,
28
- statusText: 'Not Gone',
29
- data: '{ "message": "This component is not available anymore." }',
30
- },
31
- });
32
- } else if (errorResponse2) {
33
- return Promise.reject({
34
- response: {
35
- status: 410,
36
- statusText: 'Not Gone',
37
- data: { message: 'This component is not available anymore.' },
38
- },
39
- });
40
- } else if (!found) {
41
- return Promise.reject({
42
- response: {
43
- status: 404,
44
- statusText: 'Not found',
45
- },
46
- });
47
- } else if (!auth) {
48
- return Promise.reject({
49
- response: {
50
- status: 401,
51
- statusText: 'Not authorized',
52
- },
53
- });
54
- } else {
55
- return Promise.resolve({
56
- status: 200,
57
- statusText: 'OK',
58
- });
59
- }
60
- },
61
- get(url, options) {
62
- if (errorOther) {
63
- return Promise.reject({
64
- message: 'error',
65
- });
66
- }
67
- return Promise.resolve({ data: 'test' });
26
+ if (errorRequest) {
27
+ return Promise.reject({
28
+ request: {},
29
+ });
30
+ } else if (errorOther) {
31
+ return Promise.reject({
32
+ message: 'error',
33
+ });
34
+ } else if (errorResponse) {
35
+ return Promise.reject({
36
+ response: {
37
+ status: 410,
38
+ statusText: 'Not Gone',
39
+ data: '{ "message": "This component is not available anymore." }',
40
+ },
41
+ });
42
+ } else if (errorResponse2) {
43
+ return Promise.reject({
44
+ response: {
45
+ status: 410,
46
+ statusText: 'Not Gone',
47
+ data: { message: 'This component is not available anymore.' },
48
+ },
49
+ });
50
+ } else if (!found) {
51
+ return Promise.reject({
52
+ response: {
53
+ status: 404,
54
+ statusText: 'Not found',
55
+ },
56
+ });
57
+ } else if (!auth) {
58
+ return Promise.reject({
59
+ response: {
60
+ status: 401,
61
+ statusText: 'Not authorized',
62
+ },
63
+ });
64
+ } else {
65
+ return Promise.resolve({
66
+ status: 200,
67
+ statusText: 'OK',
68
+ });
69
+ }
70
+ },
71
+ get(url, options) {
72
+ if (errorOther) {
73
+ return Promise.reject({
74
+ message: 'error',
75
+ });
76
+ }
77
+ return Promise.resolve({ data: 'test' });
78
+ },
68
79
  },
69
80
  },
81
+ FormData: jest.requireActual('form-data'),
70
82
  }));
71
83
 
72
84
  describe('HTTP Module', () => {
@@ -1,7 +1,7 @@
1
- import chalk from 'chalk';
2
1
  import { resolve } from 'path';
3
2
  import { liveIcon, settingsIcon } from './emoji';
4
3
  import { logInfo, log, logReset } from './log';
4
+ import { chalk } from '../external';
5
5
  import { Bundler } from '../types';
6
6
 
7
7
  export function notifyServerOnline(bundlers: Array<Bundler>, path: string, api: string | false) {
@@ -6,6 +6,9 @@ jest.mock('../external', () => ({
6
6
  rc(_, cfg) {
7
7
  return cfg;
8
8
  },
9
+ ora() {
10
+ return {};
11
+ },
9
12
  inquirer: {
10
13
  prompt: (...any) => {
11
14
  return Promise.resolve({ q: answer });
package/src/common/log.ts CHANGED
@@ -1,111 +1,79 @@
1
1
  import * as messages from '../messages';
2
- import { join } from 'path';
3
2
  import { format } from 'util';
4
- import { createWriteStream } from 'fs';
5
- import { isWindows } from './info';
6
- import { stripAnsi } from '../external';
3
+ import { ora } from '../external';
7
4
  import { LogLevels, QuickMessage } from '../types';
8
5
 
9
6
  type Messages = typeof messages;
10
7
  type MessageTypes = keyof Messages;
11
8
  let currentProgress: string = undefined;
12
-
13
- const logger = (() => {
14
- try {
15
- const logger = require('@parcel/logger');
16
-
17
- // check to see if this is really right
18
- if (typeof logger.verbose === 'function') {
19
- return logger;
20
- }
21
- } catch {}
22
-
23
- return require('../external').logger;
24
- })();
25
-
26
- // unfortunately, Parcel's support for verbose logging on Windows is broken
27
- if (isWindows) {
28
- logger.verbose = function (message: string) {
29
- if (this.logLevel < 4) {
30
- return;
31
- }
32
-
33
- const currDate = new Date();
34
- message = `[${currDate.toLocaleTimeString()}]: ${message}`;
35
-
36
- if (this.logLevel > 4) {
37
- if (!this.logFile) {
38
- // the critical line is the filename; it must not contain colons!
39
- const timestamp = currDate.toISOString().replace(/:/g, '');
40
- const fileName = `parcel-debug-${timestamp}.log`;
41
- this.logFile = createWriteStream(join(process.cwd(), fileName));
42
- }
43
-
44
- this.logFile.write(stripAnsi.default(message) + '\n');
45
- }
46
-
47
- this._log(message);
48
- };
49
- }
9
+ let logLevel = LogLevels.info;
10
+ let instance = ora();
50
11
 
51
12
  export function getLogLevel(): LogLevels {
52
- return logger.logLevel;
13
+ return logLevel;
53
14
  }
54
15
 
55
- export function setLogLevel(logLevel: LogLevels) {
56
- logger.setOptions({ logLevel });
16
+ export function setLogLevel(value: LogLevels) {
17
+ logLevel = value;
57
18
  }
58
19
 
59
20
  export function logInfo(message: string, ...args: Array<string | number | boolean>) {
60
21
  const msg = format(message, ...args);
61
- logger.log(msg);
22
+ instance.info(msg);
62
23
  return msg;
63
24
  }
64
25
 
65
26
  export function logDebug(message: string, ...args: Array<string | number | boolean>) {
66
27
  const msg = format(message, ...args);
67
- logger.verbose(msg);
28
+
29
+ if (logLevel >= LogLevels.debug) {
30
+ instance.info(msg);
31
+ }
32
+
68
33
  return msg;
69
34
  }
70
35
 
71
36
  export function logVerbose(message: string, ...args: Array<string | number | boolean>) {
72
37
  const msg = format(message, ...args);
73
- logger.logLevel > 3 && logger.log(msg);
38
+
39
+ if (logLevel >= LogLevels.verbose) {
40
+ instance.info(msg);
41
+ }
42
+
74
43
  return msg;
75
44
  }
76
45
 
77
46
  export function logDone(message: string, ...args: Array<string | number | boolean>) {
78
47
  const msg = format(message, ...args);
79
- logger.success(msg);
48
+ instance.succeed(msg);
80
49
  return msg;
81
50
  }
82
51
 
83
52
  export function logWarn(message: string, ...args: Array<string | number | boolean>) {
84
53
  const msg = format(message, ...args);
85
- logger.warn(msg);
54
+ instance.warn(msg);
86
55
  return msg;
87
56
  }
88
57
 
89
58
  export function logFail(message: string, ...args: Array<string | number | boolean>) {
90
59
  const msg = format(message, ...args);
91
- logger.error(msg);
60
+ instance.fail(msg);
92
61
  return msg;
93
62
  }
94
63
 
95
64
  export function progress(message: string, ...args: Array<string | number | boolean>) {
96
65
  currentProgress = format(message, ...args)
97
- logger.progress(currentProgress);
66
+ instance.start(message);
98
67
  }
99
68
 
100
69
  export function logReset() {
101
- logger.lines = 0;
102
- logger.stopSpinner();
70
+ instance.stop();
103
71
  }
104
72
 
105
73
  export function logSuspend() {
106
74
  logReset();
107
75
 
108
- return () => logger.progress(currentProgress);
76
+ return () => instance.start(currentProgress);
109
77
  }
110
78
 
111
79
  export function fail<T extends MessageTypes>(type: T, ...args: Parameters<Messages[T]>): never {
@@ -28,13 +28,8 @@ jest.mock('child_process');
28
28
 
29
29
  jest.mock('../external', () => ({
30
30
  rc() {},
31
- logger: {
32
- stopSpinner() {},
33
- verbose() {},
34
- info() {},
35
- error() {},
36
- log() {},
37
- setOptions() {},
31
+ ora() {
32
+ return {};
38
33
  },
39
34
  }));
40
35
 
@@ -7,11 +7,18 @@ import { ForceOverwrite } from './enums';
7
7
  import { checkAppShellCompatibility } from './compatibility';
8
8
  import { deepMerge } from './merge';
9
9
  import { readImportmap } from './importmap';
10
- import { filesTar, filesOnceTar, declarationEntryExtensions, bundlerNames } from './constants';
11
10
  import { getHash, checkIsDirectory, matchFiles } from './io';
12
11
  import { readJson, copy, updateExistingJson, findFile, checkExists } from './io';
13
12
  import { isGitPackage, isLocalPackage, makeGitUrl, makeFilePath } from './npm';
14
13
  import { makePiletExternals, makeExternals, findPackageRoot, findSpecificVersion } from './npm';
14
+ import {
15
+ filesTar,
16
+ filesOnceTar,
17
+ declarationEntryExtensions,
18
+ bundlerNames,
19
+ piralJsonSchemaUrl,
20
+ piletJsonSchemaUrl,
21
+ } from './constants';
15
22
  import {
16
23
  SourceLanguage,
17
24
  Framework,
@@ -210,7 +217,10 @@ export async function patchPiralPackage(
210
217
  await updateExistingJson(root, 'package.json', pkg);
211
218
  log('generalDebug_0003', `Succesfully patched the package.json.`);
212
219
 
213
- await updateExistingJson(root, 'piral.json', { pilets: getPiletsInfo({}) });
220
+ await updateExistingJson(root, 'piral.json', {
221
+ $schema: piralJsonSchemaUrl,
222
+ pilets: getPiletsInfo({}),
223
+ });
214
224
  log('generalDebug_0003', `Succesfully patched the pilet.json.`);
215
225
  }
216
226
 
@@ -567,6 +577,7 @@ export async function patchPiletPackage(
567
577
  log('generalDebug_0003', `Succesfully patched the package.json.`);
568
578
 
569
579
  await updateExistingJson(root, 'pilet.json', {
580
+ $schema: piletJsonSchemaUrl,
570
581
  piralInstances: {
571
582
  [name]: {},
572
583
  },
@@ -4,7 +4,10 @@ const defaultPort = 12345;
4
4
  const error = Error('RangeError: Port should be >= 0 and < 65536.');
5
5
 
6
6
  jest.mock('../external', () => ({
7
- getPort: (options: any) => {
7
+ ora() {
8
+ return {};
9
+ },
10
+ getPort(options: any) {
8
11
  if (options == undefined) {
9
12
  return Promise.resolve(defaultPort);
10
13
  } else if (options && options.port && options.port > 65536) {
@@ -1,5 +1,5 @@
1
1
  import { ruleSummary, runRules } from './rules';
2
- import chalk from 'chalk';
2
+ import { chalk } from '../external';
3
3
 
4
4
  const rule = {
5
5
  run: jest.fn(),
@@ -13,9 +13,9 @@ describe('Rules Module', () => {
13
13
  };
14
14
  expect(runException).toThrow(Error('[0080] Validation failed. Found 1 error(s).'));
15
15
 
16
- let consoleSpy = jest.spyOn(console, 'log');
16
+ let consoleSpy = jest.spyOn(process.stderr, 'write');
17
17
  ruleSummary([], []);
18
- expect(consoleSpy).toHaveBeenCalledWith(`✨ ${chalk.green.bold('Validation successful. No errors or warnings.')}`);
18
+ expect(consoleSpy).toHaveBeenLastCalledWith(`${chalk.green('✔')} Validation successful. No errors or warnings.\n`);
19
19
 
20
20
  jest.clearAllMocks();
21
21
  ruleSummary([], ['Warning!']);
@@ -1,4 +1,4 @@
1
- import * as externals from './index';
1
+ import * as externals from '../external';
2
2
 
3
3
  describe('Externals module', () => {
4
4
  it('exports the FormData class', () => {
@@ -27,7 +27,7 @@ describe('Externals module', () => {
27
27
  });
28
28
 
29
29
  it('exports the logger module', () => {
30
- const logger = externals.logger;
30
+ const logger = externals.ora;
31
31
  expect(logger).not.toBeUndefined();
32
32
  });
33
33
 
@@ -1,5 +1,3 @@
1
- import logger = require('@parcel/logger');
2
- import stripAnsi = require('strip-ansi');
3
1
  import inquirer = require('inquirer');
4
2
  import jju = require('jju');
5
3
  import glob = require('glob');
@@ -10,5 +8,10 @@ import axios = require('axios');
10
8
  import mime = require('mime');
11
9
  import getPort = require('get-port');
12
10
  import open = require('open');
11
+ import chalk = require('chalk');
13
12
 
14
- export { logger, inquirer, glob, tar, FormData, rc, axios, mime, stripAnsi, getPort, open, jju };
13
+ import isInteractive from 'is-interactive';
14
+ import ora from 'ora';
15
+ import { getModulePath } from './resolve';
16
+
17
+ export { chalk, inquirer, isInteractive, ora, glob, tar, FormData, rc, axios, mime, getPort, open, jju, getModulePath };
@@ -0,0 +1,28 @@
1
+ import * as fs from 'graceful-fs';
2
+ import { ResolverFactory, CachedInputFileSystem } from 'enhanced-resolve';
3
+
4
+ const nodeFileSystem = new CachedInputFileSystem(fs, 4000);
5
+
6
+ const nodeContext = {
7
+ environments: ['node+es3+es5+process+native'],
8
+ };
9
+
10
+ const enhancedResolve = ResolverFactory.createResolver({
11
+ aliasFields: ['browser'],
12
+ conditionNames: ['import', 'module', 'webpack', 'development', 'browser'],
13
+ extensions: ['.js', '.jsx', '.mjs', '.ts', '.tsx', '.json'],
14
+ exportsFields: ['exports'],
15
+ importsFields: ['imports'],
16
+ mainFields: ['browser', 'module', 'main'],
17
+ fileSystem: nodeFileSystem,
18
+ });
19
+
20
+ export function getModulePath(root: string, moduleName: string) {
21
+ const res = enhancedResolve.resolveSync(nodeContext, root, moduleName);
22
+
23
+ if (!res) {
24
+ throw new Error(`Could not find module "${moduleName}".`);
25
+ }
26
+
27
+ return res;
28
+ }