New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@discoveryjs/cli

Package Overview
Dependencies
Maintainers
0
Versions
71
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@discoveryjs/cli - npm Package Compare versions

Comparing version 2.10.0 to 2.11.0

9

lib/build.js

@@ -0,4 +1,3 @@

const fs = require('fs');
const path = require('path');
const fs = require('fs');
const mime = require('mime');
const { pipeline } = require('stream');

@@ -119,7 +118,3 @@ const bootstrap = require('./shared/bootstrap');

return m.replace(/\s+href="(.+?)"/, (m, faviconpath) =>
` href="data:${
mime.getType(path.extname(faviconpath))
};base64,${
getFileContent(faviconpath).toString('base64')
}"`
` href="${utils.dataUriForPath(faviconpath, getFileContent(faviconpath).toString('base64'))}"`
);

@@ -126,0 +121,0 @@ })

const assert = require('assert');
const bootstrap = require('./shared/bootstrap');
const { pipeline } = require('./shared/data-pipeline');
const { pathToFileURL } = require('url');

@@ -16,3 +17,3 @@ module.exports = bootstrap.model(async function getData(modelConfig, { createPlanEventHandler } = {}) {

case 'string': {
const exports = await import(modelConfig.data);
const exports = await import(pathToFileURL(modelConfig.data));

@@ -19,0 +20,0 @@ getData = exports.default;

const path = require('path');
const cronstrue = require('cronstrue');
const express = require('express');
const cors = require('cors');
const chalk = require('chalk');

@@ -155,3 +156,3 @@ const utils = require('./shared/utils');

: 'No config is used', () => {
utils.println('CORS:', options.cors ? ENABLED + ' (Access-Control-Allow-Origin: *; Access-Control-Expose-Headers: *)' : DISABLED);
utils.println('CORS:', options.cors ? ENABLED : DISABLED);
utils.section(`Data cache: ${cacheDispatcher.cache ? ENABLED : DISABLED}`, () => {

@@ -174,2 +175,7 @@ if (cacheDispatcher.cache) {

// CORS
if (options.cors) {
app.use(cors());
}
// default favicon

@@ -176,0 +182,0 @@ app.get('/favicon.ico', express.static(path.join(__dirname, 'static/favicon.ico')));

@@ -9,3 +9,3 @@ const fs = require('fs');

function alwaysFreshConfig(config, options) {
async function alwaysFreshConfig(config, options) {
if (!refreshConfigMap.has(config)) {

@@ -55,3 +55,5 @@ refreshConfigMap.set(config, {

try {
cfg.config = configUtils.loadConfigWithFallback(options).config;
const { config } = await configUtils.loadConfigWithFallback(options);
cfg.config = config;
cfg.requireCacheDigest = newDigest;

@@ -88,3 +90,3 @@ } catch (e) {

if (!currentBundle || !/\.map$/.test(type)) {
currentBundle = makeBundle(alwaysFreshConfig(config, options), { ...options, serveOnlyAssets: true }, {
currentBundle = makeBundle(await alwaysFreshConfig(config, options), { ...options, serveOnlyAssets: true }, {
outdir: '/',

@@ -91,0 +93,0 @@ // FIXME: Disable incremental build for now, since it's as twice as slower

@@ -16,7 +16,2 @@ const fs = require('fs');

if (options.cors) {
res.set('Access-Control-Allow-Origin', '*');
res.set('Access-Control-Expose-Headers', '*');
}
if (etag) {

@@ -86,13 +81,22 @@ res.set('ETag', etag);

.catch(error => {
res.status(500).json({
const clientErrorData = {
error: utils.serializeErrorForClient(String(error.message)),
data: null
});
utils.logSlugError(slug, 'Response "data.json" error:', error);
};
if (!res.headersSent) {
res.status(500).json(clientErrorData);
} else if (!res.closed) {
res.end(JSON.stringify(clientErrorData));
}
if (!req.aborted) {
utils.logSlugError(slug, 'Response "data.json" error:', error);
}
})
.finally(() => {
generateDataEvents.delete(dataRequestId);
utils.logSlugMsg(slug, 'Responsed "data.json" in', utils.prettyDuration(Date.now() - startTime));
utils.logSlugMsg(slug, `Responsed${req.aborted ? ' (request aborted)' : ''} "data.json" in`, utils.prettyDuration(Date.now() - startTime));
});
};
};

@@ -27,2 +27,6 @@ const utils = require('../shared/utils');

if (!options.dev) {
args.push('--no-dev');
}
args.push('--serve-only-assets');

@@ -29,0 +33,0 @@ args.push('--output', options.prebuild);

@@ -10,4 +10,4 @@ const path = require('path');

module.exports = fn => Object.assign(options => {
const { configFile, config } = configUtils.loadConfigWithFallback(options);
module.exports = fn => Object.assign(async options => {
const { configFile, config } = await configUtils.loadConfigWithFallback(options);

@@ -14,0 +14,0 @@ return fn(options || {}, config, preprocessConfigFile(configFile));

@@ -200,2 +200,3 @@ const fs = require('fs');

const { discoveryDir, discoveryDev } = getDiscoveryDir(process.cwd());
const { version } = require(path.join(discoveryDir, 'package.json'));
const outputDir = options.output;

@@ -269,3 +270,3 @@ const files = new Map();

: entryPoints,
conditions: discoveryDev ? ['discovery-dev'] : [],
conditions: options.dev && discoveryDev ? ['discovery-dev'] : [],
plugins: [

@@ -281,2 +282,3 @@ pluginDiscoveryPaths(discoveryDir),

global: 'window',
DISCOVERY_VERSION: version,
SINGLE_FILE: booleanStr(options.singleFile),

@@ -283,0 +285,0 @@ MODEL_DOWNLOAD: booleanStr(options.modelDownload),

@@ -16,2 +16,12 @@ const fs = require('fs');

function getDefaultIcon(workingDir) {
try {
return require.resolve('@discoveryjs/discovery/src/logo.svg', {
paths: [workingDir, __dirname]
});
} catch {
return '';
}
}
function stripKeys(obj, stripKeys) {

@@ -45,2 +55,4 @@ const result = {};

path.join(cwd, '.discoveryrc.js'),
path.join(cwd, '.discoveryrc.mjs'),
path.join(cwd, '.discoveryrc.cjs'),
path.join(cwd, '.discoveryrc.json'),

@@ -142,2 +154,4 @@ path.join(cwd, '.discoveryrc'),

prepare,
icon,
favicon,
view,

@@ -163,16 +177,24 @@ cache,

// encodings
if (typeof encodings === 'string') {
encodings = resolveFilename(encodings, modelBasedir);
}
encodings = typeof encodings === 'string'
? resolveFilename(encodings, modelBasedir)
: null;
// setup
if (typeof setup === 'string') {
setup = resolveFilename(setup, modelBasedir);
}
setup = typeof setup === 'string'
? resolveFilename(setup, modelBasedir)
: null;
// prepare
if (typeof prepare === 'string') {
prepare = resolveFilename(prepare, modelBasedir);
}
prepare = typeof prepare === 'string'
? resolveFilename(prepare, modelBasedir)
: null;
// icons
icon = typeof icon === 'string'
? resolveFilename(icon, modelBasedir)
: null;
favicon = typeof favicon === 'string'
? resolveFilename(favicon, modelBasedir)
: null;
// view

@@ -217,2 +239,4 @@ view = normalizeViewConfig(view, modelBasedir);

name: 'Untitled model',
version: null,
description: null,
cache: undefined,

@@ -224,2 +248,4 @@ ...stripKeys(modelConfig || {}, ['slug', 'basedir']),

prepare,
icon,
favicon,
view,

@@ -258,2 +284,4 @@ routers,

name: 'Implicit config',
version: null,
description: null,
mode: 'single',

@@ -267,2 +295,4 @@ models: {

name: 'Discovery',
version: null,
description: null,
mode: model ? 'single' : 'multi',

@@ -275,3 +305,6 @@ ...stripKeys(config, ['mode'])

const configBasedir = result.basedir ? path.resolve(basedir || cwd, result.basedir) : basedir || cwd;
let modelBaseConfig = normalizeModelConfig(result.modelBaseConfig || {}, configBasedir);
const modelBaseConfig = normalizeModelConfig(result.modelBaseConfig || {}, configBasedir);
const favicon = result.favicon
? resolveFilename(result.favicon, configBasedir)
: null;

@@ -284,5 +317,6 @@ result.darkmode = result.darkmode !== undefined ? result.darkmode : 'auto';

result.view = normalizeViewConfig(result.view, configBasedir);
result.favicon = result.favicon
? path.resolve(configBasedir, result.favicon)
: getDefaultFavicon(cwd);
result.favicon = favicon || getDefaultFavicon(cwd);
result.icon = result.icon
? resolveFilename(result.icon, configBasedir)
: favicon || getDefaultIcon(cwd);

@@ -307,2 +341,3 @@ if (result.extendRouter) {

};
const favicon = modelConfig.favicon;

@@ -317,2 +352,10 @@ if (modelBaseConfig.prepare) {

if (!favicon) {
modelConfig.favicon = modelBaseConfig.favicon || result.favicon;
}
if (!modelConfig.icon) {
modelConfig.icon = favicon || modelBaseConfig.icon || modelBaseConfig.favicon || result.icon;
}
modelConfig.darkmode = modelConfig.darkmode !== undefined

@@ -360,3 +403,7 @@ ? modelConfig.darkmode

function loadConfig(filename, model) {
function readJsonFromFile(filename) {
return JSON.parse(fs.readFileSync(filename, 'utf8'));
}
async function loadConfig(filename, model) {
let configFilename = resolveConfigFilename(filename);

@@ -375,7 +422,8 @@ let config;

case '.discoveryrc':
config = JSON.parse(fs.readFileSync(configFilename, 'utf8'));
config = readJsonFromFile(configFilename);
break;
case 'package.json':
const packageJson = require(configFilename);
const packageJson = readJsonFromFile(configFilename);
config = packageJson.discovery;

@@ -398,5 +446,15 @@

// .discoveryrc.js
// .discoveryrc.cjs
// .discoveryrc.mjs
// .discoveryrc.json
// or any other
config = require(configFilename);
if (path.extname(configFilename) === '.json') {
config = readJsonFromFile(configFilename);
} else {
// doesn't work for now since we need a hot relead of the config
// const exports = await import(configFilename);
// config = exports.default;
config = require(configFilename);
}
}

@@ -407,6 +465,6 @@

function loadConfigWithFallback({ configFile, model } = {}) {
async function loadConfigWithFallback({ configFile, model } = {}) {
const resolvedConfigFile = resolveConfigFilename(configFile);
const config = resolvedConfigFile
? loadConfig(resolvedConfigFile, model)
? await loadConfig(resolvedConfigFile, model)
: {

@@ -413,0 +471,0 @@ ...normalizeConfig({

const path = require('path');
const fs = require('fs');
const mime = require('mime');
const { runScript, buildEntryNameByPattern, buildAssetNameByPattern } = require('./utils');
const { runScript, buildEntryNameByPattern, buildAssetNameByPattern, dataUriForPath } = require('./utils');
const command = require('./commands');

@@ -79,4 +79,6 @@ const htmlDir = path.join(__dirname, '../static');

const {
slug,
name,
slug,
version,
description,
meta,

@@ -99,4 +101,7 @@ upload,

return {
slug,
name,
slug,
version,
description,
icon: dataUriForPath(modelConfig.icon),
url: entryName,

@@ -122,4 +127,9 @@ data: modelConfig.data

name: config.name,
version: config.version,
description: config.description,
icon: dataUriForPath(config.icon),
mode: config.mode,
embed: embedOption(options, modelConfig || config),
inspector: Boolean(config.view?.inspector),
router: Boolean(config.view?.router),
darkmode: config.darkmode,

@@ -126,0 +136,0 @@ darkmodePersistent: true

@@ -0,4 +1,6 @@

const fs = require('fs');
const path = require('path');
const { fork } = require('child_process');
const { EventEmitter } = require('events');
const mime = require('mime');
const chalk = require('chalk');

@@ -340,3 +342,3 @@ const prettyMs = require('pretty-ms');

function buildEntryNameByPattern(pattern = '[slug]/index', values) {
return path.resolve('/', pattern.replace(
return path.posix.resolve('/', pattern.replace(
/\[([a-z]+)\]/g,

@@ -348,5 +350,5 @@ (m, name) => values[name] || m)

function buildAssetNameByPattern(pattern = '[slug]/[name]', entryName, values) {
return path.relative(
path.dirname(entryName),
path.resolve('/', pattern.replace(
return path.posix.relative(
path.posix.dirname(entryName),
path.posix.resolve('/', pattern.replace(
/\[([a-z]+)\]/g,

@@ -358,2 +360,8 @@ (m, name) => values[name] || m)

function dataUriForPath(filepath, content) {
return `data:${mime.getType(path.extname(filepath))};base64,${
content || fs.readFileSync(filepath, 'base64')
}`;
}
module.exports = {

@@ -381,3 +389,4 @@ print,

buildAssetNameByPattern,
dataUriForPath,
isReadableStream
};
/* eslint-env browser */
import extensions from 'discovery-cli:extensions';
import encodings from 'discovery-cli:encodings';
import { Widget, navButtons, embed } from '@discoveryjs/discovery';
import { Widget as ViewModel, navButtons, router, embed } from '@discoveryjs/discovery';
export default function(setup, progressbar, embedState) {
const model = {
name: setup.name,
version: setup.version,
description: setup.description,
icon: setup.icon
};
const context = {
name: setup.name,
model,
models: setup.models
};
const widget = new Widget({
const viewModel = new ViewModel({
...model,
container: document.body,
styles: setup.styles,
inspector: setup.inspector,
darkmode: setup.darkmode,

@@ -18,8 +26,13 @@ darkmodePersistent: setup.darkmodePersistent,

extensions: [
...extensions,
navButtons.indexPage,
navButtons.discoveryPage,
setup.inspector && navButtons.inspect,
navButtons.darkmodeToggle,
...setup.embed ? [embed.setup(embedState)] : []
setup.router && router,
setup.embed && embed.setup(embedState),
...extensions
],
defaultPage: [
'h1:#.name',
// 'h1:#.model.name',
'app-header:#.model',
{

@@ -40,3 +53,4 @@ view: 'ul',

return widget.setData(setup.data, context, progressbar);
return viewModel.setData(setup.data, context, { progressbar });
}

@@ -12,2 +12,6 @@ /* eslint-env browser */

const app = new App({
name: model.name,
version: model.version,
description: model.description,
icon: model.icon,
mode: setup.mode,

@@ -23,5 +27,5 @@ styles: setup.styles,

extensions: [
...extensions,
model.embed ? embed.setup(embedState) : null,
!modelSetup ? prepare : null
model.embed && embed.setup(embedState),
!modelSetup && prepare,
...extensions
]

@@ -28,0 +32,0 @@ });

{
"name": "@discoveryjs/cli",
"version": "2.10.0",
"version": "2.11.0",
"description": "CLI tools to serve & build projects based on Discovery.js",

@@ -32,11 +32,12 @@ "author": "Roman Dvornov <rdvornov@gmail.com> (https://github.com/lahmatiy)",

"dependencies": {
"@discoveryjs/json-ext": "^0.6.1",
"@discoveryjs/json-ext": "^0.6.3",
"archiver": "^5.3.1",
"chalk": "^4.1.2",
"clap": "^3.1.1",
"cors": "^2.8.5",
"cron-parser": "^4.9.0",
"cron-validator": "^1.3.1",
"cronstrue": "^2.50.0",
"esbuild": "^0.23.0",
"express": "^4.19.2",
"cronstrue": "^2.51.0",
"esbuild": "^0.24.0",
"express": "^4.21.1",
"mime": "^3.0.0",

@@ -48,3 +49,3 @@ "parse-duration": "^1.1.0",

"eslint": "^8.29.0",
"mocha": "^10.6.0"
"mocha": "^10.8.2"
},

@@ -51,0 +52,0 @@ "files": [

@@ -53,6 +53,2 @@ <img align="right" width="128" height="128"

[dir] is not set)
--embed [mode] Specify an embed API: by-config (default), enable (when [mode] omitted)
or disable
--entry-names [pattern] Specify the file names of the output HTML files corresponding to each
model
--no-check-cache-ttl Disable data cache TTL checking before using it

@@ -63,3 +59,6 @@ -c, --config <filename> Path to config (JavaScript or JSON file), if not specified then looking

--cors Enable CORS, i.e. allows data fetching for any origin
--dev Enable developer mode
--no-dev Disable using Discovery.js "src" assets when available (disables
discovery-dev condition)
--embed [mode] Specify an embed API: by-config (default), enable (when [mode] omitted)
or disable
--experimental-jsonxl Enable experimental binary data encoding (codename JSONXL)

@@ -101,4 +100,4 @@ -h, --help Output usage information

--no-cache Disable data caching
--cachedir [dir] Path to store cache files (using .discoveryjs-cache by default when
[dir] is not set)
--cachedir [dir] Path to store cache files (using .discoveryjs-cache by default when [dir]
is not set)
--check-cache-ttl Check data cache TTL before using it, option enforces to use actual

@@ -112,4 +111,8 @@ (according to TTL) data only

--no-data-compression Disable HTML embedded data compression, when --single-file option is used
--no-dev Disable using Discovery.js "src" assets when available (disables
discovery-dev condition)
--embed [mode] Specify an embed API: by-config (default), enable (when [mode] omitted)
or disable
--entry-names [pattern] Specify the file names of the output HTML files corresponding to each
model
--experimental-jsonxl Enable experimental binary data encoding (codename JSONXL)

@@ -124,3 +127,3 @@ -h, --help Output usage information

--pretty-data [indent] Pretty print of model data if any
--serve-only-assets Include server only assets
--serve-only-assets Include server only assets into build
-s, --single-file Output a model build as a single HTML file per model

@@ -170,3 +173,6 @@ --sourcemap [mode] Enable source map generation, optional "mode" can be: linked (default,

* `name` – name of model (used in title)
* `name` – name of the model (used in title)
* `version` – version of the model, can be used in app header when specified
* `description` – description of the model, can be used in app header when specified
* `icon` – path to icon image of the model, can be used in app header when specified
* `meta` – any data (should be serializable to JSON) that will be available in model's `setup.js`

@@ -181,2 +187,3 @@ * `data` – function which returns `any | Promise<any>` or path to a module (CommonJS or ESM) that exports such a function as default. Result of the function is using for a model; must be serializable to JSON (i.e. have no cyclic references for now)

* `upload` – settings for upload data feature; inherits from parent config when not set
* `embed` – explicitly enable or disable embed feature (default `false`)
* `download` – default value for download feature; inherits from parent config when not set

@@ -196,3 +203,3 @@ * `view` – setup model's views (see [Configure view](#configure-view))

name: 'My dashboard',
data: () => ({ hello: 'world' }),
data: './path/to/generate-data-script.js',
encodings: path.join(__dirname, 'path/to/encodings.js'),

@@ -217,5 +224,8 @@ prepare: path.join(__dirname, 'path/to/prepare.js'),

Config should provide JSON or exports an object with following properties:
Multiple models are combine with a single entry point, a config which defines setup for the index page, models and their base configuration. Config should provide JSON or exports an object with following properties (all are optional):
* `name` - name of discovery instance (used in page title)
* `version` – version for the index page, can be used in app header when specified
* `description` – description for the index page, can be used in app header when specified
* `icon` – path to icon image for the index page
* `models` - object with model configurations, where for each entry the key used as a slug and the value as a config

@@ -237,3 +247,3 @@ * `modelBaseConfig` – the same as model's config, using as a base for a model config, i.e. `{ ...modelBaseConfig, ...modelConfig }` will be used

module.exports = {
name: 'My cool dashboards',
name: 'Dashboards hub',
favicon: './path/to/favicon.png',

@@ -240,0 +250,0 @@ models: {

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc