Skip to content

Commit

Permalink
feat(deno): support for custom allow permissions (#284)
Browse files Browse the repository at this point in the history
* feat(deno): support for custom `allow` permissions

* docs: add `deno.allow` documentation
  • Loading branch information
wellwelwel authored May 23, 2024
1 parent 8245cf4 commit 4e551f6
Show file tree
Hide file tree
Showing 7 changed files with 271 additions and 37 deletions.
6 changes: 6 additions & 0 deletions src/@types/poku.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@

import type { Configs as ListFilesConfigs } from './list-files.js';

export type DenoOptions = {
allow?: string[];
deny?: string[];
};

export type Configs = {
/**
* By setting `true`, **Poku** won't exit the process and will return the exit code (`0` or `1`).
Expand Down Expand Up @@ -93,6 +98,7 @@ export type Configs = {
* ```
*/
afterEach?: () => unknown | Promise<unknown>;
deno?: DenoOptions;
} & ListFilesConfigs;

/* c8 ignore stop */
21 changes: 20 additions & 1 deletion src/bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,18 @@
/* c8 ignore start */

import { escapeRegExp } from '../modules/list-files.js';
import { getArg, getLastParam, hasArg } from '../helpers/get-arg.js';
import {
// getAllArgs,
getArg,
getLastParam,
hasArg,
getSubArg,
} from '../helpers/get-arg.js';
import { kill, poku } from '../index.js';
import { platformIsValid } from '../helpers/get-runtime.js';
import { format } from '../helpers/format.js';

// Argument with values
const dirs =
(hasArg('include')
? getArg('include')?.split(',')
Expand All @@ -19,6 +26,13 @@ const killPort = getArg('kill-port');
const killRange = getArg('kill-range');
const killPID = getArg('kill-pid');
const concurrency = Number(getArg('concurrency')) || undefined;
const denoAllow = getSubArg('deno-allow');

// Multiple arguments with values or not
// TODO (Custom Args)
// const args = getAllArgs('arg');

// Argument exists
const parallel = hasArg('parallel');
const quiet = hasArg('quiet');
const debug = hasArg('debug');
Expand Down Expand Up @@ -64,6 +78,11 @@ if (hasArg('log-success'))
debug,
failFast,
concurrency,
// TODO (Custom Args)
// arguments: args.length > 0 ? args : undefined,
deno: {
allow: denoAllow,
},
});
})();

Expand Down
115 changes: 106 additions & 9 deletions src/helpers/get-arg.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,116 @@
/* c8 ignore start */
import process from 'node:process';

const [, , ...args] = process.argv;
const [, , ...processArgs] = process.argv;

