Compare commits
18 Commits
Author | SHA1 | Date | |
---|---|---|---|
75059dfca8 | |||
90c0f30ce1 | |||
9a55303978 | |||
224125fb8e | |||
df9d197508 | |||
ae33716af4 | |||
31b64eda5e | |||
7f3437e3cd | |||
8903bee78d | |||
a02b45a673 | |||
e7883f5997 | |||
39ab01b4af | |||
bb9de1b13b | |||
080e133e9f | |||
a284c58a68 | |||
18bb54831d | |||
141c7ed8a7 | |||
037481f195 |
@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@push.rocks/npmextra",
|
"name": "@push.rocks/npmextra",
|
||||||
"version": "4.0.13",
|
"version": "5.0.5",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "do more with npm",
|
"description": "do more with npm",
|
||||||
"main": "dist_ts/index.js",
|
"main": "dist_ts/index.js",
|
||||||
|
10
pnpm-lock.yaml
generated
10
pnpm-lock.yaml
generated
@ -87,7 +87,7 @@ packages:
|
|||||||
'@push.rocks/smartstream': 3.0.30
|
'@push.rocks/smartstream': 3.0.30
|
||||||
'@push.rocks/smarttime': 4.0.6
|
'@push.rocks/smarttime': 4.0.6
|
||||||
'@push.rocks/webstore': 2.0.13
|
'@push.rocks/webstore': 2.0.13
|
||||||
'@tsclass/tsclass': 4.0.46
|
'@tsclass/tsclass': 4.0.50
|
||||||
'@types/express': 4.17.21
|
'@types/express': 4.17.21
|
||||||
body-parser: 1.20.2
|
body-parser: 1.20.2
|
||||||
cors: 2.8.5
|
cors: 2.8.5
|
||||||
@ -830,7 +830,7 @@ packages:
|
|||||||
'@push.rocks/smartpromise': 4.0.3
|
'@push.rocks/smartpromise': 4.0.3
|
||||||
'@push.rocks/smartpuppeteer': 2.0.2
|
'@push.rocks/smartpuppeteer': 2.0.2
|
||||||
'@push.rocks/smartunique': 3.0.6
|
'@push.rocks/smartunique': 3.0.6
|
||||||
'@tsclass/tsclass': 4.0.46
|
'@tsclass/tsclass': 4.0.50
|
||||||
'@types/express': 4.17.21
|
'@types/express': 4.17.21
|
||||||
express: 4.18.2
|
express: 4.18.2
|
||||||
pdf-merger-js: 3.4.0
|
pdf-merger-js: 3.4.0
|
||||||
@ -892,7 +892,7 @@ packages:
|
|||||||
'@push.rocks/smartxml': 1.0.8
|
'@push.rocks/smartxml': 1.0.8
|
||||||
'@push.rocks/smartyaml': 2.0.5
|
'@push.rocks/smartyaml': 2.0.5
|
||||||
'@push.rocks/webrequest': 3.0.34
|
'@push.rocks/webrequest': 3.0.34
|
||||||
'@tsclass/tsclass': 4.0.46
|
'@tsclass/tsclass': 4.0.50
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@push.rocks/smartsocket@2.0.24:
|
/@push.rocks/smartsocket@2.0.24:
|
||||||
@ -1335,8 +1335,8 @@ packages:
|
|||||||
type-fest: 2.19.0
|
type-fest: 2.19.0
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@tsclass/tsclass@4.0.46:
|
/@tsclass/tsclass@4.0.50:
|
||||||
resolution: {integrity: sha512-UovPUvlozv1ftJp4KW5tt4MP/LQCNP3lSCinjyIrLkopOymczyzONUGvSAAwOBf1XBE9bO0tI4KtRuXWN9XBXQ==}
|
resolution: {integrity: sha512-ICUe4hfebpvbn8JkReGP1m3DCTq6S5FIhLJzbFx9F7tx6dn909fA9YIEHkFeMj2X7fT5aGvAXOZRlT52GsnSUw==}
|
||||||
dependencies:
|
dependencies:
|
||||||
type-fest: 4.10.2
|
type-fest: 4.10.2
|
||||||
dev: true
|
dev: true
|
||||||
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@push.rocks/npmextra',
|
name: '@push.rocks/npmextra',
|
||||||
version: '4.0.13',
|
version: '5.0.5',
|
||||||
description: 'do more with npm'
|
description: 'do more with npm'
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import * as plugins from './npmextra.plugins.js';
|
import * as plugins from './npmextra.plugins.js';
|
||||||
import * as paths from './npmextra.paths.js';
|
import * as paths from './npmextra.paths.js';
|
||||||
import { KeyValueStore } from './npmextra.classes.keyvaluestore.js';
|
import { KeyValueStore } from './npmextra.classes.keyvaluestore.js';
|
||||||
|
import { env } from 'process';
|
||||||
|
|
||||||
export interface IAppDataOptions {
|
export interface IAppDataOptions {
|
||||||
dirPath?: string;
|
dirPath?: string;
|
||||||
@ -10,19 +11,19 @@ export interface IAppDataOptions {
|
|||||||
* kvStoreKey: 'MY_ENV_VAR'
|
* kvStoreKey: 'MY_ENV_VAR'
|
||||||
*/
|
*/
|
||||||
envMapping?: {
|
envMapping?: {
|
||||||
[key: string]: string;
|
[key: string]: string | object;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export class AppData {
|
export class AppData<T = any> {
|
||||||
/**
|
/**
|
||||||
* creates appdata. If no pathArg is given, data will be stored here:
|
* creates appdata. If no pathArg is given, data will be stored here:
|
||||||
* ${PWD}/.nogit/appdata
|
* ${PWD}/.nogit/appdata
|
||||||
* @param pathArg
|
* @param pathArg
|
||||||
* @returns
|
* @returns
|
||||||
*/
|
*/
|
||||||
public static async createAndInit(optionsArg: IAppDataOptions = {}) {
|
public static async createAndInit<T = any>(optionsArg: IAppDataOptions = {}): Promise<AppData<T>> {
|
||||||
const appData = new AppData(optionsArg);
|
const appData = new AppData<T>(optionsArg);
|
||||||
await appData.readyDeferred.promise;
|
await appData.readyDeferred.promise;
|
||||||
return appData;
|
return appData;
|
||||||
}
|
}
|
||||||
@ -30,7 +31,7 @@ export class AppData {
|
|||||||
// instance
|
// instance
|
||||||
public readyDeferred = plugins.smartpromise.defer();
|
public readyDeferred = plugins.smartpromise.defer();
|
||||||
public options: IAppDataOptions;
|
public options: IAppDataOptions;
|
||||||
private kvStore: KeyValueStore;
|
private kvStore: KeyValueStore<T>;
|
||||||
constructor(optionsArg: IAppDataOptions = {}) {
|
constructor(optionsArg: IAppDataOptions = {}) {
|
||||||
this.options = optionsArg;
|
this.options = optionsArg;
|
||||||
this.init();
|
this.init();
|
||||||
@ -58,23 +59,53 @@ export class AppData {
|
|||||||
this.options.dirPath = nogitAppData;
|
this.options.dirPath = nogitAppData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.kvStore = new KeyValueStore(
|
this.kvStore = new KeyValueStore({
|
||||||
'custom',
|
typeArg: 'custom',
|
||||||
'appkv',
|
identityArg: 'appkv',
|
||||||
this.options.dirPath,
|
customPath: this.options.dirPath,
|
||||||
this.options.requiredKeys
|
mandatoryKeys: this.options.requiredKeys
|
||||||
);
|
});
|
||||||
|
|
||||||
if (this.options.envMapping) {
|
if (this.options.envMapping) {
|
||||||
const qenvInstance = new plugins.qenv.Qenv(process.cwd(), '~/.cloudlyrc');
|
const qenvInstance = new plugins.qenv.Qenv();
|
||||||
for (const key in this.options.envMapping) {
|
|
||||||
const envValue = await qenvInstance.getEnvVarOnDemand(key);
|
// Recursive function to handle nested objects, now includes key parameter
|
||||||
if (envValue) {
|
const processEnvMapping = async (key: string, mappingValue: any, parentKey: string = ''): Promise<any> => {
|
||||||
await this.kvStore.writeKey(key, envValue);
|
if (typeof mappingValue === 'string') {
|
||||||
|
let envValue = await qenvInstance.getEnvVarOnDemand(mappingValue);
|
||||||
|
if (envValue) {
|
||||||
|
if (mappingValue.endsWith('_JSON')) {
|
||||||
|
envValue = JSON.parse(envValue);
|
||||||
|
}
|
||||||
|
// Determine the correct key to use (top-level or nested)
|
||||||
|
const effectiveKey = parentKey || key;
|
||||||
|
await this.kvStore.writeKey(effectiveKey, envValue);
|
||||||
|
}
|
||||||
|
} else if (typeof mappingValue === 'object' && mappingValue !== null) {
|
||||||
|
const resultObject = {};
|
||||||
|
for (const innerKey in mappingValue) {
|
||||||
|
const nestedValue = mappingValue[innerKey];
|
||||||
|
// For nested objects, call recursively but do not immediately write to kvStore
|
||||||
|
const nestedResult = await processEnvMapping(innerKey, nestedValue, key);
|
||||||
|
resultObject[innerKey] = nestedResult;
|
||||||
|
}
|
||||||
|
if (parentKey === '') {
|
||||||
|
// Only write to kvStore if at the top level
|
||||||
|
await this.kvStore.writeKey(key, resultObject);
|
||||||
|
} else {
|
||||||
|
// For nested objects, return the constructed object instead of writing to kvStore
|
||||||
|
return resultObject;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const key in this.options.envMapping) {
|
||||||
|
await processEnvMapping(key, this.options.envMapping[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
this.readyDeferred.resolve();
|
this.readyDeferred.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,4 +130,10 @@ export class AppData {
|
|||||||
console.log('All mandatory keys are present in the appdata');
|
console.log('All mandatory keys are present in the appdata');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async waitForAndGetKey(keyArg: string) {
|
||||||
|
await this.readyDeferred.promise;
|
||||||
|
await this.kvStore.waitForKeysPresent([keyArg]);
|
||||||
|
return this.kvStore.readKey[keyArg];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,11 +5,18 @@ import { Task } from '@push.rocks/taskbuffer';
|
|||||||
|
|
||||||
export type TKeyValueStore = 'custom' | 'userHomeDir';
|
export type TKeyValueStore = 'custom' | 'userHomeDir';
|
||||||
|
|
||||||
|
export interface IKvStoreConstructorOptions {
|
||||||
|
typeArg: TKeyValueStore;
|
||||||
|
identityArg: string;
|
||||||
|
customPath?: string;
|
||||||
|
mandatoryKeys?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* kvStore is a simple key value store to store data about projects between runs
|
* kvStore is a simple key value store to store data about projects between runs
|
||||||
*/
|
*/
|
||||||
export class KeyValueStore {
|
export class KeyValueStore<T = any> {
|
||||||
private dataObject: any = {};
|
private dataObject: Partial<T> = {};
|
||||||
private deletedObject: any = {};
|
private deletedObject: any = {};
|
||||||
private mandatoryKeys: Set<string> = new Set();
|
private mandatoryKeys: Set<string> = new Set();
|
||||||
public changeSubject = new plugins.smartrx.rxjs.Subject();
|
public changeSubject = new plugins.smartrx.rxjs.Subject();
|
||||||
@ -82,19 +89,19 @@ export class KeyValueStore {
|
|||||||
* @param identityArg
|
* @param identityArg
|
||||||
* @param customPath Optional custom path for the keyValue store
|
* @param customPath Optional custom path for the keyValue store
|
||||||
*/
|
*/
|
||||||
constructor(typeArg: TKeyValueStore, identityArg: string, customPath?: string, mandatoryKeys?: string[]) {
|
constructor(optionsArg: IKvStoreConstructorOptions) {
|
||||||
if (customPath && typeArg !== 'custom') {
|
if (optionsArg.customPath && optionsArg.typeArg !== 'custom') {
|
||||||
throw new Error('customPath can only be provided if typeArg is custom');
|
throw new Error('customPath can only be provided if typeArg is custom');
|
||||||
}
|
}
|
||||||
if (typeArg === 'custom' && !customPath) {
|
if (optionsArg.typeArg === 'custom' && !optionsArg.customPath) {
|
||||||
throw new Error('customPath must be provided if typeArg is custom');
|
throw new Error('customPath must be provided if typeArg is custom');
|
||||||
}
|
}
|
||||||
this.type = typeArg;
|
this.type = optionsArg.typeArg;
|
||||||
this.identity = identityArg;
|
this.identity = optionsArg.identityArg;
|
||||||
this.customPath = customPath; // Store custom path if provided
|
this.customPath = optionsArg.customPath; // Store custom path if provided
|
||||||
this.initFilePath();
|
this.initFilePath();
|
||||||
if (mandatoryKeys) {
|
if (optionsArg.mandatoryKeys) {
|
||||||
this.setMandatoryKeys(mandatoryKeys);
|
this.setMandatoryKeys(optionsArg.mandatoryKeys);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -167,7 +174,7 @@ export class KeyValueStore {
|
|||||||
return Array.from(this.mandatoryKeys).filter(key => !(key in this.dataObject));
|
return Array.from(this.mandatoryKeys).filter(key => !(key in this.dataObject));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async waitForKeysPresent(keysArg: []): Promise<void> {
|
public async waitForKeysPresent(keysArg: string[]): Promise<void> {
|
||||||
const missingKeys = keysArg.filter(keyArg => !this.dataObject[keyArg]);
|
const missingKeys = keysArg.filter(keyArg => !this.dataObject[keyArg]);
|
||||||
if (missingKeys.length === 0) {
|
if (missingKeys.length === 0) {
|
||||||
return;
|
return;
|
||||||
|
Reference in New Issue
Block a user