Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle transformed HTML at the root route. #30

Merged
merged 2 commits into from
Jul 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/koa-node-resolve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {parse as parseURL} from 'url';
import {moduleSpecifierTransform, ModuleSpecifierTransformOptions} from './koa-module-specifier-transform';
import {prefixedLogger} from './support/logger';
import {Logger} from './support/logger';
import {noLeadingSlashInURL} from './support/path-utils';
import {noLeadingSlashInURL, resolvePathPreserveTrailingSlash} from './support/path-utils';
import {resolveNodeSpecifier} from './support/resolve-node-specifier';

export {Logger} from './support/logger';
Expand All @@ -40,7 +40,7 @@ export const nodeResolve =
return moduleSpecifierTransform(
(baseURL: string, specifier: string, logger: Logger) =>
resolveNodeSpecifier(
resolvePath(
resolvePathPreserveTrailingSlash(
resolvePath(options.root || '.'),
noLeadingSlashInURL(parseURL(baseURL).pathname || '/')),
specifier,
Expand Down
14 changes: 13 additions & 1 deletion src/support/path-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
import {posix, sep as pathSeparator} from 'path';
import {posix, resolve as resolvePath, sep as pathSeparator} from 'path';

const filenameRegex = process.platform === 'win32' ? /[^\\]+$/ : /[^\/]+$/;

Expand All @@ -35,10 +35,22 @@ export const forwardSlashesOnlyPlease = (path: string): string =>

export const getBaseURL = (href: string): string => href.replace(/[^\/]+$/, '');

export const noTrailingSlashInPath = (path: string): string =>
path.replace(/\/$/, '');

export const noLeadingSlashInURL = (href: string): string =>
href.replace(/^\//, '');

export const relativePathToURL = (from: string, to: string): string =>
ensureLeadingDotInURL(posix.relative(
getBaseURL(forwardSlashesOnlyPlease(from)),
forwardSlashesOnlyPlease(to)));

export const resolvePathPreserveTrailingSlash =
(from: string, to: string): string => {
const resolvedPath = resolvePath(from, to);
return isDirectorySpecifier(to) ? `${resolvedPath}/` : resolvedPath;
};

const isDirectorySpecifier = (specifier: string) => ['', '.', '..'].includes(
specifier.match(/([^\/]*$)/)![0]);
47 changes: 45 additions & 2 deletions src/test/koa-node-resolve.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,16 @@
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
import {resolve as resolvePath} from 'path';
import request from 'supertest';
import test from 'tape';

import {nodeResolve} from '../koa-node-resolve';
import {resolvePathPreserveTrailingSlash} from '../support/path-utils';

import {createAndServe, squeeze, testLogger} from './test-utils';

const fixturesPath = resolvePath(__dirname, '../../test/fixtures/');
const fixturesPath =
resolvePathPreserveTrailingSlash(__dirname, '../../test/fixtures/');

test('nodeResolve middleware transforms resolvable specifiers', async (t) => {
t.plan(4);
Expand Down Expand Up @@ -63,6 +64,48 @@ test('nodeResolve middleware transforms resolvable specifiers', async (t) => {
});
});

test('nodeResolve middleware works even if baseURL has no pathname', async (t) => {
t.plan(4);
const logger = testLogger();
createAndServe(
{
middleware:
[nodeResolve({root: fixturesPath, logger, logLevel: 'debug'})],
routes: {
'/my-module.js': `import * as x from 'x';`,
'/': `
<script type="module">
import * as x from 'x';
</script>
`,
},
},
async (server) => {
t.equal(
squeeze((await request(server).get('/my-module.js')).text),
squeeze(`
import * as x from './node_modules/x/main.js';
`),
'should transform specifiers in JavaScript module');
t.equal(
squeeze((await request(server).get('/')).text),
squeeze(`
<script type="module">
import * as x from './node_modules/x/main.js';
</script>
`),
'should transform specifiers in inline module script');
t.deepEqual(logger.debugs.map((args) => args.join(' ')), [
'[koa-node-resolve] Resolved Node module specifier "x" to "./node_modules/x/main.js"',
'[koa-node-resolve] Resolved Node module specifier "x" to "./node_modules/x/main.js"',
]);
t.deepEqual(logger.infos.map((args) => args.join(' ')), [
'[koa-node-resolve] Transformed 1 module specifier(s) in "/my-module.js"',
'[koa-node-resolve] Transformed 1 module specifier(s) in "/"',
]);
});
});

test('nodeResolve middleware ignores unresolvable specifiers', async (t) => {
t.plan(2);
const logger = testLogger();
Expand Down
44 changes: 44 additions & 0 deletions src/test/path-utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* @license
* Copyright (c) 2020 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at
* http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at
* http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at
* http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
import test from 'tape';

import {dirname, resolvePathPreserveTrailingSlash} from '../support/path-utils';

test('dirname returns portion of path representing directory', (t) => {
t.plan(2);
t.equal(
dirname('/a/b/c'),
'/a/b/',
'should treat lack of trailing slash as file');
t.equal(
dirname('/a/b/c/'),
'/a/b/c/',
'should treat segment before trailing slash as directory name');
});

test('resolvePathPreserveTrailingSlash may return trailing slash', (t) => {
t.plan(3);
t.equal(
resolvePathPreserveTrailingSlash('/a/b', 'c/'),
'/a/b/c/',
'should contain trailing slash when destination has trailing slash');
t.equal(
resolvePathPreserveTrailingSlash('/a/b', 'c'),
'/a/b/c',
'should not contain trailing slash if destination does not have trailing slash');
t.equal(
resolvePathPreserveTrailingSlash('/a/b', ''),
'/a/b/',
'should contain trailing slash if destination is current directory');
});
5 changes: 2 additions & 3 deletions src/test/resolve-node-specifier.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,15 @@
* subject to an additional IP rights grant found at
* http://polymer.github.io/PATENTS.txt
*/
import {resolve as resolvePath} from 'path';
import test from 'tape';

import {ensureTrailingSlashInPath} from '../support/path-utils';
import {resolvePathPreserveTrailingSlash} from '../support/path-utils';
import {resolveNodeSpecifier} from '../support/resolve-node-specifier';
import {testLogger} from './test-utils';

const logger = testLogger();
const fixturesPath =
ensureTrailingSlashInPath(resolvePath(__dirname, '../../test/fixtures/'));
resolvePathPreserveTrailingSlash(__dirname, '../../test/fixtures/');
const resolve = (specifier: string): string =>
resolveNodeSpecifier(fixturesPath, specifier, logger);

Expand Down
4 changes: 2 additions & 2 deletions src/test/test-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ export const createApp = (options: AppOptions): Koa => {
app.use(route.get(key, (ctx) => {
if (key.endsWith('.js')) {
ctx.type = 'js';
}
if (key.endsWith('.html')) {
} else {
// Assume everything else is html.
ctx.type = 'html';
}
// Make our body a stream, like koa static would do, to make sure we
Expand Down