Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_js_routing.controller.class">FOS\JsRoutingBundle\Controller\Controller</parameter>
</parameters>
<services>
<service id="fos_js_routing.controller" class="%fos_js_routing.controller.class%" public="true">
<argument type="service" id="fos_js_routing.routes_response" />
<argument type="service" id="fos_js_routing.serializer" />
<argument type="service" id="fos_js_routing.extractor" />
<argument>%fos_js_routing.cache_control%</argument>
<argument>%kernel.debug%</argument>
</service>
</services>
</container>

View File

@@ -0,0 +1,21 @@
{
"id": "router",
"paths": ["../../js"],
"mode": "ADVANCED",
"level": "VERBOSE",
"inputs": "../../js/export.js",
"externs": "../../js/externs.js",
"define": {
"goog.DEBUG": false
},
"type-prefixes-to-strip": ["goog.debug", "goog.asserts", "goog.assert", "console"],
"name-suffixes-to-strip": ["logger", "logger_"],
"output-file": "../../public/js/router.js",
"output-wrapper": "/**\n * Portions of this code are from the Google Closure Library,\n * received from the Closure Authors under the Apache 2.0 license.\n *\n * All other code is (C) FriendsOfSymfony and subject to the MIT license.\n */\n(function() {%output%})();",
"pretty-print": false,
"debug": false
}

View File

@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_js_routing_js" path="/js/routing.{_format}" methods="GET">
<default key="_controller">fos_js_routing.controller::indexAction</default>
<default key="_format">js</default>
<requirement key="_format">js|json</requirement>
</route>
</routes>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_js_routing.normalizer.route_collection.class">FOS\JsRoutingBundle\Serializer\Normalizer\RouteCollectionNormalizer</parameter>
<parameter key="fos_js_routing.normalizer.routes_response.class">FOS\JsRoutingBundle\Serializer\Normalizer\RoutesResponseNormalizer</parameter>
<parameter key="fos_js_routing.denormalizer.route_collection.class">FOS\JsRoutingBundle\Serializer\Denormalizer\RouteCollectionDenormalizer</parameter>
</parameters>
<services>
<service id="fos_js_routing.serializer" class="Symfony\Component\Serializer\Serializer" public="true">
<argument type="collection">
<argument type="service" id="fos_js_routing.normalizer.route_collection" />
<argument type="service" id="fos_js_routing.normalizer.routes_response" />
<argument type="service" id="fos_js_routing.denormalizer.route_collection" />
</argument>
<argument type="collection">
<argument key="json" type="service" id="fos_js_routing.encoder" />
</argument>
</service>
<service id="fos_js_routing.normalizer.route_collection" class="%fos_js_routing.normalizer.route_collection.class%" public="false" />
<service id="fos_js_routing.normalizer.routes_response" class="%fos_js_routing.normalizer.routes_response.class%" public="false" />
<service id="fos_js_routing.denormalizer.route_collection" class="%fos_js_routing.denormalizer.route_collection.class%" public="false" />
<service id="fos_js_routing.encoder" class="Symfony\Component\Serializer\Encoder\JsonEncoder" public="false" />
</services>
</container>

View File

@@ -0,0 +1,33 @@
<?xml version="1.0" ?>
<container xmlns="http://symfony.com/schema/dic/services"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<parameters>
<parameter key="fos_js_routing.extractor.class">FOS\JsRoutingBundle\Extractor\ExposedRoutesExtractor</parameter>
<parameter key="fos_js_routing.routes_response.class">FOS\JsRoutingBundle\Response\RoutesResponse</parameter>
</parameters>
<services>
<service id="fos_js_routing.extractor" class="%fos_js_routing.extractor.class%" public="true">
<argument type="service" id="fos_js_routing.router" />
<argument></argument>
<argument>%kernel.cache_dir%</argument>
<argument>%kernel.bundles%</argument>
</service>
<service id="fos_js_routing.routes_response" class="%fos_js_routing.routes_response.class%" public="true" />
<service id="fos_js_routing.dump_command" class="FOS\JsRoutingBundle\Command\DumpCommand">
<argument type="service" id="fos_js_routing.routes_response" />
<argument type="service" id="fos_js_routing.extractor" />
<argument type="service" id="fos_js_routing.serializer" />
<argument>%kernel.project_dir%</argument>
<argument>%fos_js_routing.request_context_base_url%</argument>
<tag name="console.command" />
</service>
<service id="fos_js_routing.router_debug_exposed_command" class="FOS\JsRoutingBundle\Command\RouterDebugExposedCommand">
<argument type="service" id="fos_js_routing.extractor" />
<argument type="service" id="router" />
<tag name="console.command" />
</service>
</services>
</container>

View File

