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 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 { parseIni } from "./parseIni.js";
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 = parseIni(readFileSync(filePath, 'utf-8'));
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,iBAuH1B"}
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 { parseIni } from "../parseIni.js";
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 = parseIni(await readFilePromise(filePath, 'utf-8'));
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
- await Promise.all([tryLoadEnvFile('.env', envPath), tryLoadEnvFile('.env.private', privateEnvPath), tryLoadEnvFile('.env.public', publicEnvPath, 'TUNGSTEN_PUBLIC_')]);
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) + '\nparsed env ' + 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) + '\nparsed env ' + 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)
@@ -1,3 +1,3 @@
1
1
  export function portError(port) {
2
- return `Invalid port: '${port}'. Did you specify 'TUNGSTEN_SERVER_PORT' in .env, .private.env or .public.env?`;
2
+ return `Invalid port: '${port}'. Did you specify 'TUNGSTEN_SERVER_PORT' in .env, .env.private or .env.public?`;
3
3
  }
@@ -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":"AAuCA,OAAO,EAAE,CAAA"}
1
+ {"version":3,"file":"dev.d.ts","sourceRoot":"","sources":["../../../src/bin/commands/dev.ts"],"names":[],"mappings":"AAwCA,OAAO,EAAE,CAAA"}
@@ -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();
@@ -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.env file?');
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 .public.env`);
4
+ if (v === undefined) throw new Error(`${String(key)} is missing from .env.private`);
5
5
  return v;
6
6
  }
@@ -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.env file?');
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.env`);
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 declare const possibleEnvFiles: string[];
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":"AACA,eAAO,MAAM,gBAAgB,UAAmD,CAAA"}
1
+ {"version":3,"file":"possibleEnvFiles.d.ts","sourceRoot":"","sources":["../src/possibleEnvFiles.ts"],"names":[],"mappings":""}
@@ -1 +1,2 @@
1
- export const possibleEnvFiles = ['.env.js', '.private.env.js', '.public.env.js'];
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;CACpC,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) => Promise<DataType | RoutingRedirect | WebRedirect>;
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;AAK5C,wBAAgB,SAAS,CAAC,OAAO,EAAE,IAAI,MAAM,EAAE,EAAE,OAAO,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI,CA6D9E"}
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(request, regex, keys);
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
- params
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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=splitRequest.sxyt.d.ts.map
@@ -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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tungsten",
3
- "version": "0.2.11",
3
+ "version": "0.2.13",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "bin": {
@@ -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
@@ -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
- }