smartclient-eval
Advanced tools
Comparing version 0.4.3 to 0.5.9
48
Const.js
@@ -35,5 +35,10 @@ /* | ||
/////////////////////////////////////////////////////////////////////////////// | ||
// Constants used in Install class. | ||
/////////////////////////////////////////////////////////////////////////////// | ||
/** | ||
* Official name of this NPM module. | ||
* | ||
* @type {string} | ||
*/ | ||
static get MODULE_NAME() { | ||
return "smartclient-eval"; | ||
} | ||
@@ -77,2 +82,11 @@ /** | ||
/** | ||
* File name for typescript configuration. | ||
* | ||
* @type {string} | ||
*/ | ||
static get TYPESCRIPT_CONF() { | ||
return "tsconfig.json"; | ||
} | ||
/** | ||
* Temporary file name for downloaded SmartClient runtime zip. | ||
@@ -267,4 +281,32 @@ * | ||
/** | ||
* List of SmartClient modules to import. Doesn't include optional modules that are | ||
* licensed separately from the SmartClient edition (in the case of Power/Enterprise). | ||
* | ||
* @type {string[]} | ||
*/ | ||
static get SMARTCLIENT_MODULES() { | ||
return ["Core", "Foundation", "Containers", "Grids", "Forms", "RichTextEditor", | ||
"DataBinding", "RealtimeMessaging", "Calendar", "PluginBridges", | ||
"Drawing", "Charts", "Analytics", "Workflow", "Tools"]; | ||
} | ||
/** | ||
* Error message reported when user tries to import this module in an environment without a | ||
* global "window" object. | ||
* <P> | ||
* Such usage isn't supported due to SmartClient's sniffing of window.navigator to identify | ||
* the browser, and load-time manipulation of window.document. Eventually, we may delay | ||
* direct interaction with "window" during loading so that non-widget APIs, such as those | ||
* involving DataSources or AdvancedCriteria, may be accessed by importing this module. | ||
* | ||
* @type {string} | ||
*/ | ||
static get ILLEGAL_USAGE_TEXT() { | ||
return "Module " + this.MODULE_NAME + " can only run in an environment such as " + | ||
"React, where a real window with navigator and document objects are present."; | ||
} | ||
} | ||
module.exports = Const; |
@@ -8,3 +8,3 @@ { | ||
"fs-extra": "^7.0.1", | ||
"prompt-sync": "4.1.6", | ||
"readline-sync": "^1.4.0", | ||
"unzipper": "^0.10.11" | ||
@@ -26,2 +26,5 @@ }, | ||
], | ||
"engines": { | ||
"node" : ">=12.18.0" | ||
}, | ||
"name": "smartclient-eval", | ||
@@ -35,3 +38,3 @@ "optionalDependencies": {}, | ||
}, | ||
"version": "0.4.3" | ||
"version": "0.5.9" | ||
} |
@@ -0,1 +1,8 @@ | ||
Provides access to | ||
[SmartClient Evaluation's client-side UI components](https://www.smartclient.com/product/download.jsp) | ||
documented | ||
[here](https://www.smartclient.com/smartclient-release/isomorphic/system/reference/). | ||
## Installation | ||
Install package and SmartClient runtime(s): | ||
@@ -16,3 +23,4 @@ | ||
--branch=<number> desired branch (e.g. 11.1); default is 12.0 | ||
--branch=<number> desired branch (e.g. 11.1); default is release | ||
branch | ||
@@ -33,6 +41,8 @@ --date=<date|'latest'> desired build date, in format YYYY-MM-DD, | ||
Note that since 'npm update' no longer runs a package's update script, you must use the | ||
syntax above to update the runtime(s) if the package has already been installed. | ||
Note that since 'npm update' no longer runs a package's update script if the | ||
version hasn't changed, you must use the syntax above, run from the package | ||
directory, to update the runtime(s) if the package has already been installed. | ||
(The smartclient-eval package is versioned separately from nighlty SDK builds.) | ||
Examples: | ||
### Command-line Examples | ||
@@ -47,5 +57,41 @@ New install, selecting a specific branch and date: | ||
Update to SmartClient 12.0 branch, installing all skins: | ||
Update to SmartClient 12.1 branch, installing all skins: | ||
npm run update --branch=12.0 --skins | ||
npm run update --branch=12.1 --skins | ||
## Importing | ||
Using smartclient-eval requires an environment, such as | ||
[React](https://en.wikipedia.org/wiki/React_(JavaScript_library)), that defines | ||
"window" as a global with real browser document and navigator objects. In your | ||
React app, you can write: | ||
import 'smartclient-eval/debug'; | ||
or | ||
import 'smartclient-eval/release'; | ||
to import the debug or release framework, respectively. To import a skin, such | ||
as "Tahoe", you can write: | ||
import 'smartclient-eval/skins/Tahoe'; | ||
If you want to refer to SmartClient APIs through your own constant, you can | ||
always issue a declaration such as: | ||
const ISC: typeof isc = window['isc']; | ||
after importing this package. | ||
## TypeScript | ||
To provide typescript support, the installation process should automatically | ||
augment your `tsconfig.json` file to include SmartClient's typescript file. | ||
Alternatively, you can copy the typescript declaration file, `smartclient.d.ts`, | ||
from the installed resources under the `isomorphic` directory to your app's | ||
source directory, and then import it from your app like: | ||
import 'smartclient.d.ts'; | ||
192
update.js
@@ -36,3 +36,3 @@ #!/usr/bin/env node | ||
const npmurl = require("url"); | ||
const ps = require("prompt-sync")(); | ||
const rs = require("readline-sync"); | ||
const unzipper = require("unzipper"); | ||
@@ -76,3 +76,3 @@ | ||
if (!username) { | ||
username = ps("Please provide your SmartClient username: "); | ||
username = rs.question("Please provide your SmartClient username: "); | ||
if (!username) { | ||
@@ -88,3 +88,4 @@ console.log("*** No username provided!"); | ||
if (!password) { | ||
password = ps("Please provide your SmartClient password: ", {echo: "*"}); | ||
password = rs.question("Please provide your SmartClient password: ", | ||
{hideEchoBack: true}); | ||
if (password) { | ||
@@ -104,6 +105,3 @@ console.log( | ||
// installation directory | ||
// we want the default location to be outside the package so it survives uninstall, but | ||
// if we put it in node_modules, the parent, it will be interpreted as an npm package | ||
let location = env.npm_config_location || config.location || | ||
path.resolve(__dirname, "..", ".."); | ||
let location = env.npm_config_location || config.location || path.resolve(__dirname); | ||
@@ -238,3 +236,4 @@ // date | ||
if (response.statusCode !== 200) { | ||
console.error("Failed to download SmartClient runtime from: " + link); | ||
console.error("ERROR! Failed to download SmartClient runtime from: " + | ||
link); | ||
process.exit(-101); | ||
@@ -308,2 +307,6 @@ } | ||
} | ||
// exclude content never wanted for npm | ||
if (dest.match(/skins\/.*\/template/)) { | ||
return false; | ||
} | ||
return true; | ||
@@ -364,2 +367,5 @@ } | ||
} else { | ||
console.log("Setting up import scripts..."); | ||
Update._createImportScripts(isomorphicPath); | ||
Update._injectTypeScript(yes); | ||
console.log("Installation complete."); | ||
@@ -515,3 +521,4 @@ } | ||
if (response.statusCode !== 200) { | ||
console.error("Failed to download " + moduleName + " module from: " + link); | ||
console.error("ERROR! Failed to download " + moduleName + " module from: " + | ||
link); | ||
process.exit(-101); | ||
@@ -598,3 +605,3 @@ } | ||
if (response.statusCode !== 200) { | ||
console.error("Failed to get SmartClient directory listing from: " + | ||
console.error("ERROR! Failed to get SmartClient directory listing from: " + | ||
linkUrl); | ||
@@ -605,3 +612,3 @@ process.exit(-102); | ||
if (data == null) { | ||
console.error("Got empty SmartClient directory listing from: " + | ||
console.error("ERROR! Got empty SmartClient directory listing from: " + | ||
linkUrl); | ||
@@ -612,3 +619,4 @@ process.exit(-103); | ||
if (!matches) { | ||
console.error("No SmartClient runtimes available from: " + linkUrl); | ||
console.error("ERROR! No SmartClient runtimes available from: " + | ||
linkUrl); | ||
process.exit(-104); | ||
@@ -626,2 +634,160 @@ } | ||
/** | ||
* (Internal) generate import scripts for importing framework and skins | ||
* | ||
* @param {string} isomorphicPath - path to isomorphic directory | ||
*/ | ||
static _createImportScripts(isomorphicPath) { | ||
var dirname = path.resolve(__dirname); | ||
// remove or regenerate the import script for SmartClient release | ||
let releaseLoaderPath = path.join(dirname, "release", "index.js"), | ||
releaseModulesPath = path.join(isomorphicPath, "system/modules"); | ||
if (fs.existsSync(releaseModulesPath)) { | ||
Update._createRuntimeLoader(releaseLoaderPath, dirname, releaseModulesPath); | ||
} else fs.removeSync(releaseLoaderPath); | ||
// remove or regenerate the import script for SmartClient debug | ||
let debugLoaderPath = path.join(dirname, "debug", "index.js"), | ||
debugModulesPath = path.join(isomorphicPath, "system/modules-debug"); | ||
if (fs.existsSync(debugModulesPath)) { | ||
Update._createRuntimeLoader(debugLoaderPath, dirname, debugModulesPath); | ||
} else fs.removeSync(debugLoaderPath); | ||
// clear out any existing scripts to import skins | ||
const skinLoaderPath = path.join(dirname, "skins"); | ||
fs.removeSync(skinLoaderPath); | ||
// generate scripts to import all skins present undder isomorphicPath | ||
let skinDirs = fs.readdirSync(path.join(isomorphicPath, "skins")); | ||
for (let i = 0; i < skinDirs.length; i++) { | ||
let skinDir = path.join(isomorphicPath, "skins", skinDirs[i]); | ||
if (fs.existsSync(skinDir) && fs.lstatSync(skinDir).isDirectory()) { | ||
Update._createSkinLoader(path.join(skinLoaderPath, skinDirs[i], "index.js"), | ||
dirname, skinDir, skinDirs[i]); | ||
} | ||
} | ||
} | ||
/** | ||
* (Internal) generate script to load framework runtime (modules), either release or debug | ||
* | ||
* @param {string} loaderPath - path where loader script should be generated | ||
* @param {string} dirname - current directory where this script is running | ||
* @param {string} modulesDir - path where framework modules are located | ||
*/ | ||
static _createRuntimeLoader(loaderPath, dirname, modulesDir) { | ||
const modules = Const.SMARTCLIENT_MODULES; | ||
if (modulesDir.startsWith(dirname)) { | ||
modulesDir = ".." + modulesDir.substring(dirname.length); | ||
} | ||
let contents = | ||
"const Const = require('../Const');\n\n" + | ||
"if (global != global.window) throw new Error(Const.ILLEGAL_USAGE_TEXT);\n\n" + | ||
"window.isc = {};\n" | ||
; | ||
for (let i = 0; i < modules.length; i++) { | ||
const moduleFile = "ISC_" + modules[i] + ".js"; | ||
contents += "require('" + path.join(modulesDir, moduleFile) + "');\n"; | ||
} | ||
fs.outputFileSync(loaderPath, contents); | ||
} | ||
/** | ||
* (Internal) generate script to load one of the installed skins | ||
* | ||
* @param {string} loaderPath - path where loader script should be generated | ||
* @param {string} dirname - current directory where this script is running | ||
* @param {string} skinDir - path to skin folder (inside isomorphic directory) | ||
* @param {string} skinName - name of skin (e.g. "Tahoe") | ||
*/ | ||
static _createSkinLoader(loaderPath, dirname, skinDir, skinName) { | ||
const skinExts = ["css", "svg", "png", "jpg", "gif", | ||
"woff", "woff2", "ttf", "TTF", "otf"] | ||
; | ||
const dependentPath = dirname.match(/.*\/(?=node_modules\/)/)[0]; | ||
if (!skinDir.startsWith(dependentPath)) { | ||
console.error("ERROR! Can't generate a skin loader for path " + skinDir + | ||
" not under the dependent module"); | ||
return; | ||
} | ||
const isomorphicPattern = ".*/(?=" + Const.ISOMORPHIC_DIR + ")"; | ||
const contextPath = skinDir.substring(dependentPath.length). | ||
match(new RegExp(isomorphicPattern))[0]; | ||
if (skinDir.startsWith(dirname)) { | ||
skinDir = "../.." + skinDir.substring(dirname.length); | ||
} | ||
let contents = "require.context(\n" + | ||
" '!!file-loader?context=" + contextPath + | ||
"&name=[path][name].[ext]!" + skinDir + "',\n" + | ||
" true, /\\.(" + skinExts.join("|") + ")$/\n" + | ||
");\n" | ||
; | ||
contents += | ||
"isc.Page.manualStyleSheets = true;\n" + | ||
"window.isc_currentScriptSrc = 'isomorphic/skins/" + skinName + "/';\n" + | ||
"require('" + path.join(skinDir, "skin_styles.css") + "');\n" + | ||
"require('" + path.join(skinDir, "load_skin.js") + "');\n" | ||
; | ||
fs.outputFileSync(loaderPath, contents); | ||
} | ||
/** | ||
* (Internal) inject include dependency for SmartClient's typescript file | ||
* | ||
* @param {string} yes - yes config option (to automatically respond "yes") | ||
*/ | ||
static _injectTypeScript(yes) { | ||
const modulePath = path.resolve(__dirname), | ||
tsConfigName = Const.TYPESCRIPT_CONF, | ||
dependentPath = modulePath.match(/.*\/(?=node_modules\/)/)[0], | ||
tsIncludePath = path.join("node_modules", Const.MODULE_NAME, "**", "*.d.ts") | ||
; | ||
// if we can find the dependent module's tsconfig.json, offer/try to update it | ||
if (dependentPath) { | ||
const tsPath = path.join(dependentPath, tsConfigName); | ||
if (fs.existsSync(tsPath)) { | ||
let tsConfig = fs.readJsonSync(tsPath), | ||
includedDirs = tsConfig.include | ||
; | ||
if (includedDirs && includedDirs.indexOf(tsIncludePath) >= 0) { | ||
console.log("Your app already has the right typescript include path in " + | ||
"its " + tsConfigName + " for SmartClient."); | ||
} else { | ||
const prompt = "Your app lacks an include path in its " + tsConfigName + | ||
" for SmartClient. Add"; | ||
let answer = Update._prompt(prompt + "? [yes]: ", yes); | ||
if (answer != null && (answer.trim() === "" || answer.match(/^y(es)?$/i))) | ||
{ | ||
console.log("Adding SmartClient's typescript include path to the " + | ||
tsConfigName + " of your app..."); | ||
if (!includedDirs) includedDirs = tsConfig.include = []; | ||
includedDirs.push(tsIncludePath); | ||
fs.writeJsonSync(tsPath, tsConfig, {spaces: 4}); | ||
} else { | ||
console.log("To import SmartClient's typescript file, add the path '" + | ||
tIncludePath + " to the include paths in your app's" + | ||
tsConfigName + " file"); | ||
} | ||
} | ||
return; | ||
} | ||
} | ||
console.warn("WARNING! Unable to find " + tsConfigName + " for your app. You can " + | ||
"manually add the path '" + tsIncludePath + "' to the list of include " + | ||
"paths in your typescript config. Or you can copy smartclient.d.ts " + | ||
"from '" + path.join(modulePath, "isomorphic", "system", "development") + | ||
"' to your app's source directory and manually import it from your app."); | ||
} | ||
/** | ||
* (Internal) Get download file name. | ||
@@ -665,3 +831,3 @@ * | ||
} | ||
return ps(prompt); | ||
return rs.question(prompt); | ||
} | ||
@@ -668,0 +834,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53213
1112
95
+ Addedreadline-sync@^1.4.0
+ Addedreadline-sync@1.4.10(transitive)
- Removedprompt-sync@4.1.6
- Removedprompt-sync@4.1.6(transitive)