Skip to content

Commit

Permalink
Merge pull request #718 from smapiot/develop
Browse files Browse the repository at this point in the history
Release 1.6.2
  • Loading branch information
FlorianRappl authored Sep 27, 2024
2 parents 9fc8bab + 3dd0674 commit 927209c
Show file tree
Hide file tree
Showing 16 changed files with 855 additions and 520 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Piral Changelog

## 1.6.2 (tbd)

- Fixed `registerBreadcrumbs` in `piral-breadcrumbs` failing when no matcher was specified
- Updated dependencies
- Removed dependency to `path-to-regexp` package
- Added `loading-pilets` and `loaded-pilets` events

## 1.6.1 (August 7, 2024)

- Improved CLI flag validation and documentation (#705)
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/04-the-pilet-api.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ export const MyPage: React.FC = () => (
In general the provided path in the `registerPage` API is exact. Therefore, if you plan to have some sub-routing on the provided page you'd need to match more than one URL. The syntax follows the [path-to-regexp](https://github.com/pillarjs/path-to-regexp) way. As an example, you could go for `/my-pilet/:path*` to match all paths prefixed with `/my-pilet`.

::: tip: Testing paths
The path supplied to the `registerPage` API can be tested with [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) utility. Importantly, you'd need to set the version to "2.0.0" to mimic the behavior of the `path-to-regexp` package in Piral.
The path supplied to the `registerPage` API can be tested with [Express Route Tester](http://forbeslindesay.github.io/express-route-tester/) utility. Importantly, you'd need to set the version to "2.0.0" to mimic the behavior of the routes in Piral.
:::

<!-- markdown-link-check-disable-next-line -->
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
"src/utilities/*"
],
"scripts": {
"bootstrap": "lerna clean --yes && lerna bootstrap",
"setup": "yarn bootstrap",
"bootstrap": "lerna clean --yes && yarn install",
"setup": "yarn install",
"build": "lerna run build",
"build:docs": "lerna run build:docs --stream",
"watch:docs": "lerna run watch:docs --stream",
Expand Down
2 changes: 1 addition & 1 deletion src/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ npm install --global yarn
Once you cloned the repository make sure to bootstrap it (installs all dependencies and more).

```sh
npx lerna bootstrap
yarn install
```

Now you are ready to build all contained modules:
Expand Down
1 change: 0 additions & 1 deletion src/framework/piral-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
"test": "echo \"Error: run tests from root\" && exit 1"
},
"dependencies": {
"path-to-regexp": "^1.8.0",
"piral-base": "^1.6.1",
"piral-debug-utils": "^1.6.1",
"zustand": "^3.0.0"
Expand Down
12 changes: 9 additions & 3 deletions src/framework/piral-core/src/components/Mediator.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,26 @@ export interface MediatorProps {
* The Mediator component for interfacing with pilets loading.
*/
export const Mediator: React.FC<MediatorProps> = ({ options }) => {
const { initialize, readState } = useGlobalStateContext();
const { initialize, readState, emit } = useGlobalStateContext();

React.useEffect(() => {
const shouldLoad = readState(s => s.app.loading);
const shouldLoad = readState((s) => s.app.loading);

if (shouldLoad) {
const { connect, disconnect } = startLoadingPilets(options);

emit('loading-pilets', { options });

const notifier: PiletsLoading = (error, pilets, loaded) => {
initialize(!loaded, error, pilets);

if (loaded) {
emit('loaded-pilets', { pilets, error });
}
};
connect(notifier);
return () => disconnect(notifier);
}

}, none);

// tslint:disable-next-line:no-null-keyword
Expand Down
28 changes: 27 additions & 1 deletion src/framework/piral-core/src/types/utils.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type {} from 'piral-base';
import type { Pilet, LoadPiletsOptions } from 'piral-base';
import type { PiralCustomEventMap } from './custom';

/**
Expand Down Expand Up @@ -82,9 +82,35 @@ export interface PiralUnhandledErrorEvent {
pilet: string;
}

/**
* Gets fired when all pilets have been loaded.
*/
export interface PiralLoadedPiletsEvent {
/**
* The pilets that have been loaded.
*/
pilets: Array<Pilet>;
/**
* The loading error, if any.
*/
error?: Error;
}

/**
* Gets fired when the loading of pilets is triggered.
*/
export interface PiralLoadingPiletsEvent {
/**
* The options that have been supplied for loading the pilets.
*/
options: LoadPiletsOptions;
}

declare module 'piral-base/lib/types/api' {
interface PiralEventMap extends PiralCustomEventMap {
'store-data': PiralStoreDataEvent;
'unhandled-error': PiralUnhandledErrorEvent;
'loading-pilets': PiralLoadingPiletsEvent;
'loaded-pilets': PiralLoadedPiletsEvent;
}
}
134 changes: 132 additions & 2 deletions src/framework/piral-core/src/utils/routes.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,135 @@
import ptr from 'path-to-regexp';
const defaultDelimiter = escapeString('/');
const pathExpr = new RegExp(
[
'(\\\\.)',
'([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))',
].join('|'),
'g',
);

function escapeString(str: string) {
return str.replace(/([.+*?=^!:${}()[\]|\/\\])/g, '\\$1');
}

function escapeGroup(group: string) {
return group.replace(/([=!:$\/()])/g, '\\$1');
}

type Token =
| string
| {
name: string;
prefix: string;
delimiter: string;
optional: boolean;
repeat: boolean;
partial: boolean;
asterisk: boolean;
pattern: string;
};

function parse(str: string) {
const tokens: Array<Token> = [];
let key = 0;
let index = 0;
let path = '';
let res: RegExpExecArray;

while ((res = pathExpr.exec(str)) !== null) {
const m = res[0];
const escaped = res[1];
const offset = res.index;
path += str.slice(index, offset);
index = offset + m.length;

// Ignore already escaped sequences.
if (escaped) {
path += escaped[1];
continue;
}

const next = str[index];
const prefix = res[2];
const name = res[3];
const capture = res[4];
const group = res[5];
const modifier = res[6];
const asterisk = res[7];

// Push the current path onto the tokens.
if (path) {
tokens.push(path);
path = '';
}

const partial = prefix != null && next != null && next !== prefix;
const repeat = modifier === '+' || modifier === '*';
const optional = modifier === '?' || modifier === '*';
const delimiter = res[2] || '/';
const pattern = capture || group;

tokens.push({
name: name || `${key++}`,
prefix: prefix || '',
delimiter,
optional,
repeat,
partial,
asterisk: !!asterisk,
pattern: pattern ? escapeGroup(pattern) : asterisk ? '.*' : '[^' + escapeString(delimiter) + ']+?',
});
}

// Match any characters still remaining.
if (index < str.length) {
path += str.substring(index);
}

// If the path exists, push it onto the end.
if (path) {
tokens.push(path);
}

return tokens;
}

function tokensToRegExp(tokens: Array<Token>) {
let route = '';

for (const token of tokens) {
if (typeof token === 'string') {
route += escapeString(token);
} else {
const prefix = escapeString(token.prefix);
let capture = '(?:' + token.pattern + ')';

if (token.repeat) {
capture += '(?:' + prefix + capture + ')*';
}

if (token.optional) {
if (!token.partial) {
capture = '(?:' + prefix + '(' + capture + '))?';
} else {
capture = prefix + '(' + capture + ')?';
}
} else {
capture = prefix + '(' + capture + ')';
}

route += capture;
}
}

const endsWithDelimiter = route.slice(-defaultDelimiter.length) === defaultDelimiter;
const path = endsWithDelimiter ? route.slice(0, -defaultDelimiter.length) : route;
return new RegExp(`^${path}(?:${defaultDelimiter}(?=$))?$`, 'i');
}

function stringToRegexp(path: string) {
return tokensToRegExp(parse(path));
}

export function createRouteMatcher(path: string): RegExp {
return ptr(path);
return stringToRegexp(path);
}
2 changes: 1 addition & 1 deletion src/plugins/piral-axios/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
"test": "echo \"Error: run tests from root\" && exit 1"
},
"dependencies": {
"axios": "^1.6.0"
"axios": "^1.7.7"
},
"devDependencies": {
"piral-core": "^1.6.1"
Expand Down
34 changes: 20 additions & 14 deletions src/plugins/piral-breadcrumbs/src/create.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,38 +68,44 @@ export function createBreadcrumbsApi(config: DashboardConfig = {}): PiralPlugin<
withAll(withBreadcrumbs(getBreadcrumbs(breadcrumbs)), withRootExtension('piral-breadcrumbs', Breadcrumbs)),
);

const registerBcs = (bcs: Dict<BreadcrumbRegistration>) => {
context.registerBreadcrumbs(bcs);
return () => context.unregisterBreadcrumbs(Object.keys(bcs));
};

return (_, target) => {
const pilet = target.name;
let next = 0;

const appendBc = (bcs: Dict<BreadcrumbRegistration>, name: string | number, settings: BreadcrumbSettings) => {
const id = buildName(pilet, name);
bcs[id] = {
pilet,
matcher: getMatcher(settings),
settings,
};
return bcs;
};

return {
registerBreadcrumbs(values) {
const bc = {};
const bcs: Dict<BreadcrumbRegistration> = {};

for (const value of values) {
const { name = next++, ...settings } = value;
const id = buildName(pilet, name);
bc[id] = settings;
appendBc(bcs, name, settings);
}

context.registerBreadcrumbs(bc);
return () => context.unregisterBreadcrumbs(Object.keys(bc));
return registerBcs(bcs);
},
registerBreadcrumb(name, settings?) {
if (typeof name !== 'string') {
settings = name;
name = next++;
}

const id = buildName(pilet, name);
context.registerBreadcrumbs({
[id]: {
pilet,
matcher: getMatcher(settings),
settings,
},
});
return () => context.unregisterBreadcrumbs([id]);
const bcs = appendBc({}, name, settings);
return registerBcs(bcs);
},
unregisterBreadcrumb(name) {
const id = buildName(pilet, name);
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/piral-fetch/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,9 @@
},
"devDependencies": {
"@types/cors": "^2.8.6",
"@types/express": "^4.11.1",
"@types/express": "^4.17.21",
"cors": "^2.8.5",
"express": "^4.17.1",
"express": "^4.20.0",
"piral-core": "^1.6.1",
"whatwg-fetch": "^3.0.0"
}
Expand Down
18 changes: 9 additions & 9 deletions src/tooling/piral-cli-webpack5/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,22 @@
"@babel/preset-react": "^7.22.15",
"ansi-html-community": "0.0.8",
"babel-loader": "^9.1.3",
"cheerio": "1.0.0-rc.12",
"css-loader": "^6.8.1",
"cheerio": "^1.0.0",
"css-loader": "^6.11.0",
"css-minimizer-webpack-plugin": "^5.0.1",
"express": "^4.17.1",
"express": "^4.20.0",
"html-entities": "^1.2.0",
"html-webpack-plugin": "^5.5.3",
"loader-utils": "^2.0.0",
"html-webpack-plugin": "^5.6.0",
"loader-utils": "^2.0.4",
"mini-css-extract-plugin": "^2.7.6",
"parcel-codegen-loader": "^1.0.0",
"sass": "^1.63.6",
"sass-loader": "^13.3.2",
"source-map-loader": "^4.0.1",
"style-loader": "^3.3.3",
"style-loader": "^3.3.4",
"systemjs-webpack-interop": "^2.3.7",
"terser-webpack-plugin": "^5.3.9",
"ts-loader": "^9.4.4",
"webpack": "^5.82.1"
"terser-webpack-plugin": "^5.3.10",
"ts-loader": "^9.5.1",
"webpack": "^5.94.0"
}
}
2 changes: 1 addition & 1 deletion src/tooling/piral-cli-webpack5/src/webpack/bundler-run.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ export function runWebpack(wpConfig: webpack.Configuration, logLevel: LogLevels)

if (process) {
// process is undefined in case of an error
const compilation = process.createCompilation();
const compilation = process.createCompilation(undefined);
preset.current = compilation.createStatsOptions(getPreset(logLevel));
}
});
Expand Down
4 changes: 2 additions & 2 deletions src/tooling/piral-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"@types/rimraf": "^2.0.2",
"@types/tar": "^4.0.0",
"@types/yargs": "^15.0.4",
"axios": "^1.6.0",
"axios": "^1.7.7",
"chalk": "^4.0.0",
"enhanced-resolve": "^5.10.0",
"form-data": "^3.0.0",
Expand All @@ -76,7 +76,7 @@
"dependencies": {
"css-conflict-inspector": "^0.2.1",
"dets": "^0.16.0",
"kras": "^0.16.1",
"kras": "^0.17.0",
"rimraf": "^3.0.0",
"typescript": "^5.0.0",
"yargs": "^15.0.0"
Expand Down
Loading

0 comments on commit 927209c

Please sign in to comment.