@gen3/toolsff 0.10.44

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.
@@ -0,0 +1,199 @@
1
+ import { existsSync, readFileSync, writeFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import { parseArgs } from 'node:util';
4
+ import tinycolor from 'tinycolor2';
5
+
6
+ const DEFAULT_NUM_DARK_COLORS = 4;
7
+ const DEFAULT_NUM_LIGHT_COLORS = 4;
8
+ const errorColor = tinycolor('#ffffffff');
9
+ const CONTRAST_RANGE = [
10
+ '#111111',
11
+ '#FEFEFE'
12
+ ];
13
+ const mix = (startColor, mixinColor, weight)=>{
14
+ if (!mixinColor || !mixinColor.isValid()) {
15
+ throw new Error('Argument to "mix" was not a Color instance, but rather an instance of ' + typeof mixinColor);
16
+ }
17
+ const color1 = mixinColor;
18
+ const p = weight === undefined ? 0.5 : weight;
19
+ const w = 2 * p - 1;
20
+ const a = color1.getAlpha() - startColor.getAlpha();
21
+ const w1 = ((w * a === -1 ? w : (w + a) / (1 + w * a)) + 1) / 2;
22
+ const w2 = 1 - w1;
23
+ return tinycolor.fromRatio({
24
+ r: w1 * color1.toRgb().r + w2 * startColor.toRgb().r,
25
+ g: w1 * color1.toRgb().g + w2 * startColor.toRgb().g,
26
+ b: w1 * color1.toRgb().b + w2 * startColor.toRgb().b,
27
+ a: color1.getAlpha() * p + startColor.getAlpha() * (1 - p)
28
+ });
29
+ };
30
+ const getColorsList = (colorsAmount, colorsShiftAmount, mixColor, saturation, mainColor)=>{
31
+ const colorsList = [];
32
+ const givenColor = mainColor.isValid() ? mainColor : errorColor;
33
+ let step;
34
+ for(step = 0; step < colorsAmount; step++){
35
+ if (mainColor.isValid()) {
36
+ colorsList.push(mix(givenColor.saturate((step + 1) / colorsAmount * (saturation / 100)), mixColor, colorsShiftAmount / 100 * (step + 1) / colorsAmount));
37
+ } else {
38
+ colorsList.push(errorColor);
39
+ }
40
+ }
41
+ return colorsList;
42
+ };
43
+ const colorType = [
44
+ 'min',
45
+ 'darkest',
46
+ 'darker',
47
+ 'dark',
48
+ 'DEFAULT',
49
+ 'vivid',
50
+ 'light',
51
+ 'lighter',
52
+ 'lightest',
53
+ 'max'
54
+ ];
55
+ const create10ColorPallet = (mainColor)=>{
56
+ const darkColors = getColorsList(DEFAULT_NUM_DARK_COLORS, 90, tinycolor('#000000'), 20, tinycolor(mainColor)).map((color)=>color);
57
+ const lightColors = getColorsList(DEFAULT_NUM_LIGHT_COLORS, 90, tinycolor('#ffffff'), 20, tinycolor(mainColor)).reverse().map((color)=>color);
58
+ return {
59
+ ...lightColors.reduce((obj, c, idx)=>{
60
+ obj[colorType[9 - idx]] = c.toHexString();
61
+ return obj;
62
+ }, {}),
63
+ DEFAULT: mainColor,
64
+ vivid: tinycolor(mainColor).saturate(10).toHexString(),
65
+ ...darkColors.reduce((obj, c, idx)=>{
66
+ obj[colorType[3 - idx]] = c.toHexString();
67
+ return obj;
68
+ }, {})
69
+ };
70
+ };
71
+ const create10ColorAccessibleContrast = (pallet)=>{
72
+ return Object.entries(pallet).reduce((results, [colorName, value])=>{
73
+ return {
74
+ ...results,
75
+ [colorName]: tinycolor.mostReadable(value, CONTRAST_RANGE, {
76
+ includeFallbackColors: true,
77
+ level: 'AAA',
78
+ size: 'large'
79
+ }).toHexString()
80
+ };
81
+ }, {});
82
+ };
83
+
84
+ const utility = {
85
+ link: '#155276',
86
+ success: '#318f71',
87
+ warning: '#d9a214',
88
+ error: '#8a0e2a',
89
+ emergency: '#6a0019',
90
+ info: '#1c5e86',
91
+ category1: '#1c5e86',
92
+ category2: '#d1541d',
93
+ category3: '#564990',
94
+ category4: '#4dbc97'
95
+ };
96
+ const utilityContrast = {
97
+ link: '#f1f1f1',
98
+ success: '#000000',
99
+ warning: '#1b1b1b',
100
+ error: '#f1f1f1',
101
+ emergency: '#f1f1f1',
102
+ info: '#f1f1f1',
103
+ category1: '#f1f1f1',
104
+ category2: '#000000',
105
+ category3: '#f1f1f1',
106
+ category4: '#1b1b1b'
107
+ };
108
+ const main = ()=>{
109
+ const { values: { themeFile, out } } = parseArgs({
110
+ options: {
111
+ themeFile: {
112
+ type: 'string',
113
+ short: 't',
114
+ default: './colors.json'
115
+ },
116
+ primary: {
117
+ type: 'string',
118
+ short: 'p',
119
+ default: '#532565'
120
+ },
121
+ secondary: {
122
+ type: 'string',
123
+ short: 's',
124
+ default: '#982568'
125
+ },
126
+ accent: {
127
+ type: 'string',
128
+ short: 'a',
129
+ default: '#E07C3E'
130
+ },
131
+ accentWarm: {
132
+ type: 'string',
133
+ default: '#E07C3E'
134
+ },
135
+ accentCool: {
136
+ type: 'string',
137
+ default: '#1552e0'
138
+ },
139
+ base: {
140
+ type: 'string',
141
+ short: 'b',
142
+ default: '#858585'
143
+ },
144
+ table: {
145
+ type: 'string',
146
+ short: 'b',
147
+ default: '#858585'
148
+ },
149
+ out: {
150
+ type: 'string',
151
+ short: 'o',
152
+ default: '../'
153
+ }
154
+ }
155
+ });
156
+ if (!themeFile) {
157
+ console.log('No themefile found. Please provide a themefile with \'-t\'.');
158
+ return;
159
+ }
160
+ if (themeFile && !existsSync(themeFile)) {
161
+ console.log('No themefile found. Please provide a themefile with \'-t\'.');
162
+ return;
163
+ }
164
+ const themeData = readFileSync(themeFile, {
165
+ encoding: 'utf8',
166
+ flag: 'r'
167
+ });
168
+ const themeColors = JSON.parse(themeData);
169
+ const primaryPallet = create10ColorPallet(themeColors.primary);
170
+ const secondaryPallet = create10ColorPallet(themeColors.secondary);
171
+ const accentPallet = create10ColorPallet(themeColors.accent);
172
+ const accentPalletWarm = create10ColorPallet(themeColors.accentWarm);
173
+ const accentPalletCool = create10ColorPallet(themeColors.accentCool);
174
+ const basePallet = create10ColorPallet(themeColors.base);
175
+ const chartPallet = create10ColorPallet(themeColors.chart);
176
+ const tablePallet = create10ColorPallet(themeColors?.table ?? '#ffffff');
177
+ const theme = {
178
+ primary: primaryPallet,
179
+ 'primary-contrast': create10ColorAccessibleContrast(primaryPallet),
180
+ secondary: secondaryPallet,
181
+ 'secondary-contrast': create10ColorAccessibleContrast(secondaryPallet),
182
+ accent: accentPallet,
183
+ 'accent-contrast': create10ColorAccessibleContrast(accentPallet),
184
+ 'accent-warm': accentPalletWarm,
185
+ 'accent-warm-contrast': create10ColorAccessibleContrast(accentPalletWarm),
186
+ 'accent-cool': accentPalletCool,
187
+ 'accent-cool-contrast': create10ColorAccessibleContrast(accentPalletCool),
188
+ base: basePallet,
189
+ 'base-contrast': create10ColorAccessibleContrast(basePallet),
190
+ utility: utility,
191
+ 'utility-contrast': utilityContrast,
192
+ chart: chartPallet,
193
+ 'chart-contrast': create10ColorAccessibleContrast(chartPallet),
194
+ table: tablePallet,
195
+ 'table-contrast': create10ColorAccessibleContrast(tablePallet)
196
+ };
197
+ writeFileSync(join(out ?? './', 'themeColors.json'), JSON.stringify(theme, null, 2));
198
+ };
199
+ main();
@@ -0,0 +1,70 @@
1
+ import { promises } from 'fs';
2
+ import { importDirectory } from '@iconify/tools/lib/import/directory';
3
+ import { cleanupSVG } from '@iconify/tools/lib/svg/cleanup';
4
+ import { runSVGO } from '@iconify/tools/lib/optimise/svgo';
5
+ import { parseColors, isEmptyColor } from '@iconify/tools/lib/colors/parse';
6
+
7
+ const getArgs = (defaults = {})=>{
8
+ const args = defaults;
9
+ process.argv.slice(2, process.argv.length).forEach((arg)=>{
10
+ // long arg
11
+ if (arg.slice(0, 2) === '--') {
12
+ const longArg = arg.split('=');
13
+ const longArgFlag = longArg[0].slice(2, longArg[0].length);
14
+ const longArgValue = longArg.length > 1 ? longArg[1] : true;
15
+ args[longArgFlag] = longArgValue;
16
+ } else if (arg[0] === '-') {
17
+ const flags = arg.slice(1, arg.length).split('');
18
+ flags.forEach((flag)=>{
19
+ args[flag] = true;
20
+ });
21
+ }
22
+ });
23
+ return args;
24
+ };
25
+ const build = async (inpath, outpath, prefix = 'gen3')=>{
26
+ // Import icons
27
+ console.log(inpath, outpath, prefix);
28
+ const iconSet = await importDirectory(inpath, {
29
+ prefix: prefix,
30
+ includeSubDirs: true
31
+ });
32
+ // Validate, clean up, fix palette and optimise
33
+ await iconSet.forEach(async (name, type)=>{
34
+ if (type !== 'icon') {
35
+ return;
36
+ }
37
+ const svg = iconSet.toSVG(name);
38
+ if (!svg) {
39
+ // Invalid icon
40
+ iconSet.remove(name);
41
+ return;
42
+ }
43
+ // Clean up and optimise icons
44
+ try {
45
+ await cleanupSVG(svg);
46
+ await parseColors(svg, {
47
+ defaultColor: 'currentColor',
48
+ callback: (attr, colorStr, color)=>{
49
+ return !color || isEmptyColor(color) ? colorStr : 'currentColor';
50
+ }
51
+ });
52
+ await runSVGO(svg);
53
+ } catch (err) {
54
+ // Invalid icon
55
+ console.error(`Error parsing ${name}:`, err);
56
+ iconSet.remove(name);
57
+ return;
58
+ }
59
+ // Update icon
60
+ iconSet.fromSVG(name, svg);
61
+ });
62
+ // Export as IconifyJSON
63
+ const exported = JSON.stringify(iconSet.export(), null, '\t') + '\n';
64
+ // Save to file
65
+ await promises.writeFile(`${outpath}/${iconSet.prefix}.json`, exported, 'utf8');
66
+ };
67
+ const { inpath, outpath, prefix } = getArgs({
68
+ prefix: 'gen3'
69
+ });
70
+ build(inpath, outpath, prefix);
@@ -0,0 +1,67 @@
1
+ import { Agent as Agent$1 } from 'https';
2
+ import { Agent } from 'http';
3
+ import { writeFileSync } from 'node:fs';
4
+ import { parseArgs } from 'node:util';
5
+ import fetchRetry from 'fetch-retry';
6
+ import { fileURLToPath } from 'url';
7
+ import { dirname } from 'path';
8
+
9
+ const __filename = fileURLToPath(import.meta.url);
10
+ const __dirname = dirname(__filename);
11
+ const fetchWithRetry = fetchRetry(fetch);
12
+ const httpAgent = new Agent();
13
+ const httpsAgent = new Agent$1({
14
+ rejectUnauthorized: false
15
+ });
16
+ const fetchJson = async (url)=>{
17
+ console.log(`Fetching DRS ids from ${url}`);
18
+ return fetchWithRetry(url, {
19
+ // TODO: fix the typing to remove the ignore
20
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
21
+ // @ts-ignore
22
+ agent: url.match(/^https:/) ? httpsAgent : httpAgent,
23
+ method: 'GET',
24
+ headers: {
25
+ Accept: 'application/json',
26
+ 'Content-Type': 'application/json'
27
+ },
28
+ retries: 5,
29
+ retryDelay: 800
30
+ }).then((res)=>{
31
+ if (res.status === 200) {
32
+ return res.json().catch((err)=>console.error(`failed json parse - ${err}`));
33
+ }
34
+ });
35
+ };
36
+ const main = ()=>{
37
+ let drsResolverURL = 'https://dataguids.org';
38
+ if (process.env.DRS_RESOLVER_URL) {
39
+ drsResolverURL = process.env.DRS_RESOLVER_URL;
40
+ }
41
+ const { values: { out } } = parseArgs({
42
+ options: {
43
+ out: {
44
+ type: 'string',
45
+ short: 'o',
46
+ default: `${__dirname}`
47
+ }
48
+ }
49
+ });
50
+ const drsCachePath = `${out}/drsHostnames.json`;
51
+ fetchJson(`${drsResolverURL}/index/_dist`).then((drsIds)=>{
52
+ if (!drsIds) {
53
+ throw new Error('Failed to fetch drsHostnames.json');
54
+ }
55
+ const drsCache = drsIds.reduce((acc, drsId)=>{
56
+ const ids = drsId.hints.map((hint)=>hint.replace('.*', '').replace('.*', '').replace('\\.', '.'));
57
+ ids.forEach((id)=>{
58
+ acc[id] = drsId.host.replace('https://', '').replace('/index/', '');
59
+ });
60
+ return acc;
61
+ }, {});
62
+ writeFileSync(drsCachePath, JSON.stringify(drsCache, null, 2));
63
+ });
64
+ };
65
+ main();
66
+
67
+ export { main as default };
@@ -0,0 +1,124 @@
1
+ import { Agent as Agent$1 } from 'https';
2
+ import { Agent } from 'http';
3
+ import { buildClientSchema, printSchema } from 'graphql';
4
+ import { writeFileSync } from 'node:fs';
5
+ import { parseArgs } from 'node:util';
6
+ import fetchRetry from 'fetch-retry';
7
+ import { fileURLToPath } from 'url';
8
+ import { dirname } from 'path';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = dirname(__filename);
12
+ const fetchWithRetry = fetchRetry(fetch);
13
+ const getSubPath = (argPath = '')=>{
14
+ const addSlash = (path)=>`${path}/`.replace(/\/+$/, '/');
15
+ if (!argPath) {
16
+ let commonsDefaultPath = 'http://localhost:5000/v0/submission/';
17
+ if (process.env.HOSTNAME) {
18
+ commonsDefaultPath = `https://${process.env.HOSTNAME}/api/v0/submission/`;
19
+ if (process.env.HOSTNAME.startsWith('revproxy')) {
20
+ // running thur a revproxy like nginx
21
+ commonsDefaultPath = `http://${process.env.HOSTNAME}/api/v0/submission/`;
22
+ }
23
+ }
24
+ return {
25
+ valid: 'ok',
26
+ commonsSubPath: addSlash(process.env.GEN3_SUBMISSION_URL || commonsDefaultPath)
27
+ };
28
+ }
29
+ const arg1 = argPath;
30
+ if (!arg1.match(/^https?:\/\//)) {
31
+ console.log(`
32
+ getSchema downloads data/schema.json and data/dictionary.json from the environment's
33
+ gen-api for later use configuring gql queries
34
+
35
+ Use: node getSchema.js [submissionApiPath]
36
+ - where gdcSubmissionApiPath defaults to: process.env.GEN3_SUBPATH || 'http://localhost:5000/v0/submission/'
37
+ - example - if gdcSubmissionApiPath = https://dev.bionimbus.org/api/vo/submission/,
38
+ then the script loads:
39
+ * https://dev.bionimbus.org/api/v0/submission/_dictionary/_all
40
+ * https://dev.bionimbus.org/api/v0/submission/getschema
41
+ `);
42
+ return {
43
+ valid: 'exit'
44
+ };
45
+ }
46
+ return {
47
+ valid: 'ok',
48
+ commonsSubPath: addSlash(arg1)
49
+ };
50
+ };
51
+ const httpAgent = new Agent();
52
+ const httpsAgent = new Agent$1({
53
+ rejectUnauthorized: false
54
+ });
55
+ const fetchJson = async (url)=>{
56
+ console.log(`Fetching ${url}`);
57
+ return fetchWithRetry(url, {
58
+ // TODO: fix the typing to remove the ts-ignore
59
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
60
+ // @ts-ignore
61
+ agent: url.match(/^https:/) ? httpsAgent : httpAgent,
62
+ method: 'GET',
63
+ headers: {
64
+ Accept: 'application/json',
65
+ 'Content-Type': 'application/json'
66
+ },
67
+ retries: 5,
68
+ retryDelay: 800
69
+ }).then((res)=>{
70
+ if (res.status === 200) {
71
+ return res.json().catch((err)=>console.error(`failed json parse - ${err}`));
72
+ }
73
+ });
74
+ };
75
+ const main = ()=>{
76
+ const { values: { url, out } } = parseArgs({
77
+ options: {
78
+ url: {
79
+ type: 'string',
80
+ default: undefined
81
+ },
82
+ out: {
83
+ type: 'string',
84
+ short: 'o',
85
+ default: `${__dirname}`
86
+ }
87
+ }
88
+ });
89
+ const { valid, commonsSubPath } = getSubPath(url);
90
+ if (valid !== 'ok') {
91
+ process.exit(1);
92
+ }
93
+ const schemaUrl = `${commonsSubPath}getschema`;
94
+ const schemaPath = `${out}/schema.json`;
95
+ const dictUrl = `${commonsSubPath}_dictionary/_all`;
96
+ const dictPath = `${out}/dictionary.json`;
97
+ const actionList = [];
98
+ actionList.push(// Save JSON of full schema introspection for Babel Relay Plugin to use
99
+ fetchJson(schemaUrl).then((schema)=>{
100
+ if (!schema) {
101
+ throw new Error('Failed to fetch schema.json');
102
+ }
103
+ writeFileSync(schemaPath, JSON.stringify(schema, null, 2));
104
+ // Save user readable type system shorthand of schema
105
+ const graphQLSchema = buildClientSchema(schema.data);
106
+ writeFileSync(`${__dirname}/schema.graphql`, printSchema(graphQLSchema));
107
+ }));
108
+ actionList.push(fetchJson(dictUrl).then((dict)=>{
109
+ if (!dict) {
110
+ throw new Error('Failed to fetch dictionary.json');
111
+ }
112
+ writeFileSync(dictPath, JSON.stringify(dict, null, 2));
113
+ }));
114
+ Promise.all(actionList).then(()=>{
115
+ console.log('All done!');
116
+ process.exit(0);
117
+ }, (err)=>{
118
+ console.error('Error: ', err);
119
+ process.exit(2);
120
+ });
121
+ };
122
+ main();
123
+
124
+ export { main as default };
package/package.json ADDED
@@ -0,0 +1,40 @@
1
+ {
2
+ "name": "@gen3/toolsff",
3
+ "version": "0.10.44",
4
+ "description": "tools for processing portal content",
5
+ "main": "index.js",
6
+ "type": "module",
7
+ "engines": {
8
+ "npm": ">=10.2.3",
9
+ "node": ">=20.11.0"
10
+ },
11
+ "scripts": {
12
+ "lint": "eslint --ext .js,.ts src",
13
+ "test": "echo \"Error: no test specified\" && exit 1",
14
+ "clean": "rimraf ./dist",
15
+ "build": "rollup --config rollup.config.js",
16
+ "build:clean": "npm run clean && npm run build"
17
+ },
18
+ "bin": {
19
+ "buildColors": "./dist/buildColors.esm.js",
20
+ "bundleIcons": "./dist/bundleIcons.esm.js",
21
+ "getSchema": "./dist/getSchema.esm.js",
22
+ "getDRSToHostname": "./dist/getDRSToHostname.esm.js"
23
+ },
24
+ "author": "Craig Barnes",
25
+ "license": "Apache-2.0",
26
+ "dependencies": {
27
+ "@iconify/tools": "^2.1.2",
28
+ "tinycolor2": "^1.6.0"
29
+ },
30
+ "devDependencies": {
31
+ "rollup-plugin-executable": "^1.6.3"
32
+ },
33
+ "peerDependencies": {
34
+ "ts-node": "^10.9.2"
35
+ },
36
+ "files": [
37
+ "dist"
38
+ ],
39
+ "gitHead": "4fa5483ea0d4d9d1e7b861ce0763490afd799e26"
40
+ }