ㄷ
import fs from 'fs';
import path from 'path';
const DEFAULT_DEST_COLUMN_KEYS = [
'encColumn',
'encryptColumn',
'encryptedColumn',
'cryptoColumn',
'destColumn',
'hashColumn'
];
function readJson(filePath) {
const raw = fs.readFileSync(filePath, 'utf8').replace(/^\uFEFF/, '');
return JSON.parse(raw);
}
function requireString(target, key, index) {
const value = target[key];
if (typeof value !== 'string' || value.trim() === '') {
throw new Error(`Target #${index} is missing "${key}".`);
}
return value.trim();
}
export function getOptionalString(target, key) {
const value = target[key];
return typeof value === 'string' && value.trim() !== '' ? value.trim() : '';
}
function findDestColumn(target, index, destColumnKeys) {
for (const key of destColumnKeys) {
const value = getOptionalString(target, key);
if (value) {
return value;
}
}
throw new Error(
`Target #${index} is missing destination column. Expected one of: ${destColumnKeys.join(', ')}.`
);
}
function groupTargets(targets, options = {}) {
const destColumnKeys = options.destColumnKeys || DEFAULT_DEST_COLUMN_KEYS;
const groups = [];
const groupByTableName = new Map();
targets.forEach((target, offset) => {
const sourceNo = offset + 1;
if (options.filter && !options.filter(target, sourceNo)) {
return;
}
const tableName = requireString(target, 'tableName', sourceNo);
const plainColumn = requireString(target, 'plainColumn', sourceNo);
const cryptoType = requireString(target, 'cryptoType', sourceNo);
const destColumn = findDestColumn(target, sourceNo, destColumnKeys);
if (!groupByTableName.has(tableName)) {
const group = {
tableName,
sourceNos: [],
plainColumns: [],
destColumns: [],
cryptoTypes: []
};
groupByTableName.set(tableName, group);
groups.push(group);
}
const group = groupByTableName.get(tableName);
group.sourceNos.push(sourceNo);
group.plainColumns.push(plainColumn);
group.destColumns.push(destColumn);
group.cryptoTypes.push(cryptoType);
});
return groups;
}
function quoteJavaString(value) {
return `"${value.replace(/\\/g, '\\\\').replace(/"/g, '\\"')}"`;
}
function formatArrayDeclaration(name, values, comments, options = {}) {
const lines = [];
if (options.annotation) {
lines.push(options.annotation);
}
lines.push(`private String[] ${name} = {`);
values.forEach((value, index) => {
const comma = index === values.length - 1 ? '' : ',';
lines.push(` ${quoteJavaString(value)}${comma}//${comments[index]}`);
});
lines.push('};');
return lines.join('\n');
}
function buildOutput(groups) {
const comments = groups.map((group) => group.sourceNos.join(','));
return [
formatArrayDeclaration('tableLists', groups.map((group) => group.tableName), comments),
'',
formatArrayDeclaration(
'srcColLists',
groups.map((group) => group.plainColumns.join(',')),
comments,
{ annotation: '@Override' }
),
'',
formatArrayDeclaration('destColLists', groups.map((group) => group.destColumns.join(',')), comments),
'',
formatArrayDeclaration('typeLists', groups.map((group) => group.cryptoTypes.join(',')), comments),
''
].join('\n');
}
export function generate(options) {
const inputPath = path.resolve(process.cwd(), options.inputPath);
const outputPath = path.resolve(process.cwd(), options.outputPath);
const targets = readJson(inputPath);
if (!Array.isArray(targets)) {
throw new Error(`Input JSON must be an array: ${inputPath}`);
}
const output = buildOutput(groupTargets(targets, options));
fs.writeFileSync(outputPath, output, 'utf8');
return outputPath;
}
==============
index.hash.js
#!/usr/bin/env node
import { generate, getOptionalString } from './generator.js';
function printUsage() {
console.log([
'Usage:',
' node vogen/index.hash.js [crypto-targets-json-path] [output-hash-txt-path] [sqlquery-xml-path]',
'',
'Defaults:',
' input : ./crypto-targets.json',
' output: ./output.hash.txt',
' sql : ./vogen/sqlquery.xml'
].join('\n'));
}
function main() {
const args = process.argv.slice(2);
if (args.includes('-h') || args.includes('--help')) {
printUsage();
return;
}
const outputPath = generate({
inputPath: args[0] || 'crypto-targets.json',
outputPath: args[1] || 'output.hash.txt',
sqlQueryXmlPath: args[2],
destColumnKeys: ['hashColumn'],
filter: (target) => Boolean(getOptionalString(target, 'hashColumn'))
});
console.log(`Generated ${outputPath}`);
}
try {
main();
} catch (error) {
console.error(error.message);
process.exit(1);
}
==================
index.js
#!/usr/bin/env node
import { generate } from './generator.js';
function printUsage() {
console.log([
'Usage:',
' node vogen/index.js [crypto-targets-json-path] [output-txt-path] [sqlquery-xml-path]',
'',
'Defaults:',
' input : ./crypto-targets.json',
' output: ./output.txt',
' sql : ./vogen/sqlquery.xml'
].join('\n'));
}
function main() {
const args = process.argv.slice(2);
if (args.includes('-h') || args.includes('--help')) {
printUsage();
return;
}
const outputPath = generate({
inputPath: args[0] || 'crypto-targets.json',
outputPath: args[1] || 'output.txt',
sqlQueryXmlPath: args[2]
});
console.log(`Generated ${outputPath}`);
}
try {
main();
} catch (error) {
console.error(error.message);
process.exit(1);
}
food eff privacy
개인정보 처리방침 / Privacy Policy 개인정보 처리방침 Privacy Policy 시행일 / Effective: 2024.01.27 | 최종 수정 / Last Updated: 2024.01.27 「식품효능」(이하 "앱")은 이용자의 개인정보를 수집하지 않으며, 「개인정보 보호법」 등 관련 법령을 준수합니다. "FoodEff" (the "App") does not collect any personal information from its users and complies with the Personal Information Protection Act and other applicable laws. 제1조 (개인정보 수집 여부) Article 1 (Personal Information Collection) 앱은 회원가입, 로그인 기능이 없으며, 이용자의 개인정보를 직접 수집·저장·처리하지 않습니다. The App does not have any registration or login features and does not directly collect, store, or process any personal information from users. 제2조 (자동 수집 정보) Article 2 (Automatically Collected Information) 앱 자체에서는 개인정보를 수집하지 않으나, 다음의 제3자 서비스에서 비식별 정보를 자동으로 수집할 수 있습니다. The App itself does not collect personal information, but the following third-party services may automatically collect de-identified information: 서비스 / Service 수집 항목 / Items Collected 목적 / Purpose Google A...
댓글
댓글 쓰기