tungsten 0.2.11 → 0.2.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Framework.js +2 -2
- package/dist/Servers/loadEnvsDev.d.ts.map +1 -1
- package/dist/Servers/loadEnvsDev.js +12 -5
- package/dist/Servers/portError.js +1 -1
- package/dist/Servers/routing.js +1 -1
- package/dist/bin/commands/dev.d.ts.map +1 -1
- package/dist/bin/commands/dev.js +2 -4
- package/dist/bin/commands/start.js +2 -4
- package/dist/env/privateEnv.js +1 -1
- package/dist/env/privateEnvOrThrow.js +1 -1
- package/dist/env/publicEnv.js +1 -1
- package/dist/env/publicEnvOrThrow.js +1 -1
- package/dist/possibleEnvFiles.d.ts +1 -1
- package/dist/possibleEnvFiles.d.ts.map +1 -1
- package/dist/possibleEnvFiles.js +2 -1
- package/dist/routing/Match.type.d.ts +9 -0
- package/dist/routing/Match.type.d.ts.map +1 -1
- package/dist/routing/RouteDataFunction.type.d.ts +3 -1
- package/dist/routing/RouteDataFunction.type.d.ts.map +1 -1
- package/dist/routing/matchPath.d.ts.map +1 -1
- package/dist/routing/matchPath.js +14 -2
- package/dist/routing/matchPath.sxyt.js +23 -0
- package/dist/routing/splitRequest.d.ts +17 -0
- package/dist/routing/splitRequest.d.ts.map +1 -0
- package/dist/routing/splitRequest.js +29 -0
- package/dist/routing/splitRequest.sxyt.d.ts +2 -0
- package/dist/routing/splitRequest.sxyt.d.ts.map +1 -0
- package/dist/routing/splitRequest.sxyt.js +47 -0
- package/package.json +1 -1
- package/dist/parseIni.d.ts +0 -4
- package/dist/parseIni.d.ts.map +0 -1
- package/dist/parseIni.js +0 -11
package/dist/Framework.js
CHANGED
|
@@ -20,7 +20,7 @@ import { staticGen } from "./staticGen/staticGen.js";
|
|
|
20
20
|
import { throwError } from "./throwError.js";
|
|
21
21
|
//import { devBundle } from './build/devBundle.jsx'
|
|
22
22
|
import { existsSync, readFileSync, openSync, closeSync, writeFileSync, copyFileSync } from 'fs';
|
|
23
|
-
import
|
|
23
|
+
import dotenv from 'dotenv';
|
|
24
24
|
import { getEnvSchemas } from "./env/getEnvSchemas.js";
|
|
25
25
|
import { injectEnv } from "./env/injectEnv.js";
|
|
26
26
|
//import { ValueOf } from 'sxy-lib'
|
|
@@ -167,7 +167,7 @@ export class Framework {
|
|
|
167
167
|
let someEnvLoaded = false; // eslint-disable-line no-type-assertion/no-type-assertion -- widening
|
|
168
168
|
//const envsLoadedMessages: string[] = []
|
|
169
169
|
function loadEnv(fileName, filePath, prefix = '') {
|
|
170
|
-
const env =
|
|
170
|
+
const env = dotenv.parse(readFileSync(filePath, 'utf-8'));
|
|
171
171
|
someEnvLoaded = true;
|
|
172
172
|
cliOut(`${fileName} loaded from ${filePath}`);
|
|
173
173
|
injectEnv(env, process.env, prefix);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"loadEnvsDev.d.ts","sourceRoot":"","sources":["../../src/Servers/loadEnvsDev.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAQpE,KAAK,UAAU,GAAG;IACd,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;CACf,CAAA;AAED,wBAAsB,WAAW,CAC7B,MAAM,EAAE,uBAAuB,EAE/B,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,UAAU,EAC7B,UAAU,EAAE,OAAO,EACnB,eAAe,UAAQ,
|
|
1
|
+
{"version":3,"file":"loadEnvsDev.d.ts","sourceRoot":"","sources":["../../src/Servers/loadEnvsDev.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,uBAAuB,CAAA;AAQpE,KAAK,UAAU,GAAG;IACd,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;IAChC,EAAE,CAAC,EAAE,MAAM,CAAC;CACf,CAAA;AAED,wBAAsB,WAAW,CAC7B,MAAM,EAAE,uBAAuB,EAE/B,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,UAAU,EAC7B,UAAU,EAAE,OAAO,EACnB,eAAe,UAAQ,iBAsH1B"}
|
|
@@ -2,7 +2,7 @@ import { join } from 'path';
|
|
|
2
2
|
import { readFile as readFilePromise, access as accessPromise } from 'fs/promises';
|
|
3
3
|
import { remap as objectRemap, filter as objectFilter } from 'sxy-lib/objects.js';
|
|
4
4
|
import { getEnvSchemasDev } from "../env/getEnvSchemas.js";
|
|
5
|
-
import
|
|
5
|
+
import dotenv from 'dotenv';
|
|
6
6
|
import { cliLog, cliOut } from "../cliOutput.js";
|
|
7
7
|
import { injectEnv } from "../env/injectEnv.js";
|
|
8
8
|
import { throwError } from 'tungsten/throwError.js';
|
|
@@ -38,7 +38,7 @@ iteration, initialProcessEnv, _firstLoad, useTestEnvFiles = false) {
|
|
|
38
38
|
const tryLoadEnvFile = async (fileName, filePath, prefix = '') => {
|
|
39
39
|
try {
|
|
40
40
|
//cliOut(`try to load env from ${filePath}`)
|
|
41
|
-
const env =
|
|
41
|
+
const env = dotenv.parse(await readFilePromise(filePath, 'utf-8'));
|
|
42
42
|
someEnvLoaded = true;
|
|
43
43
|
if (_firstLoad) cliOut(`${fileName} loaded from ${filePath}`);
|
|
44
44
|
//cliOut(fileName, JSON.stringify(env, null, 4))
|
|
@@ -53,7 +53,10 @@ iteration, initialProcessEnv, _firstLoad, useTestEnvFiles = false) {
|
|
|
53
53
|
}
|
|
54
54
|
};
|
|
55
55
|
const [envPath, privateEnvPath, publicEnvPath] = await Promise.all([resolveEnvFile(envLocation, testEnvLocation), resolveEnvFile(privateEnvLocation, testPrivateEnvLocation), resolveEnvFile(publicEnvLocation, testPublicEnvLocation)]);
|
|
56
|
-
|
|
56
|
+
// sequential, so later files override earlier ones consistently with prod (Framework.ts)
|
|
57
|
+
await tryLoadEnvFile('.env', envPath);
|
|
58
|
+
await tryLoadEnvFile('.env.private', privateEnvPath);
|
|
59
|
+
await tryLoadEnvFile('.env.public', publicEnvPath, 'TUNGSTEN_PUBLIC_');
|
|
57
60
|
if (_firstLoad && !someEnvLoaded) cliOut('No env files were loaded');
|
|
58
61
|
//console.log('check for schemas')
|
|
59
62
|
// If there are env schemas, load the relevant env and parse with schemas
|
|
@@ -62,14 +65,18 @@ iteration, initialProcessEnv, _firstLoad, useTestEnvFiles = false) {
|
|
|
62
65
|
// global.tungstenPrivateEnv = envSchemas.privateEnvSchema.parse(process.env)
|
|
63
66
|
const result = envSchemas.privateEnvSchema.safeParse(tempEnv);
|
|
64
67
|
if (!result.success) {
|
|
65
|
-
throwError('Your environment variables failed your privateEnvSchema validation', '\n' + JSON.stringify(result.error.format(), null, 4) + '\nenv: ' + JSON.stringify(tempEnv, null, 4)
|
|
68
|
+
throwError('Your environment variables failed your privateEnvSchema validation', '\n' + JSON.stringify(result.error.format(), null, 4) + '\nenv: ' + JSON.stringify(tempEnv, null, 4)
|
|
69
|
+
//+ '\nparsed env ' + JSON.stringify(tempEnv, null, 4)
|
|
70
|
+
);
|
|
66
71
|
}
|
|
67
72
|
const coreResult = tungstenCorePrivateEnvSchema.safeParse(result.data);
|
|
68
73
|
//console.log('coreResult', coreResult)
|
|
69
74
|
if (!coreResult.success) {
|
|
70
75
|
throwError('Your private environment variables don\'t meet the Tungsten requirements. Ensure your .env and privateEnvSchema provide an output meeting these requirements. You may need to coerce data to the correct type.',
|
|
71
76
|
// eslint-disable-line max-len
|
|
72
|
-
'\n' + JSON.stringify(coreResult.error.format(), null, 4) + '\nenv: ' + JSON.stringify(tempEnv, null, 4)
|
|
77
|
+
'\n' + JSON.stringify(coreResult.error.format(), null, 4) + '\nenv: ' + JSON.stringify(tempEnv, null, 4)
|
|
78
|
+
//+ '\nparsed env ' + JSON.stringify(tempEnv, null, 4)
|
|
79
|
+
);
|
|
73
80
|
}
|
|
74
81
|
global.tungstenPrivateEnv = result.data;
|
|
75
82
|
//console.log('global.tungstenPrivateEnv', global.tungstenPrivateEnv)
|
package/dist/Servers/routing.js
CHANGED
|
@@ -23,7 +23,7 @@ export async function routing(location, routes, serverDataLoading = null) {
|
|
|
23
23
|
let data = undefined;
|
|
24
24
|
if (route.data) {
|
|
25
25
|
if (serverDataLoading) serverDataLoading.value = true;
|
|
26
|
-
data = await route.data(params, location);
|
|
26
|
+
data = await route.data(params, location, match.query);
|
|
27
27
|
if (serverDataLoading) serverDataLoading.value = false;
|
|
28
28
|
}
|
|
29
29
|
//console.log('route data is', data)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"AAwCA,OAAO,EAAE,CAAA"}
|
package/dist/bin/commands/dev.js
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
import open from 'open';
|
|
2
2
|
import { cliOut } from "../../cliOutput.js";
|
|
3
3
|
import { Framework } from "../../Framework.js";
|
|
4
|
-
import dotenv from 'dotenv'
|
|
5
|
-
dotenv.config({
|
|
6
|
-
path: '.private.env'
|
|
7
|
-
});
|
|
4
|
+
//import dotenv from 'dotenv'
|
|
5
|
+
//dotenv.config({ path: '.private.env' })
|
|
8
6
|
cliOut(`Starting dev mode`);
|
|
9
7
|
//// prep the app
|
|
10
8
|
const sxyFramework = new Framework();
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { Framework } from "../../Framework.js";
|
|
2
|
-
import dotenv from 'dotenv'
|
|
3
|
-
dotenv.config({
|
|
4
|
-
path: '.private.env'
|
|
5
|
-
});
|
|
2
|
+
//import dotenv from 'dotenv'
|
|
3
|
+
//dotenv.config({ path: '.private.env' })
|
|
6
4
|
console.log('tungsten start');
|
|
7
5
|
//// prep the framework
|
|
8
6
|
const framework = new Framework();
|
package/dist/env/privateEnv.js
CHANGED
|
@@ -4,7 +4,7 @@ export function privateEnv(key) {
|
|
|
4
4
|
if (isClient) throw new Error('Error, tried to access privateEnv from client');
|
|
5
5
|
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
|
6
6
|
if (tungstenPrivateEnv === undefined) {
|
|
7
|
-
throwError('publicEnv', 'Tungsten Private Env is undefined - do you have a .env or .private
|
|
7
|
+
throwError('publicEnv', 'Tungsten Private Env is undefined - do you have a .env or .env.private file?');
|
|
8
8
|
}
|
|
9
9
|
return tungstenPrivateEnv[key];
|
|
10
10
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { privateEnv } from "./privateEnv.js";
|
|
2
2
|
export function privateEnvOrThrow(key) {
|
|
3
3
|
const v = privateEnv(key);
|
|
4
|
-
if (v === undefined) throw new Error(`${String(key)} is missing from .
|
|
4
|
+
if (v === undefined) throw new Error(`${String(key)} is missing from .env.private`);
|
|
5
5
|
return v;
|
|
6
6
|
}
|
package/dist/env/publicEnv.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { throwError } from "../throwError.js";
|
|
2
2
|
export function publicEnv(key) {
|
|
3
|
-
if (tungstenPublicEnv === undefined) throwError('publicEnv', 'Tungsten Public Env is undefined - do you have a .public
|
|
3
|
+
if (tungstenPublicEnv === undefined) throwError('publicEnv', 'Tungsten Public Env is undefined - do you have a .env.public file?');
|
|
4
4
|
return tungstenPublicEnv[key];
|
|
5
5
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { publicEnv } from "./publicEnv.js";
|
|
2
2
|
export function publicEnvOrThrow(key) {
|
|
3
3
|
const v = publicEnv(key);
|
|
4
|
-
if (v === undefined) throw new Error(`${String(key)} is missing from .public
|
|
4
|
+
if (v === undefined) throw new Error(`${String(key)} is missing from .env.public`);
|
|
5
5
|
return v;
|
|
6
6
|
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
2
2
|
//# sourceMappingURL=possibleEnvFiles.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"possibleEnvFiles.d.ts","sourceRoot":"","sources":["../src/possibleEnvFiles.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"possibleEnvFiles.d.ts","sourceRoot":"","sources":["../src/possibleEnvFiles.ts"],"names":[],"mappings":""}
|
package/dist/possibleEnvFiles.js
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export
|
|
1
|
+
export {};
|
|
2
|
+
//export const possibleEnvFiles = ['.env.js', '.private.env.js', '.public.env.js']
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
export type Match = {
|
|
2
2
|
pattern: string;
|
|
3
|
+
/** The full request string as received, including any query string and hash. */
|
|
3
4
|
request: string;
|
|
5
|
+
/** The path portion of the request only (query string and hash removed). */
|
|
6
|
+
pathname: string;
|
|
4
7
|
params: {
|
|
5
8
|
[key: string]: string;
|
|
6
9
|
};
|
|
10
|
+
/** Parsed query string parameters (empty object when there is no query string). */
|
|
11
|
+
query: {
|
|
12
|
+
[key: string]: string;
|
|
13
|
+
};
|
|
14
|
+
/** The hash fragment without the leading '#' (empty string when there is none). */
|
|
15
|
+
hash: string;
|
|
7
16
|
};
|
|
8
17
|
//# sourceMappingURL=Match.type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Match.type.d.ts","sourceRoot":"","sources":["../../src/routing/Match.type.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,KAAK,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;
|
|
1
|
+
{"version":3,"file":"Match.type.d.ts","sourceRoot":"","sources":["../../src/routing/Match.type.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,KAAK,GAAG;IAChB,OAAO,EAAE,MAAM,CAAA;IACf,gFAAgF;IAChF,OAAO,EAAE,MAAM,CAAA;IACf,4EAA4E;IAC5E,QAAQ,EAAE,MAAM,CAAA;IAChB,MAAM,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IACjC,mFAAmF;IACnF,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAChC,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAA;CACf,CAAA"}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { RoutingRedirect } from './RoutingRedirect.js';
|
|
2
2
|
import { WebRedirect } from './WebRedirect.js';
|
|
3
|
-
export type RouteDataFunction<Params extends object, DataType> = (params: Params, location: string
|
|
3
|
+
export type RouteDataFunction<Params extends object, DataType> = (params: Params, location: string, query: {
|
|
4
|
+
[key: string]: string;
|
|
5
|
+
}) => Promise<DataType | RoutingRedirect | WebRedirect>;
|
|
4
6
|
//# sourceMappingURL=RouteDataFunction.type.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"RouteDataFunction.type.d.ts","sourceRoot":"","sources":["../../src/routing/RouteDataFunction.type.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,MAAM,iBAAiB,CAAC,MAAM,SAAS,MAAM,EAAE,QAAQ,IACvD,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,QAAQ,GAAG,eAAe,GAAG,WAAW,CAAC,CAAA"}
|
|
1
|
+
{"version":3,"file":"RouteDataFunction.type.d.ts","sourceRoot":"","sources":["../../src/routing/RouteDataFunction.type.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAE9C,MAAM,MAAM,iBAAiB,CAAC,MAAM,SAAS,MAAM,EAAE,QAAQ,IACvD,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;CAAE,KAC9D,OAAO,CAAC,QAAQ,GAAG,eAAe,GAAG,WAAW,CAAC,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"matchPath.d.ts","sourceRoot":"","sources":["../../src/routing/matchPath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;
|
|
1
|
+
{"version":3,"file":"matchPath.d.ts","sourceRoot":"","sources":["../../src/routing/matchPath.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAA;AAM5C,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CAqE9E"}
|
|
@@ -1,10 +1,19 @@
|
|
|
1
1
|
import { compareRequestToRegex } from "./compareRequestToRegex.js";
|
|
2
2
|
import { patternToRegex } from "./patternToRegex.js";
|
|
3
|
+
import { splitRequest } from "./splitRequest.js";
|
|
3
4
|
export function matchPath(pattern, request) {
|
|
4
5
|
// pathToRegexp(path, keys?, options?)
|
|
5
6
|
// match(path)
|
|
6
7
|
// parse(path)
|
|
7
8
|
// compile(path)
|
|
9
|
+
// Match only the path portion of the request, like Express: strip the query
|
|
10
|
+
// string and hash fragment before testing against the anchored (^…$) regex.
|
|
11
|
+
// Otherwise a request like '/foo?bar=1' would never match the pattern '/foo'.
|
|
12
|
+
const {
|
|
13
|
+
pathname,
|
|
14
|
+
query,
|
|
15
|
+
hash
|
|
16
|
+
} = splitRequest(request);
|
|
8
17
|
const {
|
|
9
18
|
regex,
|
|
10
19
|
keys
|
|
@@ -14,13 +23,16 @@ export function matchPath(pattern, request) {
|
|
|
14
23
|
const {
|
|
15
24
|
success,
|
|
16
25
|
params
|
|
17
|
-
} = compareRequestToRegex(
|
|
26
|
+
} = compareRequestToRegex(pathname, regex, keys);
|
|
18
27
|
//console.log('regex', regex, 'keys', keys, 'success', success)
|
|
19
28
|
if (success) {
|
|
20
29
|
return {
|
|
21
30
|
pattern,
|
|
22
31
|
request,
|
|
23
|
-
|
|
32
|
+
pathname,
|
|
33
|
+
params,
|
|
34
|
+
query,
|
|
35
|
+
hash
|
|
24
36
|
};
|
|
25
37
|
}
|
|
26
38
|
return null;
|
|
@@ -15,4 +15,27 @@ describe('routing/matchPath()', ({
|
|
|
15
15
|
const match = matchPath('/foo/', '/foo');
|
|
16
16
|
expect(match).not.to.equal(null);
|
|
17
17
|
});
|
|
18
|
+
it(`matches /foo when the request has a query string`, () => {
|
|
19
|
+
const match = matchPath('/foo', '/foo?bar=1');
|
|
20
|
+
expect(match).not.to.equal(null);
|
|
21
|
+
expect(match.query).to.deep.equal({
|
|
22
|
+
bar: '1'
|
|
23
|
+
});
|
|
24
|
+
expect(match.pathname).to.equal('/foo');
|
|
25
|
+
});
|
|
26
|
+
it(`matches /foo when the request has a hash fragment`, () => {
|
|
27
|
+
const match = matchPath('/foo', '/foo#section');
|
|
28
|
+
expect(match).not.to.equal(null);
|
|
29
|
+
expect(match.hash).to.equal('section');
|
|
30
|
+
});
|
|
31
|
+
it(`matches a dynamic route with a query string and captures the param`, () => {
|
|
32
|
+
const match = matchPath('/leads/:id/details', '/leads/5/details?queue=1');
|
|
33
|
+
expect(match).not.to.equal(null);
|
|
34
|
+
expect(match.params).to.deep.equal({
|
|
35
|
+
id: '5'
|
|
36
|
+
});
|
|
37
|
+
expect(match.query).to.deep.equal({
|
|
38
|
+
queue: '1'
|
|
39
|
+
});
|
|
40
|
+
});
|
|
18
41
|
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export type SplitRequest = {
|
|
2
|
+
pathname: string;
|
|
3
|
+
query: {
|
|
4
|
+
[key: string]: string;
|
|
5
|
+
};
|
|
6
|
+
hash: string;
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Split an incoming request string into its path, query, and hash parts, the
|
|
10
|
+
* way a URL is structured: `/path?query#hash`. Only `pathname` should be used
|
|
11
|
+
* for route matching (query and hash are not part of the path).
|
|
12
|
+
*
|
|
13
|
+
* The hash is separated first because a URL's fragment can itself contain a
|
|
14
|
+
* '?' that is not a query delimiter (e.g. '/foo#a?b').
|
|
15
|
+
*/
|
|
16
|
+
export declare function splitRequest(request: string): SplitRequest;
|
|
17
|
+
//# sourceMappingURL=splitRequest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"splitRequest.d.ts","sourceRoot":"","sources":["../../src/routing/splitRequest.ts"],"names":[],"mappings":"AACA,MAAM,MAAM,YAAY,GAAG;IACvB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,CAAA;IAChC,IAAI,EAAE,MAAM,CAAA;CACf,CAAA;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CAwB1D"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Split an incoming request string into its path, query, and hash parts, the
|
|
3
|
+
* way a URL is structured: `/path?query#hash`. Only `pathname` should be used
|
|
4
|
+
* for route matching (query and hash are not part of the path).
|
|
5
|
+
*
|
|
6
|
+
* The hash is separated first because a URL's fragment can itself contain a
|
|
7
|
+
* '?' that is not a query delimiter (e.g. '/foo#a?b').
|
|
8
|
+
*/
|
|
9
|
+
export function splitRequest(request) {
|
|
10
|
+
let rest = request;
|
|
11
|
+
let hash = '';
|
|
12
|
+
let query = {};
|
|
13
|
+
const hashIndex = rest.indexOf('#');
|
|
14
|
+
if (hashIndex !== -1) {
|
|
15
|
+
hash = rest.slice(hashIndex + 1);
|
|
16
|
+
rest = rest.slice(0, hashIndex);
|
|
17
|
+
}
|
|
18
|
+
const queryIndex = rest.indexOf('?');
|
|
19
|
+
if (queryIndex !== -1) {
|
|
20
|
+
const search = rest.slice(queryIndex + 1);
|
|
21
|
+
rest = rest.slice(0, queryIndex);
|
|
22
|
+
query = Object.fromEntries(new URLSearchParams(search));
|
|
23
|
+
}
|
|
24
|
+
return {
|
|
25
|
+
pathname: rest,
|
|
26
|
+
query,
|
|
27
|
+
hash
|
|
28
|
+
};
|
|
29
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"splitRequest.sxyt.d.ts","sourceRoot":"","sources":["../../src/routing/splitRequest.sxyt.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe } from 'sxy-test-runner';
|
|
2
|
+
import { expect } from 'chai';
|
|
3
|
+
import { splitRequest } from "./splitRequest.js";
|
|
4
|
+
describe('routing/splitRequest()', ({
|
|
5
|
+
it
|
|
6
|
+
}) => {
|
|
7
|
+
it(`returns the path unchanged when there is no query or hash`, () => {
|
|
8
|
+
expect(splitRequest('/foo/bar')).to.deep.equal({
|
|
9
|
+
pathname: '/foo/bar',
|
|
10
|
+
query: {},
|
|
11
|
+
hash: ''
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
it(`splits off a query string and parses it`, () => {
|
|
15
|
+
expect(splitRequest('/foo?a=1&b=2')).to.deep.equal({
|
|
16
|
+
pathname: '/foo',
|
|
17
|
+
query: {
|
|
18
|
+
a: '1',
|
|
19
|
+
b: '2'
|
|
20
|
+
},
|
|
21
|
+
hash: ''
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
it(`splits off a hash fragment`, () => {
|
|
25
|
+
expect(splitRequest('/foo#section')).to.deep.equal({
|
|
26
|
+
pathname: '/foo',
|
|
27
|
+
query: {},
|
|
28
|
+
hash: 'section'
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
it(`splits off both query and hash`, () => {
|
|
32
|
+
expect(splitRequest('/foo?a=1#section')).to.deep.equal({
|
|
33
|
+
pathname: '/foo',
|
|
34
|
+
query: {
|
|
35
|
+
a: '1'
|
|
36
|
+
},
|
|
37
|
+
hash: 'section'
|
|
38
|
+
});
|
|
39
|
+
});
|
|
40
|
+
it(`does not treat a '?' inside the hash as a query delimiter`, () => {
|
|
41
|
+
expect(splitRequest('/foo#a?b')).to.deep.equal({
|
|
42
|
+
pathname: '/foo',
|
|
43
|
+
query: {},
|
|
44
|
+
hash: 'a?b'
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
});
|
package/package.json
CHANGED
package/dist/parseIni.d.ts
DELETED
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export declare function parseIni(content: string): Record<string, string>;
|
|
2
|
-
export declare function parseIniFile(file: string): Promise<Record<string, string>>;
|
|
3
|
-
export declare function parseIniFileSync(file: string): Record<string, string>;
|
|
4
|
-
//# sourceMappingURL=parseIni.d.ts.map
|
package/dist/parseIni.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"parseIni.d.ts","sourceRoot":"","sources":["../src/parseIni.ts"],"names":[],"mappings":"AAIA,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAEhE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAEhF;AAED,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAErE"}
|
package/dist/parseIni.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { promises as fsPromises, readFileSync } from 'fs';
|
|
2
|
-
import ini from 'ini';
|
|
3
|
-
export function parseIni(content) {
|
|
4
|
-
return ini.parse(content);
|
|
5
|
-
}
|
|
6
|
-
export async function parseIniFile(file) {
|
|
7
|
-
return parseIni(await fsPromises.readFile(file, 'utf-8'));
|
|
8
|
-
}
|
|
9
|
-
export function parseIniFileSync(file) {
|
|
10
|
-
return parseIni(readFileSync(file, 'utf-8'));
|
|
11
|
-
}
|