@carecard/auth-util 3.17.0 → 3.18.0
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/package.json
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@carecard/auth-util",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.18.0",
|
|
4
4
|
"repository": "https://github.com/CareCard-ca/pkg-auth-util.git",
|
|
5
5
|
"description": "Auth utility functions",
|
|
6
6
|
"main": "index.js",
|
|
7
7
|
"types": "index.d.ts",
|
|
8
8
|
"scripts": {
|
|
9
|
-
"test": "
|
|
10
|
-
"test:order": "node --test scripts/testOrder/randomizeTestOrder.test.mjs scripts/testOrder/testOrderPolicy.test.mjs scripts/testParallel/runIndexedMochaTests.test.mjs scripts/testParallel/parallelTestPolicy.test.mjs",
|
|
11
|
-
"test:types": "
|
|
12
|
-
"test:coverage": "
|
|
13
|
-
"test:All": "
|
|
9
|
+
"test": "node scripts/runPackageTask.mjs test",
|
|
10
|
+
"test:order": "node --test scripts/testOrder/randomizeTestOrder.test.mjs scripts/testOrder/testOrderPolicy.test.mjs scripts/testParallel/runIndexedMochaTests.test.mjs scripts/testParallel/parallelTestPolicy.test.mjs scripts/packageTaskRunner.test.mjs",
|
|
11
|
+
"test:types": "node scripts/runPackageTask.mjs test:types",
|
|
12
|
+
"test:coverage": "node scripts/runPackageTask.mjs test:coverage",
|
|
13
|
+
"test:All": "node scripts/runPackageTask.mjs test:All",
|
|
14
14
|
"format": "prettier --write .",
|
|
15
15
|
"format:check": "prettier --check .",
|
|
16
16
|
"prepare": "husky",
|
|
@@ -42,8 +42,8 @@
|
|
|
42
42
|
"typescript": "6.0.3"
|
|
43
43
|
},
|
|
44
44
|
"dependencies": {
|
|
45
|
-
"@carecard/common-util": "3.
|
|
46
|
-
"@carecard/validate": "3.
|
|
45
|
+
"@carecard/common-util": "3.18.0",
|
|
46
|
+
"@carecard/validate": "3.18.0",
|
|
47
47
|
"@types/express": "5.0.6"
|
|
48
48
|
},
|
|
49
49
|
"overrides": {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import assert from 'node:assert/strict';
|
|
2
|
+
import { readFileSync } from 'node:fs';
|
|
3
|
+
import test from 'node:test';
|
|
4
|
+
|
|
5
|
+
const packageJson = JSON.parse(readFileSync(new URL('../package.json', import.meta.url), 'utf8'));
|
|
6
|
+
const composedCommandPattern = /&&|\|\||\bsh -c\b|\bnode -e\b/u;
|
|
7
|
+
const runnerCommandPattern = /^node scripts\/runPackageTask\.mjs ([A-Za-z0-9:_-]+)$/u;
|
|
8
|
+
|
|
9
|
+
async function loadPackageTaskRunner() {
|
|
10
|
+
return import(new URL('./runPackageTask.mjs', import.meta.url));
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
test('delegates composed package tasks to the repository runner', async () => {
|
|
14
|
+
const runnerCommands = Object.entries(packageJson.scripts ?? {}).filter(([, command]) => runnerCommandPattern.test(command));
|
|
15
|
+
|
|
16
|
+
for (const [scriptName, command] of Object.entries(packageJson.scripts ?? {})) {
|
|
17
|
+
assert.doesNotMatch(command, composedCommandPattern, `${scriptName} must delegate composition to runPackageTask.mjs`);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
assert.ok(runnerCommands.length > 0, 'at least one package task must use the runner');
|
|
21
|
+
const { packageTasks } = await loadPackageTaskRunner();
|
|
22
|
+
for (const [scriptName] of runnerCommands) {
|
|
23
|
+
assert.ok(packageTasks[scriptName], `${scriptName} must have a runner task`);
|
|
24
|
+
}
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('runs task steps in order and stops at the first failure', async () => {
|
|
28
|
+
const { runPackageTask } = await loadPackageTaskRunner();
|
|
29
|
+
const executedCommands = [];
|
|
30
|
+
const fixtureTasks = {
|
|
31
|
+
fixture: [{ command: 'first' }, { command: 'second' }, { command: 'third' }],
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const exitCode = runPackageTask(
|
|
35
|
+
'fixture',
|
|
36
|
+
step => {
|
|
37
|
+
executedCommands.push(step.command);
|
|
38
|
+
return step.command === 'second' ? 7 : 0;
|
|
39
|
+
},
|
|
40
|
+
fixtureTasks,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
assert.equal(exitCode, 7);
|
|
44
|
+
assert.deepEqual(executedCommands, ['first', 'second']);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
test('runs conditional steps only when their required output is missing', async () => {
|
|
48
|
+
const { runPackageTask } = await loadPackageTaskRunner();
|
|
49
|
+
const executedCommands = [];
|
|
50
|
+
const fixtureTasks = {
|
|
51
|
+
fixture: [{ command: 'build', whenMissing: 'dist/runtime.js' }, { command: 'execute' }],
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const exitCode = runPackageTask(
|
|
55
|
+
'fixture',
|
|
56
|
+
step => {
|
|
57
|
+
executedCommands.push(step.command);
|
|
58
|
+
return 0;
|
|
59
|
+
},
|
|
60
|
+
fixtureTasks,
|
|
61
|
+
() => true,
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
assert.equal(exitCode, 0);
|
|
65
|
+
assert.deepEqual(executedCommands, ['execute']);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('does not suppress command execution errors at the CLI boundary', () => {
|
|
69
|
+
const runnerSource = readFileSync(new URL('./runPackageTask.mjs', import.meta.url), 'utf8');
|
|
70
|
+
|
|
71
|
+
assert.doesNotMatch(runnerSource, /catch\s*\{/u);
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
test('merges task environment overrides without mutating inherited values', async () => {
|
|
75
|
+
const { createTaskEnvironment } = await loadPackageTaskRunner();
|
|
76
|
+
const inheritedEnvironment = { NODE_ENV: 'test', PATH: '/bin' };
|
|
77
|
+
|
|
78
|
+
const environment = createTaskEnvironment({ NODE_ENV: 'production', DB_ENV: 'privileged' }, inheritedEnvironment);
|
|
79
|
+
|
|
80
|
+
assert.deepEqual(environment, {
|
|
81
|
+
NODE_ENV: 'production',
|
|
82
|
+
PATH: '/bin',
|
|
83
|
+
DB_ENV: 'privileged',
|
|
84
|
+
});
|
|
85
|
+
assert.deepEqual(inheritedEnvironment, { NODE_ENV: 'test', PATH: '/bin' });
|
|
86
|
+
});
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import { existsSync, rmSync } from 'node:fs';
|
|
3
|
+
import { resolve } from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
|
|
6
|
+
export const packageTasks = Object.freeze({
|
|
7
|
+
test: [
|
|
8
|
+
{ command: 'npm', arguments: ['run', 'test:order'] },
|
|
9
|
+
{ command: 'node', arguments: ['test/index.test.js'] },
|
|
10
|
+
],
|
|
11
|
+
'test:types': [
|
|
12
|
+
{ command: 'npm', arguments: ['run', 'test:order'] },
|
|
13
|
+
{ command: 'tsc', arguments: ['--noEmit'] },
|
|
14
|
+
{
|
|
15
|
+
command: 'mocha',
|
|
16
|
+
arguments: ['--require', './scripts/testOrder/randomizeTestOrder.cjs', '-r', 'ts-node/register', 'test/types.test.ts'],
|
|
17
|
+
},
|
|
18
|
+
],
|
|
19
|
+
'test:coverage': [
|
|
20
|
+
{ command: 'npm', arguments: ['run', 'test:order'] },
|
|
21
|
+
{ command: 'tsc', arguments: ['--noEmit'] },
|
|
22
|
+
{ command: 'nyc', arguments: ['node', 'test/index.test.js'] },
|
|
23
|
+
],
|
|
24
|
+
'test:All': [
|
|
25
|
+
{ command: 'npm', arguments: ['run', 'test'] },
|
|
26
|
+
{ command: 'npm', arguments: ['run', 'test:types'] },
|
|
27
|
+
],
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
export function createTaskEnvironment(overrides = {}, inheritedEnvironment = process.env) {
|
|
31
|
+
return { ...inheritedEnvironment, ...overrides };
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getTaskExitCode(result) {
|
|
35
|
+
if (result.error) throw result.error;
|
|
36
|
+
if (typeof result.status === 'number') return result.status;
|
|
37
|
+
if (result.signal === 'SIGINT') return 130;
|
|
38
|
+
if (result.signal === 'SIGTERM') return 143;
|
|
39
|
+
return 1;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function executeTaskStep(taskStep) {
|
|
43
|
+
if (taskStep.removePath) {
|
|
44
|
+
rmSync(taskStep.removePath, { recursive: true, force: true });
|
|
45
|
+
return 0;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const result = spawnSync(taskStep.command, taskStep.arguments ?? [], {
|
|
49
|
+
env: createTaskEnvironment(taskStep.environment),
|
|
50
|
+
shell: false,
|
|
51
|
+
stdio: 'inherit',
|
|
52
|
+
});
|
|
53
|
+
return getTaskExitCode(result);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function shouldRunTaskStep(taskStep, pathExists) {
|
|
57
|
+
return !taskStep.whenMissing || !pathExists(taskStep.whenMissing);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function runPackageTask(taskName, executeTask = executeTaskStep, taskDefinitions = packageTasks, pathExists = existsSync) {
|
|
61
|
+
const taskSteps = taskDefinitions[taskName];
|
|
62
|
+
if (!Array.isArray(taskSteps)) throw new Error('Unknown package task.');
|
|
63
|
+
|
|
64
|
+
for (const taskStep of taskSteps) {
|
|
65
|
+
if (!shouldRunTaskStep(taskStep, pathExists)) continue;
|
|
66
|
+
const exitCode = executeTask(taskStep);
|
|
67
|
+
if (exitCode !== 0) return exitCode;
|
|
68
|
+
}
|
|
69
|
+
return 0;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
function isDirectExecution() {
|
|
73
|
+
if (!process.argv[1]) return false;
|
|
74
|
+
return resolve(process.argv[1]) === fileURLToPath(import.meta.url);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
function runCommandLineTask() {
|
|
78
|
+
const taskName = process.argv[2];
|
|
79
|
+
if (!taskName || !packageTasks[taskName]) {
|
|
80
|
+
process.stderr.write('[PACKAGE_TASK_CONFIG] Unknown package task.\n');
|
|
81
|
+
process.exitCode = 2;
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
process.exitCode = runPackageTask(taskName);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
if (isDirectExecution()) runCommandLineTask();
|
|
@@ -7,6 +7,7 @@ import test from 'node:test';
|
|
|
7
7
|
const require = createRequire(import.meta.url);
|
|
8
8
|
const repositoryRoot = resolve(import.meta.dirname, '../..');
|
|
9
9
|
const packageJson = JSON.parse(readFileSync(new URL('../../package.json', import.meta.url), 'utf8'));
|
|
10
|
+
const packageTaskRunnerSource = readFileSync(new URL('../runPackageTask.mjs', import.meta.url), 'utf8');
|
|
10
11
|
const testIndexSource = readFileSync(new URL('../../test/index.test.js', import.meta.url), 'utf8');
|
|
11
12
|
const { parallelTestFiles } = require('../../test/index.test.js');
|
|
12
13
|
|
|
@@ -22,8 +23,11 @@ function listRuntimeTestFiles(directoryPath) {
|
|
|
22
23
|
}
|
|
23
24
|
|
|
24
25
|
test('keeps runtime test selection in the index and package scripts short', () => {
|
|
25
|
-
assert.equal(packageJson.scripts.test, '
|
|
26
|
-
assert.
|
|
26
|
+
assert.equal(packageJson.scripts.test, 'node scripts/runPackageTask.mjs test');
|
|
27
|
+
assert.equal(packageJson.scripts['test:coverage'], 'node scripts/runPackageTask.mjs test:coverage');
|
|
28
|
+
assert.match(packageTaskRunnerSource, /arguments: \['run', 'test:order'\]/);
|
|
29
|
+
assert.match(packageTaskRunnerSource, /arguments: \['test\/index\.test\.js'\]/);
|
|
30
|
+
assert.match(packageTaskRunnerSource, /command: 'nyc'/);
|
|
27
31
|
assert.match(testIndexSource, /parallelTestFiles/);
|
|
28
32
|
assert.match(testIndexSource, /runIndexedMochaTests/);
|
|
29
33
|
assert.match(testIndexSource, /if \(require\.main === module\)/);
|