newo 1.4.0 → 1.5.1
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/.env.example +17 -6
- package/CHANGELOG.md +102 -0
- package/README.md +96 -1
- package/dist/akb.d.ts +10 -0
- package/dist/akb.js +88 -0
- package/dist/api.d.ts +14 -0
- package/dist/api.js +103 -0
- package/dist/auth.d.ts +6 -0
- package/dist/auth.js +361 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +307 -0
- package/dist/customer.d.ts +23 -0
- package/dist/customer.js +87 -0
- package/dist/customerAsync.d.ts +22 -0
- package/dist/customerAsync.js +67 -0
- package/dist/customerInit.d.ts +10 -0
- package/dist/customerInit.js +78 -0
- package/dist/env.d.ts +33 -0
- package/dist/env.js +82 -0
- package/dist/fsutil.d.ts +20 -0
- package/dist/fsutil.js +51 -0
- package/dist/hash.d.ts +5 -0
- package/dist/hash.js +40 -0
- package/dist/sync.d.ts +7 -0
- package/dist/sync.js +376 -0
- package/dist/types.d.ts +229 -0
- package/dist/types.js +5 -0
- package/package.json +35 -14
- package/src/{akb.js → akb.ts} +35 -39
- package/src/api.ts +130 -0
- package/src/auth.ts +415 -0
- package/src/cli.ts +316 -0
- package/src/customer.ts +102 -0
- package/src/customerAsync.ts +78 -0
- package/src/customerInit.ts +97 -0
- package/src/env.ts +118 -0
- package/src/fsutil.ts +73 -0
- package/src/hash.ts +41 -0
- package/src/{sync.js → sync.ts} +179 -81
- package/src/types.ts +276 -0
- package/src/api.js +0 -103
- package/src/auth.js +0 -92
- package/src/cli.js +0 -108
- package/src/fsutil.js +0 -34
- package/src/hash.js +0 -17
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { NewoEnvironment, CustomerConfig, MultiCustomerConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Parse environment variables to extract customer configurations
|
|
4
|
+
* Supports both array-based (NEWO_API_KEYS) and individual customer configs
|
|
5
|
+
*/
|
|
6
|
+
export declare function parseCustomerConfig(env: NewoEnvironment): MultiCustomerConfig;
|
|
7
|
+
/**
|
|
8
|
+
* List all available customer IDNs
|
|
9
|
+
*/
|
|
10
|
+
export declare function listCustomers(config: MultiCustomerConfig): string[];
|
|
11
|
+
/**
|
|
12
|
+
* Get customer configuration by IDN
|
|
13
|
+
*/
|
|
14
|
+
export declare function getCustomer(config: MultiCustomerConfig, customerIdn: string): CustomerConfig | null;
|
|
15
|
+
/**
|
|
16
|
+
* Get default customer or throw error if none
|
|
17
|
+
*/
|
|
18
|
+
export declare function getDefaultCustomer(config: MultiCustomerConfig): CustomerConfig;
|
|
19
|
+
/**
|
|
20
|
+
* Validate customer configuration
|
|
21
|
+
*/
|
|
22
|
+
export declare function validateCustomerConfig(config: MultiCustomerConfig): void;
|
|
23
|
+
//# sourceMappingURL=customer.d.ts.map
|
package/dist/customer.js
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parse environment variables to extract customer configurations
|
|
3
|
+
* Supports both array-based (NEWO_API_KEYS) and individual customer configs
|
|
4
|
+
*/
|
|
5
|
+
export function parseCustomerConfig(env) {
|
|
6
|
+
const customers = {};
|
|
7
|
+
// Parse customer-specific API keys
|
|
8
|
+
// Format: NEWO_CUSTOMER_[IDN]_API_KEY=api_key
|
|
9
|
+
for (const [key, value] of Object.entries(env)) {
|
|
10
|
+
if (key.startsWith('NEWO_CUSTOMER_') && key.endsWith('_API_KEY') && value) {
|
|
11
|
+
const idn = key.slice('NEWO_CUSTOMER_'.length, -'_API_KEY'.length).toLowerCase();
|
|
12
|
+
if (!customers[idn]) {
|
|
13
|
+
customers[idn] = { idn, apiKey: value };
|
|
14
|
+
}
|
|
15
|
+
else {
|
|
16
|
+
customers[idn].apiKey = value;
|
|
17
|
+
}
|
|
18
|
+
// Check for corresponding project ID
|
|
19
|
+
const projectIdKey = `NEWO_CUSTOMER_${idn.toUpperCase()}_PROJECT_ID`;
|
|
20
|
+
if (env[projectIdKey]) {
|
|
21
|
+
customers[idn].projectId = env[projectIdKey];
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
// Check for legacy single customer mode
|
|
26
|
+
if (env.NEWO_API_KEY && Object.keys(customers).length === 0) {
|
|
27
|
+
customers['default'] = {
|
|
28
|
+
idn: 'default',
|
|
29
|
+
apiKey: env.NEWO_API_KEY,
|
|
30
|
+
projectId: env.NEWO_PROJECT_ID
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
return {
|
|
34
|
+
customers,
|
|
35
|
+
defaultCustomer: env.NEWO_DEFAULT_CUSTOMER || (Object.keys(customers).length === 1 ? Object.keys(customers)[0] : undefined)
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* List all available customer IDNs
|
|
40
|
+
*/
|
|
41
|
+
export function listCustomers(config) {
|
|
42
|
+
return Object.keys(config.customers).sort();
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get customer configuration by IDN
|
|
46
|
+
*/
|
|
47
|
+
export function getCustomer(config, customerIdn) {
|
|
48
|
+
return config.customers[customerIdn] || null;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Get default customer or throw error if none
|
|
52
|
+
*/
|
|
53
|
+
export function getDefaultCustomer(config) {
|
|
54
|
+
if (config.defaultCustomer) {
|
|
55
|
+
const customer = getCustomer(config, config.defaultCustomer);
|
|
56
|
+
if (customer)
|
|
57
|
+
return customer;
|
|
58
|
+
}
|
|
59
|
+
const customerIdns = listCustomers(config);
|
|
60
|
+
if (customerIdns.length === 1) {
|
|
61
|
+
const firstCustomerIdn = customerIdns[0];
|
|
62
|
+
if (firstCustomerIdn) {
|
|
63
|
+
return config.customers[firstCustomerIdn];
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (customerIdns.length === 0) {
|
|
67
|
+
throw new Error('No customers configured. Please set NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
68
|
+
}
|
|
69
|
+
throw new Error(`Multiple customers configured but no default specified. Available: ${customerIdns.join(', ')}. ` +
|
|
70
|
+
`Set NEWO_DEFAULT_CUSTOMER or use --customer flag.`);
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Validate customer configuration
|
|
74
|
+
*/
|
|
75
|
+
export function validateCustomerConfig(config) {
|
|
76
|
+
const customers = listCustomers(config);
|
|
77
|
+
if (customers.length === 0) {
|
|
78
|
+
throw new Error('No customers configured. Please set NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
79
|
+
}
|
|
80
|
+
for (const customerIdn of customers) {
|
|
81
|
+
const customer = config.customers[customerIdn];
|
|
82
|
+
if (!customer.apiKey) {
|
|
83
|
+
throw new Error(`Customer ${customerIdn} missing API key`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=customer.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { NewoEnvironment, CustomerConfig, MultiCustomerConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Async version of customer configuration parsing that supports API key array initialization
|
|
4
|
+
*/
|
|
5
|
+
export declare function parseCustomerConfigAsync(env: NewoEnvironment, verbose?: boolean): Promise<MultiCustomerConfig>;
|
|
6
|
+
/**
|
|
7
|
+
* List all available customer IDNs
|
|
8
|
+
*/
|
|
9
|
+
export declare function listCustomers(config: MultiCustomerConfig): string[];
|
|
10
|
+
/**
|
|
11
|
+
* Get customer configuration by IDN
|
|
12
|
+
*/
|
|
13
|
+
export declare function getCustomer(config: MultiCustomerConfig, customerIdn: string): CustomerConfig | null;
|
|
14
|
+
/**
|
|
15
|
+
* Get default customer or throw error if none
|
|
16
|
+
*/
|
|
17
|
+
export declare function getDefaultCustomer(config: MultiCustomerConfig): CustomerConfig;
|
|
18
|
+
/**
|
|
19
|
+
* Validate customer configuration
|
|
20
|
+
*/
|
|
21
|
+
export declare function validateCustomerConfig(config: MultiCustomerConfig): void;
|
|
22
|
+
//# sourceMappingURL=customerAsync.d.ts.map
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { initializeCustomersFromApiKeys, usesArrayBasedConfig } from './customerInit.js';
|
|
2
|
+
import { parseCustomerConfig } from './customer.js';
|
|
3
|
+
/**
|
|
4
|
+
* Async version of customer configuration parsing that supports API key array initialization
|
|
5
|
+
*/
|
|
6
|
+
export async function parseCustomerConfigAsync(env, verbose = false) {
|
|
7
|
+
// If using array-based config, initialize from API keys
|
|
8
|
+
if (usesArrayBasedConfig(env)) {
|
|
9
|
+
if (verbose)
|
|
10
|
+
console.log('📝 Using array-based API key configuration');
|
|
11
|
+
return await initializeCustomersFromApiKeys(env, verbose);
|
|
12
|
+
}
|
|
13
|
+
// Fall back to synchronous individual customer parsing
|
|
14
|
+
if (verbose)
|
|
15
|
+
console.log('📝 Using individual customer configuration');
|
|
16
|
+
return parseCustomerConfig(env);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* List all available customer IDNs
|
|
20
|
+
*/
|
|
21
|
+
export function listCustomers(config) {
|
|
22
|
+
return Object.keys(config.customers).sort();
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Get customer configuration by IDN
|
|
26
|
+
*/
|
|
27
|
+
export function getCustomer(config, customerIdn) {
|
|
28
|
+
return config.customers[customerIdn] || null;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Get default customer or throw error if none
|
|
32
|
+
*/
|
|
33
|
+
export function getDefaultCustomer(config) {
|
|
34
|
+
if (config.defaultCustomer) {
|
|
35
|
+
const customer = getCustomer(config, config.defaultCustomer);
|
|
36
|
+
if (customer)
|
|
37
|
+
return customer;
|
|
38
|
+
}
|
|
39
|
+
const customerIdns = listCustomers(config);
|
|
40
|
+
if (customerIdns.length === 1) {
|
|
41
|
+
const firstCustomerIdn = customerIdns[0];
|
|
42
|
+
if (firstCustomerIdn) {
|
|
43
|
+
return config.customers[firstCustomerIdn];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
if (customerIdns.length === 0) {
|
|
47
|
+
throw new Error('No customers configured. Please set NEWO_API_KEYS or NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
48
|
+
}
|
|
49
|
+
throw new Error(`Multiple customers configured but no default specified. Available: ${customerIdns.join(', ')}. ` +
|
|
50
|
+
`Set NEWO_DEFAULT_CUSTOMER or use --customer flag.`);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validate customer configuration
|
|
54
|
+
*/
|
|
55
|
+
export function validateCustomerConfig(config) {
|
|
56
|
+
const customers = listCustomers(config);
|
|
57
|
+
if (customers.length === 0) {
|
|
58
|
+
throw new Error('No customers configured. Please set NEWO_API_KEYS or NEWO_CUSTOMER_[IDN]_API_KEY in your .env file.');
|
|
59
|
+
}
|
|
60
|
+
for (const customerIdn of customers) {
|
|
61
|
+
const customer = config.customers[customerIdn];
|
|
62
|
+
if (!customer.apiKey) {
|
|
63
|
+
throw new Error(`Customer ${customerIdn} missing API key`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=customerAsync.js.map
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { NewoEnvironment, MultiCustomerConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Initialize customer configurations from API keys array
|
|
4
|
+
*/
|
|
5
|
+
export declare function initializeCustomersFromApiKeys(env: NewoEnvironment, verbose?: boolean): Promise<MultiCustomerConfig>;
|
|
6
|
+
/**
|
|
7
|
+
* Check if environment uses array-based configuration
|
|
8
|
+
*/
|
|
9
|
+
export declare function usesArrayBasedConfig(env: NewoEnvironment): boolean;
|
|
10
|
+
//# sourceMappingURL=customerInit.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { getCustomerProfile, makeClient } from './api.js';
|
|
2
|
+
import { exchangeApiKeyForToken } from './auth.js';
|
|
3
|
+
/**
|
|
4
|
+
* Initialize customer configurations from API keys array
|
|
5
|
+
*/
|
|
6
|
+
export async function initializeCustomersFromApiKeys(env, verbose = false) {
|
|
7
|
+
if (!env.NEWO_API_KEYS) {
|
|
8
|
+
throw new Error('NEWO_API_KEYS not set. Provide API keys array in .env file.');
|
|
9
|
+
}
|
|
10
|
+
let apiKeyConfigs;
|
|
11
|
+
try {
|
|
12
|
+
apiKeyConfigs = JSON.parse(env.NEWO_API_KEYS);
|
|
13
|
+
}
|
|
14
|
+
catch (error) {
|
|
15
|
+
throw new Error(`Invalid NEWO_API_KEYS format. Must be valid JSON array: ${error}`);
|
|
16
|
+
}
|
|
17
|
+
if (!Array.isArray(apiKeyConfigs)) {
|
|
18
|
+
throw new Error('NEWO_API_KEYS must be an array');
|
|
19
|
+
}
|
|
20
|
+
const customers = {};
|
|
21
|
+
if (verbose)
|
|
22
|
+
console.log(`🔍 Initializing ${apiKeyConfigs.length} API keys...`);
|
|
23
|
+
for (const [index, keyConfig] of apiKeyConfigs.entries()) {
|
|
24
|
+
try {
|
|
25
|
+
// Normalize config
|
|
26
|
+
const apiKey = typeof keyConfig === 'string' ? keyConfig : keyConfig.key;
|
|
27
|
+
const projectId = typeof keyConfig === 'object' ? keyConfig.project_id : undefined;
|
|
28
|
+
if (verbose)
|
|
29
|
+
console.log(` [${index + 1}/${apiKeyConfigs.length}] Exchanging API key for token...`);
|
|
30
|
+
// Create temporary customer config for token exchange
|
|
31
|
+
const tempCustomer = {
|
|
32
|
+
idn: 'temp',
|
|
33
|
+
apiKey,
|
|
34
|
+
projectId
|
|
35
|
+
};
|
|
36
|
+
// Exchange API key for token
|
|
37
|
+
const tokens = await exchangeApiKeyForToken(tempCustomer);
|
|
38
|
+
if (verbose)
|
|
39
|
+
console.log(` [${index + 1}/${apiKeyConfigs.length}] Getting customer profile...`);
|
|
40
|
+
// Create client with token
|
|
41
|
+
const client = await makeClient(verbose, tokens.access_token);
|
|
42
|
+
// Get customer profile to extract IDN
|
|
43
|
+
const profile = await getCustomerProfile(client);
|
|
44
|
+
if (verbose) {
|
|
45
|
+
console.log(` [${index + 1}/${apiKeyConfigs.length}] ✓ Customer: ${profile.idn} (${profile.organization_name})`);
|
|
46
|
+
}
|
|
47
|
+
// Store customer config with real IDN
|
|
48
|
+
customers[profile.idn] = {
|
|
49
|
+
idn: profile.idn,
|
|
50
|
+
apiKey,
|
|
51
|
+
projectId
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
catch (error) {
|
|
55
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
56
|
+
console.error(` [${index + 1}/${apiKeyConfigs.length}] ❌ Failed to initialize API key: ${message}`);
|
|
57
|
+
// Continue with other keys rather than failing entirely
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
const customerIdns = Object.keys(customers);
|
|
61
|
+
if (customerIdns.length === 0) {
|
|
62
|
+
throw new Error('No valid API keys found. Check your NEWO_API_KEYS configuration.');
|
|
63
|
+
}
|
|
64
|
+
if (verbose) {
|
|
65
|
+
console.log(`✅ Initialized ${customerIdns.length} customers: ${customerIdns.join(', ')}`);
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
customers,
|
|
69
|
+
defaultCustomer: env.NEWO_DEFAULT_CUSTOMER || (customerIdns.length === 1 ? customerIdns[0] : undefined)
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Check if environment uses array-based configuration
|
|
74
|
+
*/
|
|
75
|
+
export function usesArrayBasedConfig(env) {
|
|
76
|
+
return Boolean(env.NEWO_API_KEYS);
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=customerInit.js.map
|
package/dist/env.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validated environment configuration
|
|
3
|
+
*/
|
|
4
|
+
export interface ValidatedEnv {
|
|
5
|
+
readonly NEWO_BASE_URL: string;
|
|
6
|
+
readonly NEWO_PROJECT_ID: string | undefined;
|
|
7
|
+
readonly NEWO_API_KEY: string | undefined;
|
|
8
|
+
readonly NEWO_API_KEYS: string | undefined;
|
|
9
|
+
readonly NEWO_ACCESS_TOKEN: string | undefined;
|
|
10
|
+
readonly NEWO_REFRESH_TOKEN: string | undefined;
|
|
11
|
+
readonly NEWO_REFRESH_URL: string | undefined;
|
|
12
|
+
readonly NEWO_DEFAULT_CUSTOMER: string | undefined;
|
|
13
|
+
readonly [key: string]: string | undefined;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Environment validation errors with clear messaging
|
|
17
|
+
*/
|
|
18
|
+
export declare class EnvValidationError extends Error {
|
|
19
|
+
constructor(message: string);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Validates required environment variables and returns typed configuration
|
|
23
|
+
*/
|
|
24
|
+
export declare function validateEnvironment(): ValidatedEnv;
|
|
25
|
+
/**
|
|
26
|
+
* Global validated environment - call validateEnvironment() once at startup
|
|
27
|
+
*/
|
|
28
|
+
export declare let ENV: ValidatedEnv;
|
|
29
|
+
/**
|
|
30
|
+
* Initialize environment validation - must be called at application startup
|
|
31
|
+
*/
|
|
32
|
+
export declare function initializeEnvironment(): ValidatedEnv;
|
|
33
|
+
//# sourceMappingURL=env.d.ts.map
|
package/dist/env.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Environment validation errors with clear messaging
|
|
3
|
+
*/
|
|
4
|
+
export class EnvValidationError extends Error {
|
|
5
|
+
constructor(message) {
|
|
6
|
+
super(`Environment validation failed: ${message}`);
|
|
7
|
+
this.name = 'EnvValidationError';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Validates required environment variables and returns typed configuration
|
|
12
|
+
*/
|
|
13
|
+
export function validateEnvironment() {
|
|
14
|
+
const env = process.env;
|
|
15
|
+
const baseUrl = env.NEWO_BASE_URL?.trim() || 'https://app.newo.ai';
|
|
16
|
+
const projectId = env.NEWO_PROJECT_ID?.trim();
|
|
17
|
+
const apiKey = env.NEWO_API_KEY?.trim();
|
|
18
|
+
const accessToken = env.NEWO_ACCESS_TOKEN?.trim();
|
|
19
|
+
const refreshToken = env.NEWO_REFRESH_TOKEN?.trim();
|
|
20
|
+
const refreshUrl = env.NEWO_REFRESH_URL?.trim();
|
|
21
|
+
// Base URL validation
|
|
22
|
+
if (!isValidUrl(baseUrl)) {
|
|
23
|
+
throw new EnvValidationError(`NEWO_BASE_URL must be a valid URL. Received: ${baseUrl}`);
|
|
24
|
+
}
|
|
25
|
+
// Project ID is optional - if not set, pull all projects
|
|
26
|
+
// If provided, validate UUID format
|
|
27
|
+
if (projectId && !isValidUuid(projectId)) {
|
|
28
|
+
throw new EnvValidationError(`NEWO_PROJECT_ID must be a valid UUID when provided. Received: ${projectId}`);
|
|
29
|
+
}
|
|
30
|
+
// Authentication validation - at least one method required
|
|
31
|
+
const hasApiKey = !!apiKey;
|
|
32
|
+
const hasApiKeys = !!env.NEWO_API_KEYS?.trim();
|
|
33
|
+
const hasDirectTokens = !!(accessToken && refreshToken);
|
|
34
|
+
if (!hasApiKey && !hasApiKeys && !hasDirectTokens) {
|
|
35
|
+
throw new EnvValidationError('Authentication required: Set NEWO_API_KEY, NEWO_API_KEYS (recommended), or both NEWO_ACCESS_TOKEN and NEWO_REFRESH_TOKEN');
|
|
36
|
+
}
|
|
37
|
+
// If refresh URL is provided, validate it
|
|
38
|
+
if (refreshUrl && !isValidUrl(refreshUrl)) {
|
|
39
|
+
throw new EnvValidationError(`NEWO_REFRESH_URL must be a valid URL when provided. Received: ${refreshUrl}`);
|
|
40
|
+
}
|
|
41
|
+
return {
|
|
42
|
+
NEWO_BASE_URL: baseUrl,
|
|
43
|
+
NEWO_PROJECT_ID: projectId || undefined,
|
|
44
|
+
NEWO_API_KEY: apiKey,
|
|
45
|
+
NEWO_API_KEYS: env.NEWO_API_KEYS?.trim(),
|
|
46
|
+
NEWO_ACCESS_TOKEN: accessToken,
|
|
47
|
+
NEWO_REFRESH_TOKEN: refreshToken,
|
|
48
|
+
NEWO_REFRESH_URL: refreshUrl,
|
|
49
|
+
NEWO_DEFAULT_CUSTOMER: env.NEWO_DEFAULT_CUSTOMER?.trim(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Validates if a string is a valid URL
|
|
54
|
+
*/
|
|
55
|
+
function isValidUrl(urlString) {
|
|
56
|
+
try {
|
|
57
|
+
new URL(urlString);
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Validates if a string is a valid UUID (v4 format)
|
|
66
|
+
*/
|
|
67
|
+
function isValidUuid(uuid) {
|
|
68
|
+
const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
|
|
69
|
+
return uuidRegex.test(uuid);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Global validated environment - call validateEnvironment() once at startup
|
|
73
|
+
*/
|
|
74
|
+
export let ENV;
|
|
75
|
+
/**
|
|
76
|
+
* Initialize environment validation - must be called at application startup
|
|
77
|
+
*/
|
|
78
|
+
export function initializeEnvironment() {
|
|
79
|
+
ENV = validateEnvironment();
|
|
80
|
+
return ENV;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=env.js.map
|
package/dist/fsutil.d.ts
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { RunnerType } from './types.js';
|
|
2
|
+
export declare const NEWO_CUSTOMERS_DIR: string;
|
|
3
|
+
export declare const STATE_DIR: string;
|
|
4
|
+
export declare function customerDir(customerIdn: string): string;
|
|
5
|
+
export declare function customerProjectsDir(customerIdn: string): string;
|
|
6
|
+
export declare function customerStateDir(customerIdn: string): string;
|
|
7
|
+
export declare function mapPath(customerIdn: string): string;
|
|
8
|
+
export declare function hashesPath(customerIdn: string): string;
|
|
9
|
+
export declare function ensureState(customerIdn: string): Promise<void>;
|
|
10
|
+
export declare function projectDir(customerIdn: string, projectIdn: string): string;
|
|
11
|
+
export declare function flowsYamlPath(customerIdn: string): string;
|
|
12
|
+
export declare function skillPath(customerIdn: string, projectIdn: string, agentIdn: string, flowIdn: string, skillIdn: string, runnerType?: RunnerType): string;
|
|
13
|
+
export declare function metadataPath(customerIdn: string, projectIdn: string): string;
|
|
14
|
+
export declare const ROOT_DIR: string;
|
|
15
|
+
export declare const MAP_PATH: string;
|
|
16
|
+
export declare const HASHES_PATH: string;
|
|
17
|
+
export declare function writeFileSafe(filepath: string, content: string): Promise<void>;
|
|
18
|
+
export declare const writeFileAtomic: typeof writeFileSafe;
|
|
19
|
+
export declare function readIfExists(filepath: string): Promise<string | null>;
|
|
20
|
+
//# sourceMappingURL=fsutil.d.ts.map
|
package/dist/fsutil.js
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import fs from 'fs-extra';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export const NEWO_CUSTOMERS_DIR = path.posix.join(process.cwd(), 'newo_customers');
|
|
4
|
+
export const STATE_DIR = path.join(process.cwd(), '.newo');
|
|
5
|
+
export function customerDir(customerIdn) {
|
|
6
|
+
return path.posix.join(NEWO_CUSTOMERS_DIR, customerIdn);
|
|
7
|
+
}
|
|
8
|
+
export function customerProjectsDir(customerIdn) {
|
|
9
|
+
return path.posix.join(customerDir(customerIdn), 'projects');
|
|
10
|
+
}
|
|
11
|
+
export function customerStateDir(customerIdn) {
|
|
12
|
+
return path.join(STATE_DIR, customerIdn);
|
|
13
|
+
}
|
|
14
|
+
export function mapPath(customerIdn) {
|
|
15
|
+
return path.join(customerStateDir(customerIdn), 'map.json');
|
|
16
|
+
}
|
|
17
|
+
export function hashesPath(customerIdn) {
|
|
18
|
+
return path.join(customerStateDir(customerIdn), 'hashes.json');
|
|
19
|
+
}
|
|
20
|
+
export async function ensureState(customerIdn) {
|
|
21
|
+
await fs.ensureDir(STATE_DIR);
|
|
22
|
+
await fs.ensureDir(customerStateDir(customerIdn));
|
|
23
|
+
await fs.ensureDir(customerProjectsDir(customerIdn));
|
|
24
|
+
}
|
|
25
|
+
export function projectDir(customerIdn, projectIdn) {
|
|
26
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn);
|
|
27
|
+
}
|
|
28
|
+
export function flowsYamlPath(customerIdn) {
|
|
29
|
+
return path.posix.join(customerProjectsDir(customerIdn), 'flows.yaml');
|
|
30
|
+
}
|
|
31
|
+
export function skillPath(customerIdn, projectIdn, agentIdn, flowIdn, skillIdn, runnerType = 'guidance') {
|
|
32
|
+
const extension = runnerType === 'nsl' ? '.jinja' : '.guidance';
|
|
33
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, agentIdn, flowIdn, `${skillIdn}${extension}`);
|
|
34
|
+
}
|
|
35
|
+
export function metadataPath(customerIdn, projectIdn) {
|
|
36
|
+
return path.posix.join(customerProjectsDir(customerIdn), projectIdn, 'metadata.json');
|
|
37
|
+
}
|
|
38
|
+
// Legacy support - will be deprecated
|
|
39
|
+
export const ROOT_DIR = path.posix.join(process.cwd(), 'projects');
|
|
40
|
+
export const MAP_PATH = path.join(STATE_DIR, 'map.json');
|
|
41
|
+
export const HASHES_PATH = path.join(STATE_DIR, 'hashes.json');
|
|
42
|
+
export async function writeFileSafe(filepath, content) {
|
|
43
|
+
await fs.ensureDir(path.dirname(filepath));
|
|
44
|
+
await fs.writeFile(filepath, content, 'utf8');
|
|
45
|
+
}
|
|
46
|
+
// Deprecated: use writeFileSafe instead
|
|
47
|
+
export const writeFileAtomic = writeFileSafe;
|
|
48
|
+
export async function readIfExists(filepath) {
|
|
49
|
+
return (await fs.pathExists(filepath)) ? fs.readFile(filepath, 'utf8') : null;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=fsutil.js.map
|
package/dist/hash.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { HashStore } from './types.js';
|
|
2
|
+
export declare function sha256(str: string): string;
|
|
3
|
+
export declare function loadHashes(customerIdn?: string): Promise<HashStore>;
|
|
4
|
+
export declare function saveHashes(hashes: HashStore, customerIdn?: string): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=hash.d.ts.map
|
package/dist/hash.js
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import crypto from 'crypto';
|
|
2
|
+
import fs from 'fs-extra';
|
|
3
|
+
import { ensureState, hashesPath, HASHES_PATH } from './fsutil.js';
|
|
4
|
+
export function sha256(str) {
|
|
5
|
+
return crypto.createHash('sha256').update(str, 'utf8').digest('hex');
|
|
6
|
+
}
|
|
7
|
+
export async function loadHashes(customerIdn) {
|
|
8
|
+
if (customerIdn) {
|
|
9
|
+
await ensureState(customerIdn);
|
|
10
|
+
try {
|
|
11
|
+
return await fs.readJson(hashesPath(customerIdn));
|
|
12
|
+
}
|
|
13
|
+
catch (error) {
|
|
14
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
15
|
+
return {};
|
|
16
|
+
}
|
|
17
|
+
throw error;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
// Legacy support
|
|
21
|
+
try {
|
|
22
|
+
return await fs.readJson(HASHES_PATH);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
if (error instanceof Error && 'code' in error && error.code === 'ENOENT') {
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
throw error;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
export async function saveHashes(hashes, customerIdn) {
|
|
32
|
+
if (customerIdn) {
|
|
33
|
+
await fs.writeJson(hashesPath(customerIdn), hashes, { spaces: 2 });
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
// Legacy support
|
|
37
|
+
await fs.writeJson(HASHES_PATH, hashes, { spaces: 2 });
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=hash.js.map
|
package/dist/sync.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AxiosInstance } from 'axios';
|
|
2
|
+
import type { ProjectData, CustomerConfig } from './types.js';
|
|
3
|
+
export declare function pullSingleProject(client: AxiosInstance, customer: CustomerConfig, projectId: string, projectIdn: string, verbose?: boolean): Promise<ProjectData>;
|
|
4
|
+
export declare function pullAll(client: AxiosInstance, customer: CustomerConfig, projectId?: string | null, verbose?: boolean): Promise<void>;
|
|
5
|
+
export declare function pushChanged(client: AxiosInstance, customer: CustomerConfig, verbose?: boolean): Promise<void>;
|
|
6
|
+
export declare function status(customer: CustomerConfig, verbose?: boolean): Promise<void>;
|
|
7
|
+
//# sourceMappingURL=sync.d.ts.map
|