@ship.zone/szci 7.1.4 → 7.1.6
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/bin/szci-wrapper.js +67 -28
- package/changelog.md +17 -1
- package/deno.json +3 -3
- package/package.json +1 -1
- package/readme.md +10 -3
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/manager.nodejs/index.ts +1 -1
- package/ts/manager.npm/index.ts +38 -43
- package/ts/manager.npm/npmcredential.ts +91 -0
- package/ts/szci.classes.szciconfig.ts +5 -2
- package/ts/szci.plugins.ts +2 -3
package/bin/szci-wrapper.js
CHANGED
|
@@ -9,7 +9,7 @@ import { spawn } from 'child_process';
|
|
|
9
9
|
import { fileURLToPath } from 'url';
|
|
10
10
|
import { dirname, join } from 'path';
|
|
11
11
|
import { existsSync } from 'fs';
|
|
12
|
-
import {
|
|
12
|
+
import { arch, platform } from 'os';
|
|
13
13
|
|
|
14
14
|
const __filename = fileURLToPath(import.meta.url);
|
|
15
15
|
const __dirname = dirname(__filename);
|
|
@@ -25,12 +25,12 @@ function getBinaryName() {
|
|
|
25
25
|
const platformMap = {
|
|
26
26
|
'darwin': 'macos',
|
|
27
27
|
'linux': 'linux',
|
|
28
|
-
'win32': 'windows'
|
|
28
|
+
'win32': 'windows',
|
|
29
29
|
};
|
|
30
30
|
|
|
31
31
|
const archMap = {
|
|
32
32
|
'x64': 'x64',
|
|
33
|
-
'arm64': 'arm64'
|
|
33
|
+
'arm64': 'arm64',
|
|
34
34
|
};
|
|
35
35
|
|
|
36
36
|
const mappedPlatform = platformMap[plat];
|
|
@@ -61,12 +61,10 @@ function executeBinary() {
|
|
|
61
61
|
|
|
62
62
|
const denoSourcePath = join(__dirname, '..', 'mod.ts');
|
|
63
63
|
const denoConfigPath = join(__dirname, '..', 'deno.json');
|
|
64
|
-
const
|
|
65
|
-
const
|
|
66
|
-
? process.argv.slice(2)
|
|
67
|
-
: ['run', '--allow-all', '--config', denoConfigPath, denoSourcePath, ...process.argv.slice(2)];
|
|
64
|
+
const binaryExists = existsSync(binaryPath);
|
|
65
|
+
const sourceFallbackExists = existsSync(denoSourcePath) && existsSync(denoConfigPath);
|
|
68
66
|
|
|
69
|
-
if (!
|
|
67
|
+
if (!binaryExists && !sourceFallbackExists) {
|
|
70
68
|
console.error(`Error: Binary not found at ${binaryPath}`);
|
|
71
69
|
console.error(`Error: Deno source fallback not found at ${denoSourcePath}`);
|
|
72
70
|
console.error('Try reinstalling the package:');
|
|
@@ -75,35 +73,76 @@ function executeBinary() {
|
|
|
75
73
|
process.exit(1);
|
|
76
74
|
}
|
|
77
75
|
|
|
78
|
-
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
76
|
+
let activeChild;
|
|
77
|
+
const spawnCommand = (command, args, isStandaloneBinary) => {
|
|
78
|
+
const child = spawn(command, args, {
|
|
79
|
+
stdio: 'inherit',
|
|
80
|
+
shell: false,
|
|
81
|
+
});
|
|
82
|
+
activeChild = child;
|
|
83
83
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
});
|
|
84
|
+
child.on('error', (err) => {
|
|
85
|
+
console.error(`Error executing szci: ${err.message}`);
|
|
86
|
+
process.exit(1);
|
|
87
|
+
});
|
|
89
88
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
89
|
+
child.on('exit', (code, signal) => {
|
|
90
|
+
if (
|
|
91
|
+
isStandaloneBinary &&
|
|
92
|
+
signal === 'SIGILL' &&
|
|
93
|
+
sourceFallbackExists
|
|
94
|
+
) {
|
|
95
|
+
console.warn(
|
|
96
|
+
'SZCI standalone binary exited with SIGILL; retrying with the packaged Deno source fallback.',
|
|
97
|
+
);
|
|
98
|
+
spawnCommand(
|
|
99
|
+
'deno',
|
|
100
|
+
[
|
|
101
|
+
'run',
|
|
102
|
+
'--allow-all',
|
|
103
|
+
'--config',
|
|
104
|
+
denoConfigPath,
|
|
105
|
+
denoSourcePath,
|
|
106
|
+
...process.argv.slice(2),
|
|
107
|
+
],
|
|
108
|
+
false,
|
|
109
|
+
);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (signal) {
|
|
113
|
+
process.kill(process.pid, signal);
|
|
114
|
+
} else {
|
|
115
|
+
process.exit(code || 0);
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
};
|
|
97
119
|
|
|
98
120
|
// Forward signals to child process
|
|
99
121
|
const signals = ['SIGINT', 'SIGTERM', 'SIGHUP'];
|
|
100
|
-
signals.forEach(signal => {
|
|
122
|
+
signals.forEach((signal) => {
|
|
101
123
|
process.on(signal, () => {
|
|
102
|
-
if (!
|
|
103
|
-
|
|
124
|
+
if (activeChild && !activeChild.killed) {
|
|
125
|
+
activeChild.kill(signal);
|
|
104
126
|
}
|
|
105
127
|
});
|
|
106
128
|
});
|
|
129
|
+
|
|
130
|
+
if (binaryExists) {
|
|
131
|
+
spawnCommand(binaryPath, process.argv.slice(2), true);
|
|
132
|
+
} else {
|
|
133
|
+
spawnCommand(
|
|
134
|
+
'deno',
|
|
135
|
+
[
|
|
136
|
+
'run',
|
|
137
|
+
'--allow-all',
|
|
138
|
+
'--config',
|
|
139
|
+
denoConfigPath,
|
|
140
|
+
denoSourcePath,
|
|
141
|
+
...process.argv.slice(2),
|
|
142
|
+
],
|
|
143
|
+
false,
|
|
144
|
+
);
|
|
145
|
+
}
|
|
107
146
|
}
|
|
108
147
|
|
|
109
148
|
// Execute
|
package/changelog.md
CHANGED
|
@@ -1,7 +1,23 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
##
|
|
3
|
+
## 2026-07-28 - 7.1.6
|
|
4
4
|
|
|
5
|
+
### Fixes
|
|
6
|
+
|
|
7
|
+
- validate npm credentials before publishing (npm)
|
|
8
|
+
- Validate all SZCI_TOKEN_NPM values before logging or writing .npmrc
|
|
9
|
+
- Reject malformed registry, encoding, or token values without exposing credential input
|
|
10
|
+
- Await credential preparation and reuse the validated registry list during npm publish
|
|
11
|
+
- remove duplicate pending npm credential fix entries (changelog)
|
|
12
|
+
- Consolidate repeated pending fix bullets under the existing npm credential validation entry.
|
|
13
|
+
|
|
14
|
+
## 2026-07-28 - 7.1.5
|
|
15
|
+
|
|
16
|
+
### Fixes
|
|
17
|
+
|
|
18
|
+
- retry the packaged Deno source when the standalone binary exits with `SIGILL`
|
|
19
|
+
- Keeps the normal standalone path on supported CPUs.
|
|
20
|
+
- Recovers ARM64 CI environments that reject an incompatible executable instruction.
|
|
5
21
|
|
|
6
22
|
## 2026-05-20 - 7.1.4
|
|
7
23
|
|
package/deno.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ship.zone/szci",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.6",
|
|
4
4
|
"exports": "./mod.ts",
|
|
5
5
|
"nodeModulesDir": "auto",
|
|
6
6
|
"tasks": {
|
|
7
7
|
"dev": "deno run --allow-all mod.ts",
|
|
8
8
|
"compile": "deno task compile:all",
|
|
9
9
|
"compile:all": "bash scripts/compile-all.sh",
|
|
10
|
-
"test": "deno test --allow-all test
|
|
11
|
-
"test:watch": "deno test --allow-all --watch test
|
|
10
|
+
"test": "deno test --allow-all test/*.ts",
|
|
11
|
+
"test:watch": "deno test --allow-all --watch test/*.ts",
|
|
12
12
|
"check": "deno check mod.ts",
|
|
13
13
|
"fmt": "deno fmt",
|
|
14
14
|
"lint": "deno lint"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ship.zone/szci",
|
|
3
|
-
"version": "7.1.
|
|
3
|
+
"version": "7.1.6",
|
|
4
4
|
"description": "Serve Zone CI - A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities. Powered by Deno with standalone executables.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"Node.js",
|
package/readme.md
CHANGED
|
@@ -52,6 +52,10 @@ curl -sSL https://code.foss.global/ship.zone/szci/raw/branch/main/install.sh | s
|
|
|
52
52
|
npm install -g @ship.zone/szci
|
|
53
53
|
```
|
|
54
54
|
|
|
55
|
+
The normal pre-compiled path does not require a runtime. If a standalone executable terminates with
|
|
56
|
+
`SIGILL`, the npm wrapper automatically retries the packaged source and requires `deno` to be
|
|
57
|
+
available on `PATH`.
|
|
58
|
+
|
|
55
59
|
### From Source
|
|
56
60
|
|
|
57
61
|
```sh
|
|
@@ -128,7 +132,7 @@ szci node install 21 # Any specific version
|
|
|
128
132
|
Uses NVM under the hood (auto-detected at `/usr/local/nvm/nvm.sh` or `~/.nvm/nvm.sh`). After installing, it:
|
|
129
133
|
1. Sets the installed version as `nvm alias default`
|
|
130
134
|
2. Upgrades npm to latest
|
|
131
|
-
3. Installs any global tools listed in
|
|
135
|
+
3. Installs any global tools listed in `.smartconfig.json` → `npmGlobalTools`
|
|
132
136
|
|
|
133
137
|
### `szci ssh` — SSH Key Deployment
|
|
134
138
|
|
|
@@ -148,7 +152,7 @@ Pushes all branches and tags to a GitHub mirror. Requires `SZCI_GIT_GITHUBTOKEN`
|
|
|
148
152
|
|
|
149
153
|
## ⚙️ Configuration
|
|
150
154
|
|
|
151
|
-
###
|
|
155
|
+
### `.smartconfig.json`
|
|
152
156
|
|
|
153
157
|
Place this in your project root to configure szci behavior:
|
|
154
158
|
|
|
@@ -195,6 +199,9 @@ SZCI_TOKEN_NPM_1="registry.npmjs.org|dGhlLXRva2VuLWhlcmU="
|
|
|
195
199
|
SZCI_TOKEN_NPM_2="verdaccio.example.com|the-token-here|plain"
|
|
196
200
|
```
|
|
197
201
|
|
|
202
|
+
SZCI validates every configured npm credential before writing `.npmrc`. Malformed
|
|
203
|
+
registry, encoding, or token values fail without logging the credential.
|
|
204
|
+
|
|
198
205
|
### SSH Keys
|
|
199
206
|
|
|
200
207
|
Pipe-delimited format: `host|privKeyBase64|pubKeyBase64`
|
|
@@ -371,7 +378,7 @@ deno task lint
|
|
|
371
378
|
|
|
372
379
|
## License and Legal Information
|
|
373
380
|
|
|
374
|
-
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [
|
|
381
|
+
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license) file.
|
|
375
382
|
|
|
376
383
|
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
|
377
384
|
|
package/ts/00_commitinfo_data.ts
CHANGED
|
@@ -3,6 +3,6 @@
|
|
|
3
3
|
*/
|
|
4
4
|
export const commitinfo = {
|
|
5
5
|
name: '@ship.zone/szci',
|
|
6
|
-
version: '7.1.
|
|
6
|
+
version: '7.1.6',
|
|
7
7
|
description: 'Serve Zone CI - A tool to streamline Node.js and Docker workflows within CI environments, particularly GitLab CI, providing various CI/CD utilities. Powered by Deno with standalone executables.'
|
|
8
8
|
}
|
package/ts/manager.npm/index.ts
CHANGED
|
@@ -4,6 +4,11 @@ import * as paths from '../szci.paths.ts';
|
|
|
4
4
|
import { logger } from '../szci.logging.ts';
|
|
5
5
|
import { bash, bashNoError, nvmAvailable } from '../szci.bash.ts';
|
|
6
6
|
import { Szci } from '../szci.classes.szci.ts';
|
|
7
|
+
import {
|
|
8
|
+
type INpmCredential,
|
|
9
|
+
parseNpmCredentialEnvironment,
|
|
10
|
+
validateNpmRegistryUrl,
|
|
11
|
+
} from './npmcredential.ts';
|
|
7
12
|
|
|
8
13
|
export class SzciNpmManager {
|
|
9
14
|
public szciRef: Szci;
|
|
@@ -42,7 +47,7 @@ export class SzciNpmManager {
|
|
|
42
47
|
} else {
|
|
43
48
|
logger.log(
|
|
44
49
|
'info',
|
|
45
|
-
`>>szci npm ...<< cli arguments invalid... Please read the documentation
|
|
50
|
+
`>>szci npm ...<< cli arguments invalid... Please read the documentation.`,
|
|
46
51
|
);
|
|
47
52
|
Deno.exit(1);
|
|
48
53
|
}
|
|
@@ -51,66 +56,55 @@ export class SzciNpmManager {
|
|
|
51
56
|
/**
|
|
52
57
|
* authenticates npm with token from env var
|
|
53
58
|
*/
|
|
54
|
-
public async prepare() {
|
|
59
|
+
public async prepare(): Promise<INpmCredential[]> {
|
|
55
60
|
logger.log('info', 'running >>npm prepare<<');
|
|
56
61
|
const config = this.szciRef.szciConfig.getConfig();
|
|
57
|
-
|
|
58
|
-
await plugins.smartobject.forEachMinimatch(
|
|
62
|
+
const npmCredentials = parseNpmCredentialEnvironment(
|
|
59
63
|
Deno.env.toObject(),
|
|
60
|
-
'SZCI_TOKEN_NPM*',
|
|
61
|
-
(npmEnvArg: string) => {
|
|
62
|
-
if (!npmEnvArg) {
|
|
63
|
-
logger.log('note','found empty token...');
|
|
64
|
-
return;
|
|
65
|
-
}
|
|
66
|
-
const npmRegistryUrl = npmEnvArg.split('|')[0];
|
|
67
|
-
logger.log('ok', `found token for ${npmRegistryUrl}`);
|
|
68
|
-
let npmToken = npmEnvArg.split('|')[1];
|
|
69
|
-
if (npmEnvArg.split('|')[2] && npmEnvArg.split('|')[2] === 'plain') {
|
|
70
|
-
logger.log('ok', 'npm token not base64 encoded.');
|
|
71
|
-
} else {
|
|
72
|
-
logger.log('ok', 'npm token base64 encoded.');
|
|
73
|
-
npmToken = plugins.smartstring.base64.decode(npmToken);
|
|
74
|
-
}
|
|
75
|
-
npmrcFileString += `//${npmRegistryUrl}/:_authToken="${npmToken}"\n`;
|
|
76
|
-
}
|
|
77
64
|
);
|
|
78
|
-
|
|
79
|
-
|
|
65
|
+
if (npmCredentials.length === 0) {
|
|
66
|
+
throw new Error('No SZCI_TOKEN_NPM credentials were provided.');
|
|
67
|
+
}
|
|
80
68
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
logger.log('
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
69
|
+
let npmrcFileString: string = '';
|
|
70
|
+
for (const npmCredential of npmCredentials) {
|
|
71
|
+
logger.log('ok', `found token for ${npmCredential.registryUrl}`);
|
|
72
|
+
logger.log(
|
|
73
|
+
'ok',
|
|
74
|
+
npmCredential.tokenEncoding === 'plain'
|
|
75
|
+
? 'npm token not base64 encoded.'
|
|
76
|
+
: 'npm token base64 encoded.',
|
|
77
|
+
);
|
|
78
|
+
npmrcFileString += `//${npmCredential.registryUrl}/:_authToken="${npmCredential.token}"\n`;
|
|
87
79
|
}
|
|
88
80
|
|
|
81
|
+
const defaultRegistryUrl = validateNpmRegistryUrl(config.npmRegistryUrl);
|
|
82
|
+
logger.log('info', `setting default npm registry to ${defaultRegistryUrl}`);
|
|
83
|
+
npmrcFileString += `registry=https://${defaultRegistryUrl}\n`;
|
|
84
|
+
logger.log('info', 'found one or more access tokens');
|
|
85
|
+
|
|
89
86
|
// lets save it to disk
|
|
90
87
|
plugins.smartfile.memory.toFsSync(npmrcFileString, '/root/.npmrc');
|
|
91
88
|
|
|
92
89
|
// lets set the cache directory
|
|
93
90
|
await bash(`npm config set cache ${paths.SzciCacheDir} --global `);
|
|
94
91
|
|
|
95
|
-
return;
|
|
92
|
+
return npmCredentials;
|
|
96
93
|
}
|
|
97
94
|
|
|
98
95
|
/**
|
|
99
96
|
* publish a package to npm
|
|
100
97
|
*/
|
|
101
98
|
public async publish() {
|
|
102
|
-
const buildPublishCommand = async (
|
|
99
|
+
const buildPublishCommand = async (
|
|
100
|
+
npmCredentialsArg: INpmCredential[],
|
|
101
|
+
) => {
|
|
103
102
|
let npmAccessCliString = ``;
|
|
104
103
|
let npmRegistryCliString = ``;
|
|
105
104
|
let publishVerdaccioAsWell = false;
|
|
106
105
|
const config = this.szciRef.szciConfig.getConfig();
|
|
107
|
-
const availableRegistries
|
|
108
|
-
|
|
109
|
-
Deno.env.toObject(),
|
|
110
|
-
'SZCI_TOKEN_NPM*',
|
|
111
|
-
(npmEnvArg: string) => {
|
|
112
|
-
availableRegistries.push(npmEnvArg.split('|')[0]);
|
|
113
|
-
}
|
|
106
|
+
const availableRegistries = npmCredentialsArg.map(
|
|
107
|
+
(npmCredentialArg) => npmCredentialArg.registryUrl,
|
|
114
108
|
);
|
|
115
109
|
|
|
116
110
|
// -> configure package access level
|
|
@@ -140,13 +134,14 @@ export class SzciNpmManager {
|
|
|
140
134
|
if (verdaccioRegistry) {
|
|
141
135
|
logger.log(
|
|
142
136
|
'info',
|
|
143
|
-
`package is public and verdaccio registry is specified. Also publishing to Verdaccio
|
|
137
|
+
`package is public and verdaccio registry is specified. Also publishing to Verdaccio!`,
|
|
144
138
|
);
|
|
145
|
-
publishCommand =
|
|
139
|
+
publishCommand =
|
|
140
|
+
`${publishCommand} && npm publish ${npmAccessCliString} --registry=https://${verdaccioRegistry}`;
|
|
146
141
|
} else {
|
|
147
142
|
logger.log(
|
|
148
143
|
'error',
|
|
149
|
-
`This package should also be published to Verdaccio, however there is no Verdaccio registry data available
|
|
144
|
+
`This package should also be published to Verdaccio, however there is no Verdaccio registry data available!`,
|
|
150
145
|
);
|
|
151
146
|
}
|
|
152
147
|
}
|
|
@@ -155,7 +150,7 @@ export class SzciNpmManager {
|
|
|
155
150
|
|
|
156
151
|
// -> preparing
|
|
157
152
|
logger.log('info', `now preparing environment:`);
|
|
158
|
-
this.prepare();
|
|
153
|
+
const npmCredentials = await this.prepare();
|
|
159
154
|
await bash(`npm -v`);
|
|
160
155
|
await bash(`pnpm -v`);
|
|
161
156
|
|
|
@@ -173,7 +168,7 @@ export class SzciNpmManager {
|
|
|
173
168
|
|
|
174
169
|
// -> publish it
|
|
175
170
|
logger.log('info', `now invoking npm to publish the package!`);
|
|
176
|
-
await bash(await buildPublishCommand());
|
|
171
|
+
await bash(await buildPublishCommand(npmCredentials));
|
|
177
172
|
logger.log('success', `Package was successfully published!`);
|
|
178
173
|
}
|
|
179
174
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import * as plugins from './mod.plugins.ts';
|
|
2
|
+
|
|
3
|
+
export interface INpmCredential {
|
|
4
|
+
registryUrl: string;
|
|
5
|
+
token: string;
|
|
6
|
+
tokenEncoding: 'base64' | 'plain';
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
const invalidCredentialError = () =>
|
|
10
|
+
new Error(
|
|
11
|
+
'Invalid SZCI_TOKEN_NPM credential. Expected registry|token[|plain].',
|
|
12
|
+
);
|
|
13
|
+
|
|
14
|
+
const registryUrlRegex = /^[A-Za-z0-9](?:[A-Za-z0-9.-]*[A-Za-z0-9])?(?::[0-9]{1,5})?$/;
|
|
15
|
+
const unsafeTokenRegex = /[\u0000-\u001f\u007f"\\]/;
|
|
16
|
+
|
|
17
|
+
export const validateNpmRegistryUrl = (registryUrlArg: string): string => {
|
|
18
|
+
if (
|
|
19
|
+
!registryUrlArg ||
|
|
20
|
+
registryUrlArg.length > 512 ||
|
|
21
|
+
!registryUrlRegex.test(registryUrlArg)
|
|
22
|
+
) {
|
|
23
|
+
throw invalidCredentialError();
|
|
24
|
+
}
|
|
25
|
+
return registryUrlArg;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export const parseNpmCredential = (
|
|
29
|
+
npmEnvironmentValueArg: string,
|
|
30
|
+
): INpmCredential => {
|
|
31
|
+
const fields = npmEnvironmentValueArg.split('|');
|
|
32
|
+
if (fields.length < 2 || fields.length > 3) {
|
|
33
|
+
throw invalidCredentialError();
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const registryUrl = validateNpmRegistryUrl(fields[0]);
|
|
37
|
+
const encodedToken = fields[1];
|
|
38
|
+
const encodingMarker = fields[2];
|
|
39
|
+
if (
|
|
40
|
+
!encodedToken ||
|
|
41
|
+
(encodingMarker !== undefined && encodingMarker !== 'plain')
|
|
42
|
+
) {
|
|
43
|
+
throw invalidCredentialError();
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
let token: string;
|
|
47
|
+
let tokenEncoding: INpmCredential['tokenEncoding'];
|
|
48
|
+
if (encodingMarker === 'plain') {
|
|
49
|
+
token = encodedToken;
|
|
50
|
+
tokenEncoding = 'plain';
|
|
51
|
+
} else {
|
|
52
|
+
if (!plugins.smartstring.base64.isBase64(encodedToken)) {
|
|
53
|
+
throw invalidCredentialError();
|
|
54
|
+
}
|
|
55
|
+
token = plugins.smartstring.base64.decode(encodedToken);
|
|
56
|
+
if (plugins.smartstring.base64.encode(token) !== encodedToken) {
|
|
57
|
+
throw invalidCredentialError();
|
|
58
|
+
}
|
|
59
|
+
tokenEncoding = 'base64';
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (
|
|
63
|
+
!token ||
|
|
64
|
+
token.length > 65536 ||
|
|
65
|
+
unsafeTokenRegex.test(token) ||
|
|
66
|
+
token.includes('${')
|
|
67
|
+
) {
|
|
68
|
+
throw invalidCredentialError();
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
registryUrl,
|
|
73
|
+
token,
|
|
74
|
+
tokenEncoding,
|
|
75
|
+
};
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
export const parseNpmCredentialEnvironment = (
|
|
79
|
+
environmentArg: Record<string, string>,
|
|
80
|
+
): INpmCredential[] => {
|
|
81
|
+
const credentialValues = Object.entries(environmentArg)
|
|
82
|
+
.filter(([environmentVariableNameArg]) =>
|
|
83
|
+
environmentVariableNameArg.startsWith('SZCI_TOKEN_NPM')
|
|
84
|
+
)
|
|
85
|
+
.sort(([environmentVariableNameA], [environmentVariableNameB]) =>
|
|
86
|
+
environmentVariableNameA.localeCompare(environmentVariableNameB)
|
|
87
|
+
)
|
|
88
|
+
.map(([, environmentVariableValueArg]) => environmentVariableValueArg);
|
|
89
|
+
|
|
90
|
+
return credentialValues.map((credentialValueArg) => parseNpmCredential(credentialValueArg));
|
|
91
|
+
};
|
|
@@ -44,7 +44,7 @@ export class SzciConfig {
|
|
|
44
44
|
this.szciQenv = new plugins.qenv.Qenv(
|
|
45
45
|
paths.SzciProjectDir,
|
|
46
46
|
paths.SzciProjectNogitDir,
|
|
47
|
-
false
|
|
47
|
+
false,
|
|
48
48
|
);
|
|
49
49
|
|
|
50
50
|
this.configObject = {
|
|
@@ -54,7 +54,10 @@ export class SzciConfig {
|
|
|
54
54
|
npmRegistryUrl: 'registry.npmjs.org',
|
|
55
55
|
urlCloudly: await this.szciQenv.getEnvVarOnDemand('SZCI_URL_CLOUDLY'),
|
|
56
56
|
};
|
|
57
|
-
this.configObject = this.szciSmartconfig.dataFor<ISzciOptions>(
|
|
57
|
+
this.configObject = this.szciSmartconfig.dataFor<ISzciOptions>(
|
|
58
|
+
'@ship.zone/szci',
|
|
59
|
+
this.configObject,
|
|
60
|
+
);
|
|
58
61
|
}
|
|
59
62
|
|
|
60
63
|
public getConfig(): ISzciOptions {
|
package/ts/szci.plugins.ts
CHANGED
|
@@ -36,10 +36,10 @@ export {
|
|
|
36
36
|
projectinfo,
|
|
37
37
|
qenv,
|
|
38
38
|
smartanalytics,
|
|
39
|
-
smartfile,
|
|
40
|
-
smartgit,
|
|
41
39
|
smartcli,
|
|
42
40
|
smartconfig,
|
|
41
|
+
smartfile,
|
|
42
|
+
smartgit,
|
|
43
43
|
smartlog,
|
|
44
44
|
smartlogDestinationLocal,
|
|
45
45
|
smartobject,
|
|
@@ -56,4 +56,3 @@ export {
|
|
|
56
56
|
import * as tsclass from '@tsclass/tsclass';
|
|
57
57
|
|
|
58
58
|
export { tsclass };
|
|
59
|
-
|