@@ -0,0 +1,24 @@
const gulp = require('gulp');
const rename = require('gulp-rename');
const uglify = require('gulp-uglify');
const wrap = require('gulp-wrap');
const ts = require('gulp-typescript')
gulp.task('ts', function() {
return gulp.src('js/router.ts')
.pipe(ts({
noImplicitAny: true,
}))
.pipe(gulp.dest('public/js'));
});
gulp.task('min', function() {
return gulp.src('public/js/!(*.min).js')
.pipe(wrap({ src: 'js/router.template.js' }))
.pipe(gulp.dest('public/js'))
.pipe(rename({ extname: '.min.js' }))
.pipe(uglify())
.pipe(gulp.dest('public/js'));
});
gulp.task('default', gulp.series('ts', 'min'));

View File

@@ -0,0 +1,23 @@
(function (root, factory) {
var routing = factory();
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], routing.Routing);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = routing.Routing;
} else {
// Browser globals (root is window)
root.Routing = routing.Routing;
root.fos = {
Router: routing.Router
};
}
}(this, function () {
var exports = {};
<%= contents %>
return { Router: exports.Router, Routing: exports.Routing };
}));

View File

@@ -0,0 +1,353 @@
export interface RouteDefaults {
[index: string]: string | null;
}
export interface RouteRequirements {
[index: string]: string;
}
export interface RouteParams {
[index: string]: any;
}
export interface QueryParamAddFunction {
(prefix: string, params: any): void;
}
export interface Route {
tokens: (string|boolean)[][];
defaults: undefined[] | RouteDefaults;
requirements: undefined[] | RouteRequirements;
hosttokens: string[][];
schemes: string[];
methods: string[];
}
export interface RoutesMap {
[index: string]: Route;
}
export interface Context {
base_url: string;
prefix: string;
host: string;
port: string | null;
scheme: string;
locale: string | null;
}
export interface RoutingData {
base_url: string;
routes: RoutesMap;
prefix?: string;
host: string;
port?: string | null;
scheme?: string;
locale?: string | null;
}
export class Router {
private context_: Context;
private routes_!: RoutesMap;
static getInstance(): Router {
return Routing;
}
static setData(data: RoutingData): void {
const router = Router.getInstance();
router.setRoutingData(data);
}
constructor(context?: Context, routes?: RoutesMap) {
this.context_ = context || { base_url: '', prefix: '', host: '', port: '', scheme: '', locale: '' };
this.setRoutes(routes || {});
}
setRoutingData(data: RoutingData): void {
this.setBaseUrl(data['base_url']);
this.setRoutes(data['routes']);
if (typeof data.prefix !== 'undefined') {
this.setPrefix(data['prefix']);
}
if (typeof data.port !== 'undefined') {
this.setPort(data['port']);
}
if (typeof data.locale !== 'undefined') {
this.setLocale(data['locale']);
}
this.setHost(data['host']);
if (typeof data.scheme !== 'undefined') {
this.setScheme(data['scheme']);
}
}
setRoutes(routes: RoutesMap): void {
this.routes_ = Object.freeze(routes);
}
getRoutes(): RoutesMap {
return this.routes_;
}
setBaseUrl(baseUrl: string): void {
this.context_.base_url = baseUrl;
}
getBaseUrl(): string {
return this.context_.base_url;
}
setPrefix(prefix: string): void {
this.context_.prefix = prefix;
}
setScheme(scheme: string): void {
this.context_.scheme = scheme;
}
getScheme(): string {
return this.context_.scheme;
}
setHost(host: string): void {
this.context_.host = host;
}
getHost(): string {
return this.context_.host;
}
setPort(port: string | null) {
this.context_.port = port;
}
getPort(): string | null {
return this.context_.port;
};
setLocale(locale: string | null) {
this.context_.locale = locale;
}
getLocale(): string | null {
return this.context_.locale;
};
/**
* Builds query string params added to a URL.
* Port of jQuery's $.param() function, so credit is due there.
*/
buildQueryParams(prefix: string, params: any, add: QueryParamAddFunction): void {
let name;
let rbracket = new RegExp(/\[\]$/);
if (params instanceof Array) {
params.forEach((val, i) => {
if (rbracket.test(prefix)) {
add(prefix, val);
} else {
this.buildQueryParams(prefix + '[' + (typeof val === 'object' ? i : '') + ']', val, add);
}
});
} else if (typeof params === 'object') {
for (name in params) {
this.buildQueryParams(prefix + '[' + name + ']', params[name], add);
}
} else {
add(prefix, params);
}
}
/**
* Returns a raw route object.
*/
getRoute(name: string): Route {
let prefixedName = this.context_.prefix + name;
let sf41i18nName = name + '.' + this.context_.locale;
let prefixedSf41i18nName = this.context_.prefix + name + '.' + this.context_.locale;
let variants = [prefixedName, sf41i18nName, prefixedSf41i18nName, name];
for (let i in variants) {
if (variants[i] in this.routes_) {
return this.routes_[variants[i]];
}
}
throw new Error('The route "' + name + '" does not exist.');
}
/**
* Generates the URL for a route.
*/
generate(name: string, opt_params?: RouteParams, absolute?: boolean): string {
let route = (this.getRoute(name));
let params = opt_params || {};
let unusedParams = Object.assign({}, params);
let url = '';
let optional = true;
let host = '';
let port = (typeof this.getPort() == 'undefined' || this.getPort() === null) ? '' : this.getPort();
route.tokens.forEach((token) => {
if ('text' === token[0] && typeof token[1] === 'string') {
url = Router.encodePathComponent(token[1]) + url;
optional = false;
return;
}
if ('variable' === token[0]) {
if (token.length === 6 && token[5] === true) { // Sixth part of the token array indicates if it should be included in case of defaults
optional = false;
}
let hasDefault = route.defaults && !Array.isArray(route.defaults) && typeof token[3] === 'string' && (token[3] in route.defaults);
if (false === optional || !hasDefault || ((typeof token[3] === 'string' && token[3] in params) && !Array.isArray(route.defaults) && params[token[3]] != route.defaults[token[3]])) {
let value;
if (typeof token[3] === 'string' && token[3] in params) {
value = params[token[3]];
delete unusedParams[token[3]];
} else if (typeof token[3] === 'string' && hasDefault && !Array.isArray(route.defaults)) {
value = route.defaults[token[3]];
} else if (optional) {
return;
} else {
throw new Error('The route "' + name + '" requires the parameter "' + token[3] + '".');
}
let empty = true === value || false === value || '' === value;
if (!empty || !optional) {
let encodedValue = Router.encodePathComponent(value);
if ('null' === encodedValue && null === value) {
encodedValue = '';
}
url = token[1] + encodedValue + url;
}
optional = false;
} else if (hasDefault && (typeof token[3] === 'string' && token[3] in unusedParams)) {
delete unusedParams[token[3]];
}
return;
}
throw new Error('The token type "' + token[0] + '" is not supported.');
});
if (url === '') {
url = '/';
}
route.hosttokens.forEach((token) => {
let value;
if ('text' === token[0]) {
host = token[1] + host;
return;
}
if ('variable' === token[0]) {
if (token[3] in params) {
value = params[token[3]];
delete unusedParams[token[3]];
} else if (route.defaults && !Array.isArray(route.defaults) && (token[3] in route.defaults)) {
value = route.defaults[token[3]];
}
host = token[1] + value + host;
}
});
url = this.context_.base_url + url;
if (route.requirements && ('_scheme' in route.requirements) && this.getScheme() != route.requirements['_scheme']) {
const currentHost = host || this.getHost();
url = route.requirements['_scheme'] + '://' + currentHost + (currentHost.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
} else if ('undefined' !== typeof route.schemes && 'undefined' !== typeof route.schemes[0] && this.getScheme() !== route.schemes[0]) {
const currentHost = host || this.getHost();
url = route.schemes[0] + '://' + currentHost + (currentHost.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
} else if (host && this.getHost() !== host + (host.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port)) {
url = this.getScheme() + '://' + host + (host.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
} else if (absolute === true) {
url = this.getScheme() + '://' + this.getHost() + (this.getHost().indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
}
if (Object.keys(unusedParams).length > 0) {
let queryParams: string[] = [];
let add = (key: string, value: string|(() => string)) => {
// if value is a function then call it and assign it's return value as value
value = (typeof value === 'function') ? value() : value;
// change null to empty string
value = (value === null) ? '' : value;
queryParams.push(Router.encodeQueryComponent(key) + '=' + Router.encodeQueryComponent(value));
};
for (const prefix in unusedParams) {
if(unusedParams.hasOwnProperty(prefix)) {
this.buildQueryParams(prefix, unusedParams[prefix], add);
}
}
url = url + '?' + queryParams.join('&');
}
return url;
}
/**
* Returns the given string encoded to mimic Symfony URL generator.
*/
static customEncodeURIComponent(value: string): string {
return encodeURIComponent(value)
.replace(/%2F/g, '/')
.replace(/%40/g, '@')
.replace(/%3A/g, ':')
.replace(/%21/g, '!')
.replace(/%3B/g, ';')
.replace(/%2C/g, ',')
.replace(/%2A/g, '*')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/'/g, '%27')
;
}
/**
* Returns the given path properly encoded to mimic Symfony URL generator.
*/
static encodePathComponent(value: string): string {
return Router.customEncodeURIComponent(value)
.replace(/%3D/g, '=')
.replace(/%2B/g, '+')
.replace(/%21/g, '!')
.replace(/%7C/g, '|')
;
}
/**
* Returns the given query parameter or value properly encoded to mimic Symfony URL generator.
*/
static encodeQueryComponent(value: string): string {
return Router.customEncodeURIComponent(value)
.replace(/%3F/g, '?')
;
}
}
export const Routing = new Router();
export default Routing;

View File

@@ -0,0 +1,19 @@
Copyright (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,283 @@
(function (root, factory) {
var routing = factory();
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define([], routing.Routing);
} else if (typeof module === 'object' && module.exports) {
// Node. Does not work with strict CommonJS, but
// only CommonJS-like environments that support module.exports,
// like Node.
module.exports = routing.Routing;
} else {
// Browser globals (root is window)
root.Routing = routing.Routing;
root.fos = {
Router: routing.Router
};
}
}(this, function () {
var exports = {};
"use strict";
exports.__esModule = true;
exports.Routing = exports.Router = void 0;
var Router = /** @class */ (function () {
function Router(context, routes) {
this.context_ = context || { base_url: '', prefix: '', host: '', port: '', scheme: '', locale: '' };
this.setRoutes(routes || {});
}
Router.getInstance = function () {
return exports.Routing;
};
Router.setData = function (data) {
var router = Router.getInstance();
router.setRoutingData(data);
};
Router.prototype.setRoutingData = function (data) {
this.setBaseUrl(data['base_url']);
this.setRoutes(data['routes']);
if (typeof data.prefix !== 'undefined') {
this.setPrefix(data['prefix']);
}
if (typeof data.port !== 'undefined') {
this.setPort(data['port']);
}
if (typeof data.locale !== 'undefined') {
this.setLocale(data['locale']);
}
this.setHost(data['host']);
if (typeof data.scheme !== 'undefined') {
this.setScheme(data['scheme']);
}
};
Router.prototype.setRoutes = function (routes) {
this.routes_ = Object.freeze(routes);
};
Router.prototype.getRoutes = function () {
return this.routes_;
};
Router.prototype.setBaseUrl = function (baseUrl) {
this.context_.base_url = baseUrl;
};
Router.prototype.getBaseUrl = function () {
return this.context_.base_url;
};
Router.prototype.setPrefix = function (prefix) {
this.context_.prefix = prefix;
};
Router.prototype.setScheme = function (scheme) {
this.context_.scheme = scheme;
};
Router.prototype.getScheme = function () {
return this.context_.scheme;
};
Router.prototype.setHost = function (host) {
this.context_.host = host;
};
Router.prototype.getHost = function () {
return this.context_.host;
};
Router.prototype.setPort = function (port) {
this.context_.port = port;
};
Router.prototype.getPort = function () {
return this.context_.port;
};
;
Router.prototype.setLocale = function (locale) {
this.context_.locale = locale;
};
Router.prototype.getLocale = function () {
return this.context_.locale;
};
;
/**
* Builds query string params added to a URL.
* Port of jQuery's $.param() function, so credit is due there.
*/
Router.prototype.buildQueryParams = function (prefix, params, add) {
var _this = this;
var name;
var rbracket = new RegExp(/\[\]$/);
if (params instanceof Array) {
params.forEach(function (val, i) {
if (rbracket.test(prefix)) {
add(prefix, val);
}
else {
_this.buildQueryParams(prefix + '[' + (typeof val === 'object' ? i : '') + ']', val, add);
}
});
}
else if (typeof params === 'object') {
for (name in params) {
this.buildQueryParams(prefix + '[' + name + ']', params[name], add);
}
}
else {
add(prefix, params);
}
};
/**
* Returns a raw route object.
*/
Router.prototype.getRoute = function (name) {
var prefixedName = this.context_.prefix + name;
var sf41i18nName = name + '.' + this.context_.locale;
var prefixedSf41i18nName = this.context_.prefix + name + '.' + this.context_.locale;
var variants = [prefixedName, sf41i18nName, prefixedSf41i18nName, name];
for (var i in variants) {
if (variants[i] in this.routes_) {
return this.routes_[variants[i]];
}
}
throw new Error('The route "' + name + '" does not exist.');
};
/**
* Generates the URL for a route.
*/
Router.prototype.generate = function (name, opt_params, absolute) {
var route = (this.getRoute(name));
var params = opt_params || {};
var unusedParams = Object.assign({}, params);
var url = '';
var optional = true;
var host = '';
var port = (typeof this.getPort() == 'undefined' || this.getPort() === null) ? '' : this.getPort();
route.tokens.forEach(function (token) {
if ('text' === token[0] && typeof token[1] === 'string') {
url = Router.encodePathComponent(token[1]) + url;
optional = false;
return;
}
if ('variable' === token[0]) {
if (token.length === 6 && token[5] === true) { // Sixth part of the token array indicates if it should be included in case of defaults
optional = false;
}
var hasDefault = route.defaults && !Array.isArray(route.defaults) && typeof token[3] === 'string' && (token[3] in route.defaults);
if (false === optional || !hasDefault || ((typeof token[3] === 'string' && token[3] in params) && !Array.isArray(route.defaults) && params[token[3]] != route.defaults[token[3]])) {
var value = void 0;
if (typeof token[3] === 'string' && token[3] in params) {
value = params[token[3]];
delete unusedParams[token[3]];
}
else if (typeof token[3] === 'string' && hasDefault && !Array.isArray(route.defaults)) {
value = route.defaults[token[3]];
}
else if (optional) {
return;
}
else {
throw new Error('The route "' + name + '" requires the parameter "' + token[3] + '".');
}
var empty = true === value || false === value || '' === value;
if (!empty || !optional) {
var encodedValue = Router.encodePathComponent(value);
if ('null' === encodedValue && null === value) {
encodedValue = '';
}
url = token[1] + encodedValue + url;
}
optional = false;
}
else if (hasDefault && (typeof token[3] === 'string' && token[3] in unusedParams)) {
delete unusedParams[token[3]];
}
return;
}
throw new Error('The token type "' + token[0] + '" is not supported.');
});
if (url === '') {
url = '/';
}
route.hosttokens.forEach(function (token) {
var value;
if ('text' === token[0]) {
host = token[1] + host;
return;
}
if ('variable' === token[0]) {
if (token[3] in params) {
value = params[token[3]];
delete unusedParams[token[3]];
}
else if (route.defaults && !Array.isArray(route.defaults) && (token[3] in route.defaults)) {
value = route.defaults[token[3]];
}
host = token[1] + value + host;
}
});
url = this.context_.base_url + url;
if (route.requirements && ('_scheme' in route.requirements) && this.getScheme() != route.requirements['_scheme']) {
var currentHost = host || this.getHost();
url = route.requirements['_scheme'] + '://' + currentHost + (currentHost.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
}
else if ('undefined' !== typeof route.schemes && 'undefined' !== typeof route.schemes[0] && this.getScheme() !== route.schemes[0]) {
var currentHost = host || this.getHost();
url = route.schemes[0] + '://' + currentHost + (currentHost.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
}
else if (host && this.getHost() !== host + (host.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port)) {
url = this.getScheme() + '://' + host + (host.indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
}
else if (absolute === true) {
url = this.getScheme() + '://' + this.getHost() + (this.getHost().indexOf(':' + port) > -1 || '' === port ? '' : ':' + port) + url;
}
if (Object.keys(unusedParams).length > 0) {
var queryParams_1 = [];
var add = function (key, value) {
// if value is a function then call it and assign it's return value as value
value = (typeof value === 'function') ? value() : value;
// change null to empty string
value = (value === null) ? '' : value;
queryParams_1.push(Router.encodeQueryComponent(key) + '=' + Router.encodeQueryComponent(value));
};
for (var prefix in unusedParams) {
if (unusedParams.hasOwnProperty(prefix)) {
this.buildQueryParams(prefix, unusedParams[prefix], add);
}
}
url = url + '?' + queryParams_1.join('&');
}
return url;
};
/**
* Returns the given string encoded to mimic Symfony URL generator.
*/
Router.customEncodeURIComponent = function (value) {
return encodeURIComponent(value)
.replace(/%2F/g, '/')
.replace(/%40/g, '@')
.replace(/%3A/g, ':')
.replace(/%21/g, '!')
.replace(/%3B/g, ';')
.replace(/%2C/g, ',')
.replace(/%2A/g, '*')
.replace(/\(/g, '%28')
.replace(/\)/g, '%29')
.replace(/'/g, '%27');
};
/**
* Returns the given path properly encoded to mimic Symfony URL generator.
*/
Router.encodePathComponent = function (value) {
return Router.customEncodeURIComponent(value)
.replace(/%3D/g, '=')
.replace(/%2B/g, '+')
.replace(/%21/g, '!')
.replace(/%7C/g, '|');
};
/**
* Returns the given query parameter or value properly encoded to mimic Symfony URL generator.
*/
Router.encodeQueryComponent = function (value) {
return Router.customEncodeURIComponent(value)
.replace(/%3F/g, '?');
};
return Router;
}());
exports.Router = Router;
exports.Routing = new Router();
exports["default"] = exports.Routing;
return { Router: exports.Router, Routing: exports.Routing };
}));

View File

@@ -0,0 +1 @@
!function(e){(t={}).__esModule=!0,t.Routing=t.Router=void 0,o=function(){function l(e,t){this.context_=e||{base_url:"",prefix:"",host:"",port:"",scheme:"",locale:""},this.setRoutes(t||{})}return l.getInstance=function(){return t.Routing},l.setData=function(e){l.getInstance().setRoutingData(e)},l.prototype.setRoutingData=function(e){this.setBaseUrl(e.base_url),this.setRoutes(e.routes),void 0!==e.prefix&&this.setPrefix(e.prefix),void 0!==e.port&&this.setPort(e.port),void 0!==e.locale&&this.setLocale(e.locale),this.setHost(e.host),void 0!==e.scheme&&this.setScheme(e.scheme)},l.prototype.setRoutes=function(e){this.routes_=Object.freeze(e)},l.prototype.getRoutes=function(){return this.routes_},l.prototype.setBaseUrl=function(e){this.context_.base_url=e},l.prototype.getBaseUrl=function(){return this.context_.base_url},l.prototype.setPrefix=function(e){this.context_.prefix=e},l.prototype.setScheme=function(e){this.context_.scheme=e},l.prototype.getScheme=function(){return this.context_.scheme},l.prototype.setHost=function(e){this.context_.host=e},l.prototype.getHost=function(){return this.context_.host},l.prototype.setPort=function(e){this.context_.port=e},l.prototype.getPort=function(){return this.context_.port},l.prototype.setLocale=function(e){this.context_.locale=e},l.prototype.getLocale=function(){return this.context_.locale},l.prototype.buildQueryParams=function(o,e,n){var t,r=this,s=new RegExp(/\[\]$/);if(e instanceof Array)e.forEach(function(e,t){s.test(o)?n(o,e):r.buildQueryParams(o+"["+("object"==typeof e?t:"")+"]",e,n)});else if("object"==typeof e)for(t in e)this.buildQueryParams(o+"["+t+"]",e[t],n);else n(o,e)},l.prototype.getRoute=function(e){var t,o=[this.context_.prefix+e,e+"."+this.context_.locale,this.context_.prefix+e+"."+this.context_.locale,e];for(t in o)if(o[t]in this.routes_)return this.routes_[o[t]];throw new Error('The route "'+e+'" does not exist.')},l.prototype.generate=function(r,e,p){var t,s=this.getRoute(r),i=e||{},u=Object.assign({},i),c="",a=!0,o="",e=void 0===this.getPort()||null===this.getPort()?"":this.getPort();if(s.tokens.forEach(function(e){if("text"===e[0]&&"string"==typeof e[1])return c=l.encodePathComponent(e[1])+c,void(a=!1);if("variable"!==e[0])throw new Error('The token type "'+e[0]+'" is not supported.');6===e.length&&!0===e[5]&&(a=!1);var t=s.defaults&&!Array.isArray(s.defaults)&&"string"==typeof e[3]&&e[3]in s.defaults;if(!1===a||!t||"string"==typeof e[3]&&e[3]in i&&!Array.isArray(s.defaults)&&i[e[3]]!=s.defaults[e[3]]){var o,n=void 0;if("string"==typeof e[3]&&e[3]in i)n=i[e[3]],delete u[e[3]];else{if("string"!=typeof e[3]||!t||Array.isArray(s.defaults)){if(a)return;throw new Error('The route "'+r+'" requires the parameter "'+e[3]+'".')}n=s.defaults[e[3]]}(!0===n||!1===n||""===n)&&a||(o=l.encodePathComponent(n),c=e[1]+(o="null"===o&&null===n?"":o)+c),a=!1}else t&&"string"==typeof e[3]&&e[3]in u&&delete u[e[3]]}),""===c&&(c="/"),s.hosttokens.forEach(function(e){var t;"text"!==e[0]?"variable"===e[0]&&(e[3]in i?(t=i[e[3]],delete u[e[3]]):s.defaults&&!Array.isArray(s.defaults)&&e[3]in s.defaults&&(t=s.defaults[e[3]]),o=e[1]+t+o):o=e[1]+o}),c=this.context_.base_url+c,s.requirements&&"_scheme"in s.requirements&&this.getScheme()!=s.requirements._scheme?(t=o||this.getHost(),c=s.requirements._scheme+"://"+t+(-1<t.indexOf(":"+e)||""===e?"":":"+e)+c):void 0!==s.schemes&&void 0!==s.schemes[0]&&this.getScheme()!==s.schemes[0]?(t=o||this.getHost(),c=s.schemes[0]+"://"+t+(-1<t.indexOf(":"+e)||""===e?"":":"+e)+c):o&&this.getHost()!==o+(-1<o.indexOf(":"+e)||""===e?"":":"+e)?c=this.getScheme()+"://"+o+(-1<o.indexOf(":"+e)||""===e?"":":"+e)+c:!0===p&&(c=this.getScheme()+"://"+this.getHost()+(-1<this.getHost().indexOf(":"+e)||""===e?"":":"+e)+c),0<Object.keys(u).length){function f(e,t){t=null===(t="function"==typeof t?t():t)?"":t,h.push(l.encodeQueryComponent(e)+"="+l.encodeQueryComponent(t))}var n,h=[];for(n in u)u.hasOwnProperty(n)&&this.buildQueryParams(n,u[n],f);c=c+"?"+h.join("&")}return c},l.customEncodeURIComponent=function(e){return encodeURIComponent(e).replace(/%2F/g,"/").replace(/%40/g,"@").replace(/%3A/g,":").replace(/%21/g,"!").replace(/%3B/g,";").replace(/%2C/g,",").replace(/%2A/g,"*").replace(/\(/g,"%28").replace(/\)/g,"%29").replace(/'/g,"%27")},l.encodePathComponent=function(e){return l.customEncodeURIComponent(e).replace(/%3D/g,"=").replace(/%2B/g,"+").replace(/%21/g,"!").replace(/%7C/g,"|")},l.encodeQueryComponent=function(e){return l.customEncodeURIComponent(e).replace(/%3F/g,"?")},l}(),t.Router=o,t.Routing=new o,t.default=t.Routing;var t,o={Router:t.Router,Routing:t.Routing};"function"==typeof define&&define.amd?define([],o.Routing):"object"==typeof module&&module.exports?module.exports=o.Routing:(e.Routing=o.Routing,e.fos={Router:o.Router})}(this);

View File

@@ -0,0 +1,88 @@
export interface RouteDefaults {
[index: string]: string | null;
}
export interface RouteRequirements {
[index: string]: string;
}
export interface RouteParams {
[index: string]: any;
}
export interface QueryParamAddFunction {
(prefix: string, params: any): void;
}
export interface Route {
tokens: (string | boolean)[][];
defaults: undefined[] | RouteDefaults;
requirements: undefined[] | RouteRequirements;
hosttokens: string[][];
schemes: string[];
methods: string[];
}
export interface RoutesMap {
[index: string]: Route;
}
export interface Context {
base_url: string;
prefix: string;
host: string;
port: string | null;
scheme: string;
locale: string | null;
}
export interface RoutingData {
base_url: string;
routes: RoutesMap;
prefix?: string;
host: string;
port?: string | null;
scheme?: string;
locale?: string | null;
}
export declare class Router {
private context_;
private routes_;
static getInstance(): Router;
static setData(data: RoutingData): void;
constructor(context?: Context, routes?: RoutesMap);
setRoutingData(data: RoutingData): void;
setRoutes(routes: RoutesMap): void;
getRoutes(): RoutesMap;
setBaseUrl(baseUrl: string): void;
getBaseUrl(): string;
setPrefix(prefix: string): void;
setScheme(scheme: string): void;
getScheme(): string;
setHost(host: string): void;
getHost(): string;
setPort(port: string | null): void;
getPort(): string | null;
setLocale(locale: string | null): void;
getLocale(): string | null;
/**
* Builds query string params added to a URL.
* Port of jQuery's $.param() function, so credit is due there.
*/
buildQueryParams(prefix: string, params: any, add: QueryParamAddFunction): void;
/**
* Returns a raw route object.
*/
getRoute(name: string): Route;
/**
* Generates the URL for a route.
*/
generate(name: string, opt_params?: RouteParams, absolute?: boolean): string;
/**
* Returns the given string encoded to mimic Symfony URL generator.
*/
static customEncodeURIComponent(value: string): string;
/**
* Returns the given path properly encoded to mimic Symfony URL generator.
*/
static encodePathComponent(value: string): string;
/**
* Returns the given query parameter or value properly encoded to mimic Symfony URL generator.
*/
static encodeQueryComponent(value: string): string;
}
export declare const Routing: Router;
export default Routing;

View File

@@ -0,0 +1,89 @@
import { expectType } from 'tsd';
import type { RoutesMap } from '../js/router';
import { type Route, Router, Routing } from './router';
import routes from './routes.json';
expectType<Router>(Router.getInstance());
expectType<Router>(Routing);
expectType<RoutesMap>(Routing.getRoutes());
expectType<Route>(Routing.getRoute('homepage'));
expectType<string>(Routing.getBaseUrl());
Routing.setBaseUrl('');
expectType<string>(Routing.getScheme());
Routing.setScheme('https');
expectType<string>(Routing.getHost());
Routing.setHost('localhost');
expectType<string | null>(Routing.getPort());
Routing.setPort('1234');
expectType<string | null>(Routing.getLocale());
Routing.setLocale('en');
Routing.setRoutingData(routes);
Routing.setRoutingData({
base_url: '',
routes: {
homepage: { tokens: [['text', '/']], defaults: [], requirements: [], hosttokens: [], methods: [], schemes: [], },
admin_index: { tokens: [['text', '/admin']], defaults: [], requirements: [], hosttokens: [], methods: [], schemes: [], },
admin_pages: { tokens: [['text', '/admin/path']], defaults: [], requirements: [], hosttokens: [], methods: [], schemes: [], },
blog_index: { tokens: [['text', '/blog']], defaults: [], requirements: [], hosttokens: [['text', 'localhost']], methods: [], schemes: [], },
blog_post: {
tokens: [
['variable', '/', '[^/]++', 'slug'],
['text', '/blog'],
],
defaults: [],
requirements: [],
hosttokens: [['text', 'localhost']],
methods: [],
schemes: [],
},
users_delete: {
tokens: [
['text', '/delete'],
['variable', '/', '[^/]++', 'id', true],
['text', '/users']
],
defaults: [],
requirements: [],
hosttokens: [],
methods: [
'DELETE'
],
schemes: []
},
feed_post: {
tokens: [
['variable', '.', 'js|json', '_format', true],
['text', '/feed/post']
],
defaults: {
_format: 'xml',
},
requirements: {
_format: 'xml|json',
},
hosttokens: [],
methods: ['GET'],
schemes: [],
},
},
prefix: '',
host: '',
port: null,
scheme: '',
locale: 'en',
});
expectType<string>(Routing.generate('homepage'));
expectType<string>(Routing.generate('blog_post', {
slug: 'my-blog-post',
}));
expectType<string>(Routing.generate('users_delete', {
id: 123,
}));

View File

@@ -0,0 +1,33 @@
{
"base_url": "",
"routes": {
"feed_post": {
"tokens": [
[
"variable",
".",
"js|json",
"_format",
true
],
["text", "/feed/post"]
],
"defaults": {
"_format": "xml"
},
"requirements": {
"_format": "xml|json"
},
"hosttokens": [],
"methods": [
"GET"
],
"schemes": []
}
},
"prefix": "",
"host": "localhost",
"port": "",
"scheme": "https",
"locale": null
}

View File

@@ -0,0 +1,8 @@
{
"compilerOptions": {
"declaration": true,
"declarationDir": "ts",
"resolveJsonModule": true,
"esModuleInterop": true
}
}

View File

@@ -0,0 +1,106 @@
/**
* @author Adrien Foulon <tofandel@tukan.hu>
*/
const fs = require('fs');
const path = require('path');
const util = require('util');
const InjectPlugin = require('@bpnetguy/webpack-inject-plugin').default;
const execFile = util.promisify(require('child_process').execFile);
const readFile = util.promisify(fs.readFile);
const rmFile = util.promisify(fs.rm);
const writeFile = util.promisify(fs.writeFile);
const makeDir = util.promisify(fs.mkdir)
class FosRouting {
default = {
locale: '',
prettyPrint: false,
domain: [],
php: 'php'
};
constructor(options = {}, registerCompileHooks = true) {
this.options = Object.assign({target: 'var/cache/fosRoutes.json'}, this.default, options, {format: 'json'});
this.finalTarget = path.resolve(process.cwd(), this.options.target);
this.options.target = path.resolve(process.cwd(), this.options.target.replace(/\.json$/, '.tmp.json'));
if (this.options.target === this.finalTarget) {
this.options.target += '.tmp';
}
this.registerCompileHooks = registerCompileHooks;
}
// Values don't need to be escaped because node already does that
shellArg(key, value) {
key = this.kebabize(key);
return typeof value === 'boolean' ? (value ? '--' + key : '') : '--' + key + '=' + value;
}
kebabize(str) {
return str.split('').map((letter, idx) => {
return letter.toUpperCase() === letter
? `${idx !== 0 ? '-' : ''}${letter.toLowerCase()}`
: letter;
}).join('');
}
apply(compiler) {
let prevContent = null;
try {
fs.readFileSync(this.finalTarget);
} catch (e) {
}
const compile = async (comp, callback) => {
const args = Object.keys(this.options).reduce((pass, key) => {
const val = this.options[key];
if (val !== this.default[key]) {
if (Array.isArray(val)) {
pass.push(...val.map((v) => this.shellArg(key, v)));
} else {
pass.push(this.shellArg(key, val));
}
}
return pass;
}, []);
await execFile(this.options.php, ['bin/console', 'fos:js-routing:dump', ...args]);
try {
const content = await readFile(this.options.target);
await rmFile(this.options.target);
if (!prevContent || content.compare(prevContent) !== 0) {
await makeDir(path.dirname(this.finalTarget), {recursive: true});
await writeFile(this.finalTarget, content);
prevContent = content;
if (comp.modifiedFiles && !comp.modifiedFiles.has(this.finalTarget)) {
comp.modifiedFiles.add(this.finalTarget);
}
}
} catch (e) {
const logger = compiler.getInfrastructureLogger('FosRouting');
logger.error(e.toString());
}
callback();
};
if (this.registerCompileHooks === true) {
compiler.hooks.beforeRun.tapAsync('RouteDump', compile);
compiler.hooks.watchRun.tapAsync('RouteDump_Watch', (comp, callback) => {
if (!comp.modifiedFiles || !comp.modifiedFiles.has(this.finalTarget)) {
compile(comp, callback);
} else {
callback();
}
});
}
new InjectPlugin(() => {
return 'import Routing from "fos-router";' +
'import routes from '+JSON.stringify(this.finalTarget)+';' +
'Routing.setRoutingData(routes);';
}).apply(compiler);
}
}
module.exports = FosRouting;
module.exports.default = FosRouting;