export const getArg = (arg: string): string | undefined => {
const getArg = args.find((a) => a.startsWith(`--${arg}=`));
if (getArg) return getArg.split('=')?.[1] || undefined;
/**
* Gets the value of an argument.
*
* ---
*
* CLI arguments examples:
*
* ```sh
* command --arg=some # 'some'
* command --arg="" # ''
* command --arg # undefined
* ```
*/
export const getArg = (arg: string, prefix = '--'): string | undefined => {
const mountArg = processArgs.find((a) => a.startsWith(`${prefix}${arg}=`));
if (!mountArg) return undefined;

return undefined;
return mountArg.split('=')?.[1].replace(/''|""/, '');
};

export const hasArg = (arg: string): boolean =>
args.some((a) => a.startsWith(`--${arg}`));
/**
* Parses all arguments of an argument value.
*
* ---
*
* CLI arguments examples:
*
* ```sh
* command --arg='--sub=some' # ['--sub=some']
* command --arg='--sub=some, --sub2' # ['--sub=some', '--sub2']
* ```
*/
export const getSubArg = (arg: string, prefix = '--') => {
if (hasArg(arg) && !getArg(arg)?.[1]) return [];

export const getLastParam = (): string => {
return args[args.length - 1];
return processArgs
.find((a) => a.startsWith(`${prefix}${arg}=`))
?.split(`--${arg}=`)[1]
.split(',')
.map((a) => a.trim())
.filter((a) => a && !/''|""/.test(a));
};

/**
* Checks if an argument exists.
*
* ---
*
* CLI arguments examples:
*
* ```sh
* command --arg # true
* command # false
* ```
*/
export const hasArg = (arg: string, prefix = '--'): boolean =>
processArgs.some((a) => a.startsWith(`${prefix}${arg}`));

/**
* Gets the last param/value.
*
* CLI arguments examples:
*
* ```sh
* command --arg --arg2=some value # 'value'
* command value # 'value'
* command # undefined
* command --arg # undefined
* ```
*/
export const getLastParam = (prefix = '--'): string | undefined => {
const lastArg = processArgs[processArgs.length - 1];

if (!lastArg || lastArg.startsWith(prefix)) return undefined;

return lastArg;
};

// TODO (Custom Args)
// export const getAllArgs = (arg: string, prefix = '--'): string[] => {
// return processArgs
// .filter((a) => a.startsWith(`${prefix}${arg}=`) || a === `${prefix}${arg}`)
// .map((a) => {
// const [key, ...value] = a.split('=');
// return value.length > 0 ? value.join('=') : key;
// });
// };

// TODO (Custom Args)
// export const setArgs = (
// args: (string | Record<string, string>)[],
// options?: { prefix: string }
// ): string[] => {
// const customArgs: string[] = [];
// const prefix = options?.prefix || '';

// args.forEach((arg) => {
// if (!Array.isArray(arg) && typeof arg === 'object') {
// for (const key in arg) {
// customArgs.push(`${prefix}${key}=${arg[key]}`);
// }

// return;
// }

// customArgs.push(`${prefix}${arg}`);
// });

// return customArgs;
// };
/* c8 ignore stop */
24 changes: 15 additions & 9 deletions src/helpers/runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@ export const runner = (filename: string, configs?: Configs): string[] => {
if (runtime === 'bun') return ['bun'];

// Deno
if (runtime === 'deno')
return [
'deno',
'run',
'--allow-read', // Poku searches for all test files
'--allow-env', // Poku share the process.env with the `child_process`
'--allow-run', // Poku CLI
'--allow-net', // Create Service
];
if (runtime === 'deno') {
const denoAllow = configs?.deno?.allow
? configs.deno.allow
.map((allow) => (allow ? `--allow-${allow}` : ''))
.filter((allow) => allow)
: [
// Defaults
'--allow-read', // Poku searches for all test files
'--allow-env', // Poku share the process.env with the `child_process`
'--allow-run', // Poku CLI
'--allow-net', // Create Service
];

return ['deno', 'run', ...denoAllow];
}

// Node.js
return path.extname(filename) === '.ts'
Expand Down
65 changes: 65 additions & 0 deletions test/unit/deno/allow.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { assert, describe, test } from '../../../src/index.js';
import { runner } from '../../../src/helpers/runner.js';

describe('Deno Security Arguments', { background: false, icon: '🔬' });

test(() => {
assert.deepStrictEqual(
runner('', {
platform: 'deno',
}),
[
'deno',
'run',
'--allow-read',
'--allow-env',
'--allow-run',
'--allow-net',
],
'Default Permissions'
);

assert.deepStrictEqual(
runner('', {
platform: 'deno',
deno: {
allow: ['read'],
},
}),
['deno', 'run', '--allow-read'],
'Custom Permission'
);

assert.deepStrictEqual(
runner('', {
platform: 'deno',
deno: {
allow: ['read', 'env'],
},
}),
['deno', 'run', '--allow-read', '--allow-env'],
'Custom Permissions'
);

assert.deepStrictEqual(
runner('', {
platform: 'deno',
deno: {
allow: ['read="file.js"', 'env'],
},
}),
['deno', 'run', '--allow-read="file.js"', '--allow-env'],
'Custom Permissions per Files'
);

assert.deepStrictEqual(
runner('', {
platform: 'deno',
deno: {
allow: [],
},
}),
['deno', 'run'],
'No Permissions'
);
});
18 changes: 0 additions & 18 deletions tools/workflows/get-prs.ts

This file was deleted.

59 changes: 59 additions & 0 deletions website/docs/documentation/poku/options/deno.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
---
sidebar_position: 98
---

# `deno`

## `allow`

> `poku(targetPaths: string | string[], configs?: Configs)`
>
> `allow: string[]`
Change permissions for **Deno**.

By default **Poku** uses `--allow-run`, `--allow-env`, `--allow-read` and `--allow-net`.

### API (_in-code_)

```ts
poku(['...'], {
deno: {
allow: ['read', 'run' /* ... */],
},
});
```

```ts
poku(['...'], {
deno: {
allow: ['read=file.js', 'run' /* ... */],
},
});
```

Clear all permissions:

```ts
poku(['...'], {
deno: {
allow: [],
},
});
```

### CLI

```bash
npx poku --deno-allow='read, run' ./test
```

```bash
npx poku --deno-allow='read=file.js, run' ./test
```

Clear all permissions:

```bash
npx poku --deno-allow='' ./test
```

0 comments on commit 4e551f6

Please sign in to comment.