Skip to content

Commit ea91d97

Browse files
committed
[INTERNAL] resourceFactory: Add factory functions for Filter and Link readers
Eventually remove them from AbstractReader to remove the circular dependency to sub-class.
1 parent b56bd97 commit ea91d97

File tree

5 files changed

+122
-12
lines changed

5 files changed

+122
-12
lines changed

lib/AbstractReader.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ class AbstractReader {
8080
* @returns {Promise<@ui5/fs/readers/Filter>} Promise resolving with filter instance
8181
*/
8282
async filter(callback) {
83+
console.warn("DEPRECATED CALL TO AbstractReader#filter - THIS FUNCTION WILL BE REMOVED IN THE NEXT RELEASE");
8384
const {default: Filter} = await import("./readers/Filter.js");
8485
return new Filter({
8586
reader: this,
@@ -115,6 +116,7 @@ class AbstractReader {
115116
* @returns {Promise<@ui5/fs/readers/Link>} Promise resolving with reader instance
116117
*/
117118
async flatten(namespace) {
119+
console.warn("DEPRECATED CALL TO AbstractReader#flatten - THIS FUNCTION WILL BE REMOVED IN THE NEXT RELEASE");
118120
const {default: Link} = await import("./readers/Link.js");
119121
return new Link({
120122
reader: this,

lib/readers/Filter.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ import AbstractReader from "../AbstractReader.js";
55
*
66
* @public
77
* @class
8-
* @hideconstructor
98
* @alias @ui5/fs/readers/Filter
109
* @extends @ui5/fs/AbstractReader
1110
*/
@@ -22,8 +21,9 @@ class Filter extends AbstractReader {
2221
/**
2322
* Constructor
2423
*
24+
* @public
2525
* @param {object} parameters Parameters
26-
* @param {@ui5/fs/AbstractReader} parameters.reader The resource reader to wrap
26+
* @param {@ui5/fs/AbstractReader} parameters.reader The resource reader or collection to wrap
2727
* @param {@ui5/fs/readers/Filter~callback} parameters.callback
2828
* Filter function. Will be called for every resource read through this reader.
2929
*/

lib/readers/Link.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,30 +5,29 @@ import logger from "@ui5/logger";
55
const log = logger.getLogger("resources:readers:Link");
66

77
/**
8-
* A reader that allows modification of all resources passed through it.
8+
* A reader that allows removing paths segments from all resources passed through it.
99
*
1010
* @public
1111
* @class
12-
* @hideconstructor
1312
* @alias @ui5/fs/readers/Link
1413
* @extends @ui5/fs/AbstractReader
1514
*/
1615
class Link extends AbstractReader {
1716
/**
1817
* Path mapping for a [Link]{@link @ui5/fs/readers/Link}
1918
*
20-
* @private
19+
* @public
2120
* @typedef {object} @ui5/fs/readers/Link/PathMapping
22-
* @property {string} linkPath Input path to rewrite
23-
* @property {string} targetPath Path to rewrite to
21+
* @property {string} linkPath Path to match and replace in the requested path or pattern
22+
* @property {string} targetPath Path to use as a replacement in the request for the source reader
2423
*/
2524

2625
/**
2726
* Constructor
2827
*
29-
* @private
28+
* @public
3029
* @param {object} parameters Parameters
31-
* @param {@ui5/fs/AbstractReader} parameters.reader The resource reader to wrap
30+
* @param {@ui5/fs/AbstractReader} parameters.reader The resource reader or collection to wrap
3231
* @param {@ui5/fs/readers/Link/PathMapping} parameters.pathMapping
3332
*/
3433
constructor({reader, pathMapping}) {

lib/resourceFactory.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import ReaderCollection from "./ReaderCollection.js";
77
import ReaderCollectionPrioritized from "./ReaderCollectionPrioritized.js";
88
import Resource from "./Resource.js";
99
import WriterCollection from "./WriterCollection.js";
10+
import Filter from "./readers/Filter.js";
11+
import Link from "./readers/Link.js";
1012

1113
/**
1214
* @module @ui5/fs/resourceFactory
@@ -160,6 +162,59 @@ export function createWorkspace({reader, writer, virBasePath = "/", name = "vir
160162
});
161163
}
162164

165+
/**
166+
* Create a [Filter-Reader]{@link @ui5/fs/readers/Filter} with the given reader.
167+
* The provided callback is called for every resource that is retrieved through the
168+
* reader and decides whether the resource shall be passed on or dropped.
169+
*
170+
* @public
171+
* @param {object} parameters
172+
* @param {@ui5/fs/AbstractReader} parameters.reader Single reader or collection of readers
173+
* @param {@ui5/fs/readers/Filter~callback} parameters.callback
174+
* Filter function. Will be called for every resource passed through this reader.
175+
* @returns {@ui5/fs/readers/Filter} Reader instance
176+
*/
177+
export function createFilterReader(parameters) {
178+
return new Filter(parameters);
179+
}
180+
181+
/**
182+
* Create a [Link-Reader]{@link @ui5/fs/readers/Filter} with the given reader.
183+
* The provided path mapping allows
184+
*
185+
* @public
186+
* @param {object} parameters
187+
* @param {@ui5/fs/AbstractReader} parameters.reader Single reader or collection of readers
188+
* @param {@ui5/fs/readers/Link/PathMapping} parameters.pathMapping
189+
* @returns {@ui5/fs/readers/Link} Reader instance
190+
*/
191+
export function createLinkReader(parameters) {
192+
return new Link(parameters);
193+
}
194+
195+
/**
196+
* Create a [Link-Reader]{@link @ui5/fs/readers/Link} where all requests are prefixed with
197+
* <code>/resources/<namespace></code>.
198+
*
199+
* This simulates "flat" resource access, which is for example common for projects of type
200+
* "application".
201+
*
202+
* @public
203+
* @param {object} parameters
204+
* @param {@ui5/fs/AbstractReader} parameters.reader Single reader or collection of readers
205+
* @param {string} parameters.namespace Project namespace
206+
* @returns {@ui5/fs/readers/Link} Reader instance
207+
*/
208+
export function createFlatReader({reader, namespace}) {
209+
return new Link({
210+
reader: reader,
211+
pathMapping: {
212+
linkPath: `/`,
213+
targetPath: `/resources/${namespace}/`
214+
}
215+
});
216+
}
217+
163218
/**
164219
* Normalizes virtual glob patterns by prefixing them with
165220
* a given virtual base directory path

test/lib/resources.js

Lines changed: 57 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import chaifs from "chai-fs";
44
chai.use(chaifs);
55
const assert = chai.assert;
66
import sinon from "sinon";
7-
import {createAdapter} from "../../lib/resourceFactory.js";
7+
import {createAdapter, createFilterReader, createFlatReader, createLinkReader} from "../../lib/resourceFactory.js";
88

99
test.afterEach.always((t) => {
1010
sinon.restore();
@@ -37,7 +37,7 @@ test("Get resource from application.a (/index.html) and write it to /dest/ using
3737
});
3838
});
3939

40-
test("Filter resources", async (t) => {
40+
test("Legacy: Filter resources", async (t) => {
4141
const source = createAdapter({
4242
fsBasePath: "./test/fixtures/application.a/webapp",
4343
virBasePath: "/app/"
@@ -54,6 +54,39 @@ test("Filter resources", async (t) => {
5454
t.is(resources[0].getPath(), "/app/test.js", "Found correct resource");
5555
});
5656

57+
test("Legacy: Flatten resources", async (t) => {
58+
const source = createAdapter({
59+
fsBasePath: "./test/fixtures/application.a/webapp",
60+
virBasePath: "/resources/app/"
61+
});
62+
const transformedSource = await source.flatten("app");
63+
64+
const resources = await transformedSource.byGlob("**/*.js");
65+
t.is(resources.length, 1, "Found one resource via transformer");
66+
t.is(resources[0].getPath(), "/test.js", "Found correct resource");
67+
});
68+
69+
70+
test("Filter resources", async (t) => {
71+
const source = createAdapter({
72+
fsBasePath: "./test/fixtures/application.a/webapp",
73+
virBasePath: "/app/"
74+
});
75+
const filteredSource = createFilterReader({
76+
reader: source,
77+
callback: (resource) => {
78+
return resource.getPath().endsWith(".js");
79+
}
80+
});
81+
const sourceResources = await source.byGlob("**");
82+
t.is(sourceResources.length, 2, "Found two resources in source");
83+
84+
const resources = await filteredSource.byGlob("**");
85+
86+
t.is(resources.length, 1, "Found exactly one resource via filter");
87+
t.is(resources[0].getPath(), "/app/test.js", "Found correct resource");
88+
});
89+
5790
test("Transform resources", async (t) => {
5891
const source = createAdapter({
5992
fsBasePath: "./test/fixtures/application.a/webapp",
@@ -83,9 +116,30 @@ test("Flatten resources", async (t) => {
83116
fsBasePath: "./test/fixtures/application.a/webapp",
84117
virBasePath: "/resources/app/"
85118
});
86-
const transformedSource = await source.flatten("app");
119+
const transformedSource = createFlatReader({
120+
reader: source,
121+
namespace: "app"
122+
});
87123

88124
const resources = await transformedSource.byGlob("**/*.js");
89125
t.is(resources.length, 1, "Found one resource via transformer");
90126
t.is(resources[0].getPath(), "/test.js", "Found correct resource");
91127
});
128+
129+
test("Link resources", async (t) => {
130+
const source = createAdapter({
131+
fsBasePath: "./test/fixtures/application.a/webapp",
132+
virBasePath: "/resources/app/"
133+
});
134+
const transformedSource = createLinkReader({
135+
reader: source,
136+
pathMapping: {
137+
linkPath: "/wow/this/is/a/beautiful/path/just/wow/",
138+
targetPath: "/resources/"
139+
}
140+
});
141+
142+
const resources = await transformedSource.byGlob("**/*.js");
143+
t.is(resources.length, 1, "Found one resource via transformer");
144+
t.is(resources[0].getPath(), "/wow/this/is/a/beautiful/path/just/wow/app/test.js", "Found correct resource");
145+
});

0 commit comments

Comments
 (0)