diff --git a/src/amd/js/Uri.js b/src/amd/js/Uri.js --- a/src/amd/js/Uri.js +++ b/src/amd/js/Uri.js @@ -1,4 +1,4 @@ -define(["./declare", "./log/trace!"], function (declare, trace) { +define(["dojo/_base/declare", "./log/trace!"], function (declare, trace) { trace.warn("THIS MODULE IS DEPRECATED! use uri-js or similar alternatives."); function parseURI(uri) { diff --git a/src/amd/ts/di/ResolverHelper.ts b/src/amd/ts/di/ResolverHelper.ts --- a/src/amd/ts/di/ResolverHelper.ts +++ b/src/amd/ts/di/ResolverHelper.ts @@ -1,5 +1,5 @@ import { Uuid } from "../Uuid"; -import { argumentNotEmptyString, getGlobal } from "../safe"; +import { argumentNotEmptyString, getGlobal, isNullOrEmptyString } from "../safe"; import { TraceSource, DebugLevel } from "../log/TraceSource"; import m = require("module"); @@ -7,7 +7,7 @@ const sandboxId = Uuid(); define(sandboxId, ["require"], r => r); // tslint:disable-next-line:no-var-requires -const globalRequire = require(sandboxId); +const globalRequire = getGlobal().require as Require; const trace = TraceSource.get(m.id); @@ -58,15 +58,17 @@ class ModuleResolver { } } -export function makeResolver(moduleName: string, contextRequire: Require) { +export async function makeResolver(moduleName: string, contextRequire: Require) { trace.debug( "makeResolver moduleName={0}, contextRequire={1}", moduleName || "", contextRequire ? typeof (contextRequire) : "" ); - const base = moduleName && moduleName.split("/").slice(0, -1).join("/"); + const nestedRequire = isNullOrEmptyString(moduleName) ? null : await createContextRequire(moduleName); - const resolver = new ModuleResolver(contextRequire, base); + // const base = moduleName && moduleName.split("/").slice(0, -1).join("/"); + + const resolver = new ModuleResolver(nestedRequire, null); return (id: string) => resolver.resolve(id); } diff --git a/src/amd/ts/log/trace.ts b/src/amd/ts/log/trace.ts --- a/src/amd/ts/log/trace.ts +++ b/src/amd/ts/log/trace.ts @@ -2,7 +2,9 @@ import { TraceSource } from "./TraceSour import { Predicate } from "../interfaces"; export = { - on(filter: any , cb: any) { + level: 0, + + on(filter: any, cb: any) { if (arguments.length === 1) { cb = filter; filter = undefined; @@ -18,11 +20,13 @@ export = { if (test) { TraceSource.on(source => { + source.level = this.level; if (test(source.id)) source.events.on(cb); }); } else { TraceSource.on(source => { + source.level = this.level; source.events.on(cb); }); } diff --git a/src/amd/ts/text/TemplateCompiler.ts b/src/amd/ts/text/TemplateCompiler.ts --- a/src/amd/ts/text/TemplateCompiler.ts +++ b/src/amd/ts/text/TemplateCompiler.ts @@ -1,4 +1,4 @@ -import { format } from "./StringFormat"; +import * as format from "./format"; import { TraceSource, DebugLevel } from "../log/TraceSource"; import { ITemplateParser, TokenType } from "./TemplateParser"; import m = require("module"); @@ -98,7 +98,7 @@ export class TemplateCompiler { } visitTextFragment(parser: ITemplateParser) { - const i = this._data.push(parser.value()); + const i = this._data.push(parser.value()) - 1; this._code.push("$p.push($data[" + i + "]);"); } } diff --git a/src/amd/ts/text/TemplateParser.ts b/src/amd/ts/text/TemplateParser.ts --- a/src/amd/ts/text/TemplateParser.ts +++ b/src/amd/ts/text/TemplateParser.ts @@ -1,5 +1,9 @@ import { argumentNotEmptyString } from "../safe"; import { MapOf } from "../interfaces"; +import { TraceSource, DebugLevel } from "../log/TraceSource"; +import m = require("module"); + +const trace = TraceSource.get(m.id); const splitRx = /(<%=|\[%=|<%|\[%|%\]|%>)/; @@ -45,6 +49,7 @@ export class TemplateParser implements I if (this._pos < this._tokens.length) { this._value = this._tokens[this._pos]; this._type = tokenMap[this._value] || TokenType.Text; + return true; } else { this._type = TokenType.None; diff --git a/src/amd/ts/text/format-compile.ts b/src/amd/ts/text/format-compile.ts --- a/src/amd/ts/text/format-compile.ts +++ b/src/amd/ts/text/format-compile.ts @@ -1,8 +1,9 @@ import * as module from "module"; import { TraceSource } from "../log/TraceSource"; +import { compile } from "./StringFormat"; const logger = TraceSource.get(module.id); logger.warn("The module is deprecated, use StringFormat.compile() method directly"); -export { compile } from "./StringFormat"; +export = compile; diff --git a/src/amd/ts/text/format.ts b/src/amd/ts/text/format.ts --- a/src/amd/ts/text/format.ts +++ b/src/amd/ts/text/format.ts @@ -1,8 +1,8 @@ import { format as dojoFormatNumber } from "dojo/number"; import { format as dojoFormatDate } from "dojo/date/locale"; -import { Formatter } from "./StringFormat"; +import { Formatter, compile as _compile } from "./StringFormat"; -import { isNumber } from "../safe"; +import { isNumber, isNull } from "../safe"; interface NumberFormatOptions { round?: number; @@ -42,6 +42,26 @@ function convertDate(value: any, pattern const _formatter = new Formatter([convertNumber, convertDate]); -export = function format(msg: string, ...args: any[]) { - return _formatter.format.apply(msg, ...args); -}; +function format(msg: string, ...args: any[]) { + return _formatter.format(msg, ...args); +} + +function _convert(value: any, pattern: string) { + return _formatter.convert(value, pattern); +} + +namespace format { + export const convert = _convert; + export function compile(text: string) { + const template = _compile(text); + + return (...data) => { + return template((name, pattern) => { + const value = data[name]; + return !isNull(value) ? convert(value, pattern) : ""; + }); + }; + } +} + +export = format; diff --git a/src/main/ts/Uuid.ts b/src/main/ts/Uuid.ts --- a/src/main/ts/Uuid.ts +++ b/src/main/ts/Uuid.ts @@ -54,9 +54,9 @@ function setupBrowser() { return _rnds; }; - if ("undefined" !== typeof console && console.warn) { - console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); - } + // if ("undefined" !== typeof console && console.warn) { + // console.warn("[SECURITY] node-uuid: crypto not usable, falling back to insecure Math.random()"); + // } } } @@ -92,7 +92,7 @@ for (let i = 0; i < 256; i++) { } // **`parse()` - Parse a UUID into it's component bytes** -export function _parse(s, buf?, offset?): Array { +function _parse(s, buf?, offset?): Array { const i = (buf && offset) || 0; let ii = 0; buf = buf || []; @@ -146,7 +146,7 @@ let _clockseq = (_seedBytes[6] << 8 | _s let _lastMSecs = 0; let _lastNSecs = 0; // See https://github.com/broofa/node-uuid for API details -export function _v1(options?, buf?, offset?): string { +function _v1(options?, buf?, offset?): string { let i = buf && offset || 0; const b = buf || []; @@ -231,7 +231,7 @@ export function _v1(options?, buf?, offs // **`v4()` - Generate random UUID** // See https://github.com/broofa/node-uuid for API details -export function _v4(options?, buf?, offset?): string { +function _v4(options?, buf?, offset?): string { // Deprecated - 'format' argument, as supported in v1.2 const i = buf && offset || 0; @@ -257,13 +257,16 @@ export function _v4(options?, buf?, offs return buf || _unparse(rnds); } -export function Uuid() { +function _Uuid() { return _v4(); } -export namespace Uuid { +namespace _Uuid { export const v4 = _v4; export const v1 = _v1; export const empty = "00000000-0000-0000-0000-000000000000"; export const parse = _parse; + export const Uuid = _v4; } + +export = _Uuid; diff --git a/src/main/ts/di/Configuration.ts b/src/main/ts/di/Configuration.ts --- a/src/main/ts/di/Configuration.ts +++ b/src/main/ts/di/Configuration.ts @@ -28,27 +28,6 @@ import { ICancellation } from "../interf const trace = TraceSource.get("@implab/core/di/Configuration"); -declare const define; -declare const require; -declare const module; - -function hasAmdLoader() { - try { - // es6 may throw the exception - return (typeof define === "function" && define.amd); - } catch { - return false; - } -} - -function hasNodeJs() { - try { - return (typeof module !== "undefined" && module.exports); - } catch { - return false; - } -} - async function mapAll(data: object | any[], map?: (v, k) => any): Promise { if (data instanceof Array) { return Promise.all(map ? data.map(map) : data); @@ -99,21 +78,21 @@ export class Configuration { this._configName = moduleName; - const r = makeResolver(null, contextRequire); + const r = await makeResolver(null, contextRequire); const config = await r(moduleName, ct); await this._applyConfiguration( config, - makeResolver(moduleName, contextRequire), + await makeResolver(moduleName, contextRequire), ct ); } - applyConfiguration(data: object, contextRequire?: any, ct = Cancellation.none) { + async applyConfiguration(data: object, contextRequire?: any, ct = Cancellation.none) { argumentNotNull(data, "data"); - return this._applyConfiguration(data, makeResolver(void (0), contextRequire), ct); + await this._applyConfiguration(data, await makeResolver(void (0), contextRequire), ct); } async _applyConfiguration(data: object, resolver?: ModuleResolver, ct = Cancellation.none) { @@ -262,7 +241,7 @@ export class Configuration { opts.services = this._visitRegistrations(data.services, "services"); if (data.inject) { - this._path.push("inject"); + this._enter("inject"); opts.inject = mapAll( data.inject instanceof Array ? data.inject : @@ -353,11 +332,11 @@ export class Configuration { } async _visitFactoryRegistration(data: FactoryRegistration, name: _key) { - argumentOfType(data.$factory, Function, "data.$type"); + argumentOfType(data.$factory, Function, "data.$factory"); this._enter(name); const opts = this._makeServiceParams(data); - opts.factory = opts.$factory; + opts.factory = data.$factory; const d = new FactoryServiceDescriptor( await mapAll(opts) diff --git a/src/main/ts/di/FactoryServiceDescriptor.ts b/src/main/ts/di/FactoryServiceDescriptor.ts --- a/src/main/ts/di/FactoryServiceDescriptor.ts +++ b/src/main/ts/di/FactoryServiceDescriptor.ts @@ -14,7 +14,7 @@ export class FactoryServiceDescriptor ex argumentNotNull(opts && opts.factory, "opts.factory"); // bind to null - this._factory = () => opts.factory(); + this._factory = (...args) => opts.factory.apply(null, args); if (opts.activation === ActivationType.Singleton) { this._cacheId = oid(opts.factory); diff --git a/src/main/ts/di/ResolverHelper.d.ts b/src/main/ts/di/ResolverHelper.d.ts --- a/src/main/ts/di/ResolverHelper.d.ts +++ b/src/main/ts/di/ResolverHelper.d.ts @@ -1,3 +1,3 @@ import { ModuleResolver } from "./Configuration"; -export declare function makeResolver(moduleName?: string, contextRequire?: any): ModuleResolver; \ No newline at end of file +export declare function makeResolver(moduleName?: string, contextRequire?: any): Promise; \ No newline at end of file diff --git a/src/main/ts/di/ServiceDescriptor.ts b/src/main/ts/di/ServiceDescriptor.ts --- a/src/main/ts/di/ServiceDescriptor.ts +++ b/src/main/ts/di/ServiceDescriptor.ts @@ -14,9 +14,9 @@ function injectMethod(target, method, co throw new Error("Method '" + method + "' not found"); if (args instanceof Array) - return m.apply(target, context.parse(args, "." + method)); + return m.apply(target, _parse(args, context, "." + method)); else - return m.call(target, context.parse(args, "." + method)); + return m.call(target, _parse(args, context, "." + method)); } function makeClenupCallback(target, method: ((instance) => void) | string) { @@ -90,10 +90,10 @@ export class ServiceDescriptor implement this._owner = opts.owner; - if (opts.activation) + if ("activation" in opts) this._activationType = opts.activation; - if (opts.params) + if ("params" in opts) this._params = opts.params; if (opts.inject) diff --git a/src/main/ts/di/interfaces.ts b/src/main/ts/di/interfaces.ts --- a/src/main/ts/di/interfaces.ts +++ b/src/main/ts/di/interfaces.ts @@ -16,7 +16,7 @@ export interface ServiceMap { } export enum ActivationType { - Singleton, + Singleton = 1, Container, Hierarchy, Context, @@ -59,11 +59,11 @@ export interface DependencyRegistration } export function isTypeRegistration(x): x is TypeRegistration { - return (!isPrimitive(x)) && ("$type" in x || "$factory" in x); + return (!isPrimitive(x)) && ("$type" in x); } export function isFactoryRegistration(x): x is FactoryRegistration { - return (!isPrimitive(x)) && ("$type" in x || "$factory" in x); + return (!isPrimitive(x)) && ("$factory" in x); } export function isValueRegistration(x): x is ValueRegistration { diff --git a/src/main/ts/log/TraceSource.ts b/src/main/ts/log/TraceSource.ts --- a/src/main/ts/log/TraceSource.ts +++ b/src/main/ts/log/TraceSource.ts @@ -1,6 +1,6 @@ import { Observable } from "../Observable"; import { Registry } from "./Registry"; -import { format } from "../text/StringFormat"; +import { format as _format } from "../text/StringFormat"; export const DebugLevel = 400; @@ -20,6 +20,12 @@ export interface TraceEvent { readonly arg: any; } +function format(msg) { + if (typeof(msg) !== "string" || arguments.length === 1) + return msg; + return _format.apply(null, arguments); +} + export class TraceSource { readonly id: any; diff --git a/src/main/ts/safe.ts b/src/main/ts/safe.ts --- a/src/main/ts/safe.ts +++ b/src/main/ts/safe.ts @@ -3,6 +3,9 @@ const _oid = typeof Symbol === "function Symbol("__implab__oid__") : "__implab__oid__"; +declare const window: any; +declare const global: any; + export function oid(instance: object): string { if (isNull(instance)) return null; @@ -55,7 +58,7 @@ export function isString(val) { } export function isPromise(val): val is PromiseLike { - return "then" in val && val.then instanceof Function; + return val && typeof val.then === "function"; } export function isNullOrEmptyString(str) { @@ -68,8 +71,23 @@ export function isNotEmptyArray(arg): ar return (arg instanceof Array && arg.length > 0); } +function _isStrictMode() { + return !this; +} + +function _getNonStrictGlobal() { + return this; +} + export function getGlobal() { - return this; + // in es3 we can't use indirect call to eval, since it will + // be executed in the current call context. + if (!_isStrictMode()) { + return _getNonStrictGlobal(); + } else { + // tslint:disable-next-line:no-eval + return eval.call(null, "this"); + } } export function get(member: string, context?: object) { @@ -135,6 +153,9 @@ export function mixin(dest: T, sou argumentNotNull(dest, "to"); const _res = dest as T & S; + if (isPrimitive(source)) + return _res; + if (template instanceof Array) { for (const p of template) { if (p in source) @@ -268,6 +289,31 @@ export function pmap(items, cb) { return next(); } +export function pfor(items, cb) { + argumentNotNull(cb, "cb"); + + if (isPromise(items)) + return items.then(data => { + return pmap(data, cb); + }); + + if (isNull(items) || !items.length) + return items; + + let i = 0; + + function next() { + while (i < items.length) { + const r = cb(items[i], i); + i++; + if (isPromise(r)) + return r.then(next); + } + } + + return next(); +} + /** * Выбирает первый элемент из последовательности, или обещания, если в * качестве параметра используется обещание, оно должно вернуть массив. diff --git a/src/main/ts/text/StringFormat.ts b/src/main/ts/text/StringFormat.ts --- a/src/main/ts/text/StringFormat.ts +++ b/src/main/ts/text/StringFormat.ts @@ -124,7 +124,7 @@ function defaultConverter(value: any, pa } else if (value instanceof Date) { return value.toISOString(); } else { - return pattern ? value.toString(pattern) : value.toString(); + return value.toString(); } } @@ -171,3 +171,7 @@ const _default = new Formatter(); export function format(msg: string, ...args: any[]) { return _default.format(msg, ...args); } + +export function convert(value: any, pattern: string) { + return _default.format(value, pattern); +}