@delma/fylo 2.0.1 → 2.1.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/README.md +206 -261
- package/dist/adapters/cipher.js +155 -0
- package/dist/adapters/cipher.js.map +1 -0
- package/dist/core/collection.js +6 -0
- package/dist/core/collection.js.map +1 -0
- package/dist/core/directory.js +48 -0
- package/dist/core/directory.js.map +1 -0
- package/dist/core/doc-id.js +15 -0
- package/dist/core/doc-id.js.map +1 -0
- package/dist/core/extensions.js +16 -0
- package/dist/core/extensions.js.map +1 -0
- package/dist/core/format.js +355 -0
- package/dist/core/format.js.map +1 -0
- package/dist/core/parser.js +764 -0
- package/dist/core/parser.js.map +1 -0
- package/dist/core/query.js +47 -0
- package/dist/core/query.js.map +1 -0
- package/dist/engines/s3-files/documents.js +62 -0
- package/dist/engines/s3-files/documents.js.map +1 -0
- package/dist/engines/s3-files/filesystem.js +165 -0
- package/dist/engines/s3-files/filesystem.js.map +1 -0
- package/dist/engines/s3-files/query.js +235 -0
- package/dist/engines/s3-files/query.js.map +1 -0
- package/dist/engines/s3-files/types.js +2 -0
- package/dist/engines/s3-files/types.js.map +1 -0
- package/dist/engines/s3-files.js +629 -0
- package/dist/engines/s3-files.js.map +1 -0
- package/dist/engines/types.js +2 -0
- package/dist/engines/types.js.map +1 -0
- package/dist/index.js +562 -0
- package/dist/index.js.map +1 -0
- package/dist/sync.js +18 -0
- package/dist/sync.js.map +1 -0
- package/dist/types/fylo.d.ts +179 -0
- package/{src → dist}/types/node-runtime.d.ts +1 -0
- package/package.json +3 -6
- package/.env.example +0 -16
- package/.github/copilot-instructions.md +0 -3
- package/.github/prompts/release.prompt.md +0 -10
- package/.github/workflows/ci.yml +0 -37
- package/.github/workflows/publish.yml +0 -91
- package/.prettierrc +0 -7
- package/AGENTS.md +0 -3
- package/CLAUDE.md +0 -3
- package/eslint.config.js +0 -32
- package/src/CLI +0 -39
- package/src/adapters/cipher.ts +0 -180
- package/src/adapters/redis.ts +0 -487
- package/src/adapters/s3.ts +0 -61
- package/src/core/collection.ts +0 -5
- package/src/core/directory.ts +0 -387
- package/src/core/extensions.ts +0 -21
- package/src/core/format.ts +0 -457
- package/src/core/parser.ts +0 -901
- package/src/core/query.ts +0 -53
- package/src/core/walker.ts +0 -174
- package/src/core/write-queue.ts +0 -59
- package/src/engines/s3-files.ts +0 -1068
- package/src/engines/types.ts +0 -21
- package/src/index.ts +0 -1727
- package/src/migrate-cli.ts +0 -22
- package/src/migrate.ts +0 -74
- package/src/types/fylo.d.ts +0 -261
- package/src/types/write-queue.ts +0 -42
- package/src/worker.ts +0 -18
- package/src/workers/write-worker.ts +0 -120
- package/tests/collection/truncate.test.js +0 -35
- package/tests/data.js +0 -97
- package/tests/index.js +0 -14
- package/tests/integration/aws-s3-files.canary.test.js +0 -22
- package/tests/integration/create.test.js +0 -39
- package/tests/integration/delete.test.js +0 -95
- package/tests/integration/edge-cases.test.js +0 -158
- package/tests/integration/encryption.test.js +0 -131
- package/tests/integration/export.test.js +0 -46
- package/tests/integration/join-modes.test.js +0 -154
- package/tests/integration/migration.test.js +0 -38
- package/tests/integration/nested.test.js +0 -142
- package/tests/integration/operators.test.js +0 -122
- package/tests/integration/queue.test.js +0 -83
- package/tests/integration/read.test.js +0 -119
- package/tests/integration/rollback.test.js +0 -60
- package/tests/integration/s3-files.test.js +0 -192
- package/tests/integration/update.test.js +0 -99
- package/tests/mocks/cipher.js +0 -40
- package/tests/mocks/redis.js +0 -123
- package/tests/mocks/s3.js +0 -80
- package/tests/schemas/album.d.ts +0 -5
- package/tests/schemas/album.json +0 -5
- package/tests/schemas/comment.d.ts +0 -7
- package/tests/schemas/comment.json +0 -7
- package/tests/schemas/photo.d.ts +0 -7
- package/tests/schemas/photo.json +0 -7
- package/tests/schemas/post.d.ts +0 -6
- package/tests/schemas/post.json +0 -6
- package/tests/schemas/tip.d.ts +0 -7
- package/tests/schemas/tip.json +0 -7
- package/tests/schemas/todo.d.ts +0 -6
- package/tests/schemas/todo.json +0 -6
- package/tests/schemas/user.d.ts +0 -23
- package/tests/schemas/user.json +0 -23
- package/tsconfig.json +0 -21
- package/tsconfig.typecheck.json +0 -31
- /package/{src → dist}/types/bun-runtime.d.ts +0 -0
- /package/{src → dist}/types/index.d.ts +0 -0
- /package/{src → dist}/types/query.d.ts +0 -0
- /package/{src → dist}/types/vendor-modules.d.ts +0 -0
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AES-256-GCM encryption adapter for field-level value encryption.
|
|
3
|
+
*
|
|
4
|
+
* Two modes are supported via the `deterministic` flag on `encrypt()`:
|
|
5
|
+
*
|
|
6
|
+
* - **Random IV (default)**: A cryptographically random IV is generated per
|
|
7
|
+
* encryption operation. Identical plaintexts produce different ciphertexts.
|
|
8
|
+
* Use this for fields that do not need exact-match ($eq/$ne) queries.
|
|
9
|
+
*
|
|
10
|
+
* Exact-match queries use a separate keyed HMAC blind index. This leaks equality
|
|
11
|
+
* and frequency for indexed values, but stored document bodies use random nonces.
|
|
12
|
+
*
|
|
13
|
+
* Encrypted fields are declared per-collection in JSON schema files via the
|
|
14
|
+
* `$encrypted` array. The encryption key is sourced from `ENCRYPTION_KEY` env var.
|
|
15
|
+
* Set `CIPHER_SALT` to a unique random value to prevent cross-deployment attacks.
|
|
16
|
+
*/
|
|
17
|
+
export class Cipher {
|
|
18
|
+
static key = null;
|
|
19
|
+
static legacyCbcKey = null;
|
|
20
|
+
static hmacKey = null;
|
|
21
|
+
/** Per-collection encrypted field sets, loaded from schema `$encrypted` arrays. */
|
|
22
|
+
static collections = new Map();
|
|
23
|
+
static isConfigured() {
|
|
24
|
+
return Cipher.key !== null;
|
|
25
|
+
}
|
|
26
|
+
static hasEncryptedFields(collection) {
|
|
27
|
+
const fields = Cipher.collections.get(collection);
|
|
28
|
+
return !!fields && fields.size > 0;
|
|
29
|
+
}
|
|
30
|
+
static isEncryptedField(collection, field) {
|
|
31
|
+
const fields = Cipher.collections.get(collection);
|
|
32
|
+
if (!fields || fields.size === 0)
|
|
33
|
+
return false;
|
|
34
|
+
for (const pattern of fields) {
|
|
35
|
+
if (field === pattern)
|
|
36
|
+
return true;
|
|
37
|
+
// Support nested: encrypting "address" encrypts "address/city" etc.
|
|
38
|
+
if (field.startsWith(`${pattern}/`))
|
|
39
|
+
return true;
|
|
40
|
+
}
|
|
41
|
+
return false;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Registers encrypted fields for a collection (from schema `$encrypted` array).
|
|
45
|
+
*/
|
|
46
|
+
static registerFields(collection, fields) {
|
|
47
|
+
if (fields.length > 0) {
|
|
48
|
+
Cipher.collections.set(collection, new Set(fields));
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Derives AES + HMAC keys from a secret string. Called once at startup.
|
|
53
|
+
*/
|
|
54
|
+
static async configure(secret) {
|
|
55
|
+
const encoder = new TextEncoder();
|
|
56
|
+
const keyMaterial = await crypto.subtle.importKey('raw', encoder.encode(secret), 'PBKDF2', false, ['deriveBits']);
|
|
57
|
+
const cipherSalt = process.env.CIPHER_SALT;
|
|
58
|
+
if (!cipherSalt) {
|
|
59
|
+
console.warn('CIPHER_SALT is not set. Using default salt is insecure for multi-deployment use. Set CIPHER_SALT to a unique random value.');
|
|
60
|
+
}
|
|
61
|
+
// Derive 64 bytes: 32 for AES-GCM key + 32 for HMAC blind indexes.
|
|
62
|
+
const bits = await crypto.subtle.deriveBits({
|
|
63
|
+
name: 'PBKDF2',
|
|
64
|
+
salt: encoder.encode(cipherSalt ?? 'fylo-cipher'),
|
|
65
|
+
iterations: 100000,
|
|
66
|
+
hash: 'SHA-256'
|
|
67
|
+
}, keyMaterial, 512);
|
|
68
|
+
const derived = new Uint8Array(bits);
|
|
69
|
+
const key = await crypto.subtle.importKey('raw', derived.slice(0, 32), { name: 'AES-GCM' }, false, ['encrypt', 'decrypt']);
|
|
70
|
+
const legacyCbcKey = await crypto.subtle.importKey('raw', derived.slice(0, 32), { name: 'AES-CBC' }, false, ['decrypt']);
|
|
71
|
+
const hmacKey = await crypto.subtle.importKey('raw', derived.slice(32, 64), { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
72
|
+
Cipher.key = key;
|
|
73
|
+
Cipher.legacyCbcKey = legacyCbcKey;
|
|
74
|
+
Cipher.hmacKey = hmacKey;
|
|
75
|
+
}
|
|
76
|
+
static reset() {
|
|
77
|
+
Cipher.key = null;
|
|
78
|
+
Cipher.legacyCbcKey = null;
|
|
79
|
+
Cipher.hmacKey = null;
|
|
80
|
+
Cipher.collections = new Map();
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Deterministic nonce from HMAC-SHA256 of plaintext, truncated to 12 bytes.
|
|
84
|
+
*/
|
|
85
|
+
static async deriveNonce(plaintext) {
|
|
86
|
+
const encoder = new TextEncoder();
|
|
87
|
+
const sig = await crypto.subtle.sign('HMAC', Cipher.hmacKey, encoder.encode(plaintext));
|
|
88
|
+
return new Uint8Array(sig).slice(0, 12);
|
|
89
|
+
}
|
|
90
|
+
static base64Url(bytes) {
|
|
91
|
+
let binary = '';
|
|
92
|
+
for (let i = 0; i < bytes.length; i += 0x8000) {
|
|
93
|
+
binary += String.fromCharCode(...bytes.slice(i, i + 0x8000));
|
|
94
|
+
}
|
|
95
|
+
return btoa(binary).replace(/\+/g, '-').replace(/\//g, '_').replace(/=+$/, '');
|
|
96
|
+
}
|
|
97
|
+
static fromBase64Url(encoded) {
|
|
98
|
+
const b64 = encoded.replace(/-/g, '+').replace(/_/g, '/');
|
|
99
|
+
const padded = b64 + '='.repeat((4 - (b64.length % 4)) % 4);
|
|
100
|
+
return Uint8Array.from(atob(padded), (c) => c.charCodeAt(0));
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Produces a keyed lookup token for encrypted exact-match indexes.
|
|
104
|
+
*/
|
|
105
|
+
static async blindIndex(value) {
|
|
106
|
+
if (!Cipher.hmacKey)
|
|
107
|
+
throw new Error('Cipher not configured — set ENCRYPTION_KEY env var');
|
|
108
|
+
const sig = await crypto.subtle.sign('HMAC', Cipher.hmacKey, new TextEncoder().encode(value));
|
|
109
|
+
return `idx1.${Cipher.base64Url(new Uint8Array(sig))}`;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Encrypts a value. Returns a URL-safe base64 string (no slashes).
|
|
113
|
+
*
|
|
114
|
+
* @param value - The plaintext to encrypt.
|
|
115
|
+
* @param deterministic - Compatibility mode for legacy deterministic callers.
|
|
116
|
+
* Prefer `blindIndex()` for query indexes and random nonces for stored data.
|
|
117
|
+
*/
|
|
118
|
+
static async encrypt(value, deterministic = false) {
|
|
119
|
+
if (!Cipher.key)
|
|
120
|
+
throw new Error('Cipher not configured — set ENCRYPTION_KEY env var');
|
|
121
|
+
const nonce = deterministic
|
|
122
|
+
? await Cipher.deriveNonce(value)
|
|
123
|
+
: crypto.getRandomValues(new Uint8Array(12));
|
|
124
|
+
const encoder = new TextEncoder();
|
|
125
|
+
const encrypted = await crypto.subtle.encrypt({ name: 'AES-GCM', iv: nonce }, Cipher.key, encoder.encode(value));
|
|
126
|
+
const combined = new Uint8Array(nonce.length + encrypted.byteLength);
|
|
127
|
+
combined.set(nonce);
|
|
128
|
+
combined.set(new Uint8Array(encrypted), nonce.length);
|
|
129
|
+
return `v2.${Cipher.base64Url(combined)}`;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Decrypts a URL-safe base64 encoded value back to plaintext.
|
|
133
|
+
*/
|
|
134
|
+
static async decrypt(encoded) {
|
|
135
|
+
if (!Cipher.key)
|
|
136
|
+
throw new Error('Cipher not configured — set ENCRYPTION_KEY env var');
|
|
137
|
+
if (!encoded.startsWith('v2.'))
|
|
138
|
+
return await Cipher.decryptLegacyCbc(encoded);
|
|
139
|
+
const combined = Cipher.fromBase64Url(encoded.slice(3));
|
|
140
|
+
const nonce = combined.slice(0, 12);
|
|
141
|
+
const ciphertext = combined.slice(12);
|
|
142
|
+
const decrypted = await crypto.subtle.decrypt({ name: 'AES-GCM', iv: nonce }, Cipher.key, ciphertext);
|
|
143
|
+
return new TextDecoder().decode(decrypted);
|
|
144
|
+
}
|
|
145
|
+
static async decryptLegacyCbc(encoded) {
|
|
146
|
+
if (!Cipher.legacyCbcKey)
|
|
147
|
+
throw new Error('Cipher not configured — set ENCRYPTION_KEY env var');
|
|
148
|
+
const combined = Cipher.fromBase64Url(encoded);
|
|
149
|
+
const iv = combined.slice(0, 16);
|
|
150
|
+
const ciphertext = combined.slice(16);
|
|
151
|
+
const decrypted = await crypto.subtle.decrypt({ name: 'AES-CBC', iv }, Cipher.legacyCbcKey, ciphertext);
|
|
152
|
+
return new TextDecoder().decode(decrypted);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=cipher.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cipher.js","sourceRoot":"","sources":["../../src/adapters/cipher.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"collection.js","sourceRoot":"","sources":["../../src/core/collection.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,sBAAsB,CAAC,UAAkB;IACrD,IAAI,CAAC,+BAA+B,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC;QACpD,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAA;IAC9C,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { Cipher } from '../adapters/cipher';
|
|
2
|
+
export class Dir {
|
|
3
|
+
static SLASH_ASCII = '%2F';
|
|
4
|
+
static async extractKeys(collection, _id, data, parentField) {
|
|
5
|
+
const keys = { data: [], indexes: [] };
|
|
6
|
+
const obj = { ...data };
|
|
7
|
+
for (const field in obj) {
|
|
8
|
+
const newField = parentField ? `${parentField}/${field}` : field;
|
|
9
|
+
const fieldValue = obj[field];
|
|
10
|
+
if (fieldValue && typeof fieldValue === 'object' && !Array.isArray(fieldValue)) {
|
|
11
|
+
const items = await this.extractKeys(collection, _id, fieldValue, newField);
|
|
12
|
+
keys.data.push(...items.data);
|
|
13
|
+
keys.indexes.push(...items.indexes);
|
|
14
|
+
continue;
|
|
15
|
+
}
|
|
16
|
+
if (Array.isArray(fieldValue)) {
|
|
17
|
+
if (fieldValue.some((item) => typeof item === 'object')) {
|
|
18
|
+
throw new Error(`Cannot have an array of objects`);
|
|
19
|
+
}
|
|
20
|
+
for (let i = 0; i < fieldValue.length; i++) {
|
|
21
|
+
let val = String(fieldValue[i]).replaceAll('/', this.SLASH_ASCII);
|
|
22
|
+
if (Cipher.isConfigured() && Cipher.isEncryptedField(collection, newField)) {
|
|
23
|
+
val = await Cipher.blindIndex(val);
|
|
24
|
+
}
|
|
25
|
+
keys.data.push(`${_id}/${newField}/${i}/${val}`);
|
|
26
|
+
keys.indexes.push(`${newField}/${i}/${val}/${_id}`);
|
|
27
|
+
}
|
|
28
|
+
continue;
|
|
29
|
+
}
|
|
30
|
+
let val = String(fieldValue).replaceAll('/', this.SLASH_ASCII);
|
|
31
|
+
if (Cipher.isConfigured() && Cipher.isEncryptedField(collection, newField)) {
|
|
32
|
+
val = await Cipher.blindIndex(val);
|
|
33
|
+
}
|
|
34
|
+
keys.data.push(`${_id}/${newField}/${val}`);
|
|
35
|
+
keys.indexes.push(`${newField}/${val}/${_id}`);
|
|
36
|
+
}
|
|
37
|
+
return keys;
|
|
38
|
+
}
|
|
39
|
+
static parseValue(value) {
|
|
40
|
+
try {
|
|
41
|
+
return JSON.parse(value);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return value;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=directory.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"directory.js","sourceRoot":"","sources":["../../src/core/directory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAA;AAE3C,MAAM,OAAO,GAAG;IACJ,MAAM,CAAU,WAAW,GAAG,KAAK,CAAA;IAE3C,MAAM,CAAC,KAAK,CAAC,WAAW,CAAI,UAAkB,EAAE,GAAU,EAAE,IAAO,EAAE,WAAoB;QACrF,MAAM,IAAI,GAA0C,EAAE,IAAI,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;QAC7E,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,EAAyB,CAAA;QAE9C,KAAK,MAAM,KAAK,IAAI,GAAG,EAAE,CAAC;YACtB,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,GAAG,WAAW,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAA;YAChE,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,CAAA;YAE7B,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC7E,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,EAAE,QAAQ,CAAC,CAAA;gBAC3E,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,CAAA;gBAC7B,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAA;gBACnC,SAAQ;YACZ,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC5B,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;oBACtD,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAA;gBACtD,CAAC;gBAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACzC,IAAI,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;oBACjE,IAAI,MAAM,CAAC,YAAY,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;wBACzE,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;oBACtC,CAAC;oBACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,IAAI,CAAC,IAAI,GAAG,EAAE,CAAC,CAAA;oBAChD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,CAAC,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC,CAAA;gBACvD,CAAC;gBACD,SAAQ;YACZ,CAAC;YAED,IAAI,GAAG,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,WAAW,CAAC,CAAA;YAC9D,IAAI,MAAM,CAAC,YAAY,EAAE,IAAI,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACzE,GAAG,GAAG,MAAM,MAAM,CAAC,UAAU,CAAC,GAAG,CAAC,CAAA;YACtC,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,GAAG,IAAI,QAAQ,IAAI,GAAG,EAAE,CAAC,CAAA;YAC3C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,QAAQ,IAAI,GAAG,IAAI,GAAG,EAAE,CAAC,CAAA;QAClD,CAAC;QAED,OAAO,IAAI,CAAA;IACf,CAAC;IAED,MAAM,CAAC,UAAU,CAAC,KAAa;QAC3B,IAAI,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QAC5B,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,KAAK,CAAA;QAChB,CAAC;IACL,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import TTID from '@delma/ttid';
|
|
3
|
+
export function validateDocId(docId) {
|
|
4
|
+
if (!TTID.isTTID(docId))
|
|
5
|
+
throw new Error(`Invalid document ID: ${docId}`);
|
|
6
|
+
}
|
|
7
|
+
export function assertPathInside(parent, target) {
|
|
8
|
+
const resolvedParent = path.resolve(parent);
|
|
9
|
+
const resolvedTarget = path.resolve(target);
|
|
10
|
+
const relative = path.relative(resolvedParent, resolvedTarget);
|
|
11
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
12
|
+
throw new Error(`Unsafe document path: ${target}`);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=doc-id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"doc-id.js","sourceRoot":"","sources":["../../src/core/doc-id.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,IAAI,MAAM,aAAa,CAAA;AAE9B,MAAM,UAAU,aAAa,CAAC,KAAa;IACvC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAA;AAC7E,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAc,EAAE,MAAc;IAC3D,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3C,MAAM,cAAc,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;IAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC,CAAA;IAE9D,IAAI,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QACzD,MAAM,IAAI,KAAK,CAAC,yBAAyB,MAAM,EAAE,CAAC,CAAA;IACtD,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
Object.appendGroup = function (target, source) {
|
|
4
|
+
const result = { ...target };
|
|
5
|
+
for (const [sourceId, sourceGroup] of Object.entries(source)) {
|
|
6
|
+
if (!result[sourceId]) {
|
|
7
|
+
result[sourceId] = sourceGroup;
|
|
8
|
+
continue;
|
|
9
|
+
}
|
|
10
|
+
for (const [groupId, groupDoc] of Object.entries(sourceGroup)) {
|
|
11
|
+
result[sourceId][groupId] = groupDoc;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return result;
|
|
15
|
+
};
|
|
16
|
+
//# sourceMappingURL=extensions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":";AAAA,uDAAuD;AAEvD,MAAM,CAAC,WAAW,GAAG,UACjB,MAA2B,EAC3B,MAA2B;IAE3B,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,EAAE,CAAA;IAE5B,KAAK,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3D,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpB,MAAM,CAAC,QAAQ,CAAC,GAAG,WAAW,CAAA;YAC9B,SAAQ;QACZ,CAAC;QAED,KAAK,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;YAC5D,MAAM,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,GAAG,QAAQ,CAAA;QACxC,CAAC;IACL,CAAC;IAED,OAAO,MAAM,CAAA;AACjB,CAAC,CAAA"}
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import TTID from '@delma/ttid';
|
|
2
|
+
class Format {
|
|
3
|
+
static table(docs) {
|
|
4
|
+
// Calculate the _id column width (considering both the column name and the actual keys)
|
|
5
|
+
const idColumnWidth = Math.max(...Object.keys(docs).map((key) => key.length)) + 2; // Add padding
|
|
6
|
+
const { maxWidths, maxHeight } = this.getHeaderDim(Object.values(docs));
|
|
7
|
+
let key = Object.keys(docs).shift();
|
|
8
|
+
const keys = key.split(',');
|
|
9
|
+
if (TTID.isTTID(key) || keys.some((key) => TTID.isTTID(key ?? ''))) {
|
|
10
|
+
key = '_id';
|
|
11
|
+
}
|
|
12
|
+
else
|
|
13
|
+
key = '_key';
|
|
14
|
+
// Add the _id column to the front of maxWidths
|
|
15
|
+
const fullWidths = {
|
|
16
|
+
[key]: idColumnWidth,
|
|
17
|
+
...maxWidths
|
|
18
|
+
};
|
|
19
|
+
// Render the header
|
|
20
|
+
const header = this.renderHeader(fullWidths, maxHeight, key);
|
|
21
|
+
console.log('\n' + header);
|
|
22
|
+
// Render the data rows
|
|
23
|
+
const dataRows = this.renderDataRows(docs, fullWidths, key);
|
|
24
|
+
console.log(dataRows);
|
|
25
|
+
}
|
|
26
|
+
static getHeaderDim(docs) {
|
|
27
|
+
let maxWidths = {};
|
|
28
|
+
let maxHeight = 1;
|
|
29
|
+
// Create a copy to avoid mutating the original array
|
|
30
|
+
const docsCopy = [...docs];
|
|
31
|
+
while (docsCopy.length > 0) {
|
|
32
|
+
const doc = docsCopy.shift();
|
|
33
|
+
const widths = this.getValueWidth(doc);
|
|
34
|
+
const height = this.getHeaderHeight(doc); // Fix: get height for this doc
|
|
35
|
+
maxHeight = Math.max(maxHeight, height); // Fix: take maximum height
|
|
36
|
+
maxWidths = this.increaseWidths(maxWidths, widths);
|
|
37
|
+
}
|
|
38
|
+
return { maxWidths, maxHeight };
|
|
39
|
+
}
|
|
40
|
+
static getValueWidth(doc) {
|
|
41
|
+
const keyWidths = {};
|
|
42
|
+
for (const key in doc) {
|
|
43
|
+
if (typeof doc[key] === 'object' && doc[key] !== null && !Array.isArray(doc[key])) {
|
|
44
|
+
keyWidths[key] = this.getValueWidth(doc[key]);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
// Consider both the key name length and the value length
|
|
48
|
+
const valueWidth = JSON.stringify(doc[key]).length;
|
|
49
|
+
const keyWidth = key.length;
|
|
50
|
+
// Add padding: 1 space before + content + 1 space after
|
|
51
|
+
keyWidths[key] = Math.max(valueWidth, keyWidth) + 2;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return keyWidths;
|
|
55
|
+
}
|
|
56
|
+
static increaseWidths(oldWidths, newWidths) {
|
|
57
|
+
const increasedWidths = { ...oldWidths };
|
|
58
|
+
for (const key in newWidths) {
|
|
59
|
+
if (oldWidths[key] &&
|
|
60
|
+
typeof newWidths[key] === 'object' &&
|
|
61
|
+
typeof oldWidths[key] === 'object') {
|
|
62
|
+
increasedWidths[key] = this.increaseWidths(oldWidths[key], newWidths[key]);
|
|
63
|
+
}
|
|
64
|
+
else if (oldWidths[key] &&
|
|
65
|
+
typeof newWidths[key] === 'number' &&
|
|
66
|
+
typeof oldWidths[key] === 'number') {
|
|
67
|
+
increasedWidths[key] = Math.max(newWidths[key], oldWidths[key]);
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
increasedWidths[key] = newWidths[key];
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// Handle keys that exist in newWidths but not in oldWidths
|
|
74
|
+
for (const key in newWidths) {
|
|
75
|
+
if (!(key in increasedWidths)) {
|
|
76
|
+
increasedWidths[key] = newWidths[key];
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// Also ensure column family names fit within their total width
|
|
80
|
+
for (const key in increasedWidths) {
|
|
81
|
+
if (typeof increasedWidths[key] === 'object' && increasedWidths[key] !== null) {
|
|
82
|
+
const totalChildWidth = this.calculateTotalWidth(increasedWidths[key]);
|
|
83
|
+
const keyWidth = key.length;
|
|
84
|
+
// If the column family name (with padding) is longer than the total child width,
|
|
85
|
+
// we need to adjust the child column widths proportionally
|
|
86
|
+
const keyWidthWithPadding = keyWidth + 2; // Add padding for family name too
|
|
87
|
+
if (keyWidthWithPadding > totalChildWidth) {
|
|
88
|
+
const childKeys = Object.keys(increasedWidths[key]);
|
|
89
|
+
const extraWidth = keyWidthWithPadding - totalChildWidth;
|
|
90
|
+
const widthPerChild = Math.ceil(extraWidth / childKeys.length);
|
|
91
|
+
for (const childKey of childKeys) {
|
|
92
|
+
if (typeof increasedWidths[key][childKey] === 'number') {
|
|
93
|
+
increasedWidths[key][childKey] += widthPerChild;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return increasedWidths;
|
|
100
|
+
}
|
|
101
|
+
static getHeaderHeight(doc) {
|
|
102
|
+
let maxDepth = 1; // Fix: start with 1 for current level
|
|
103
|
+
for (const key in doc) {
|
|
104
|
+
if (typeof doc[key] === 'object' && doc[key] !== null && !Array.isArray(doc[key])) {
|
|
105
|
+
const nestedDepth = 1 + this.getHeaderHeight(doc[key]); // Fix: add 1 for current level
|
|
106
|
+
maxDepth = Math.max(maxDepth, nestedDepth); // Fix: track maximum depth
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
return maxDepth;
|
|
110
|
+
}
|
|
111
|
+
static renderHeader(widths, height, idColumnKey) {
|
|
112
|
+
const lines = [];
|
|
113
|
+
// Flatten the structure to get all columns
|
|
114
|
+
const columns = this.flattenColumns(widths);
|
|
115
|
+
// Add top border
|
|
116
|
+
lines.push(this.renderTopBorder(columns));
|
|
117
|
+
// Add header content rows
|
|
118
|
+
for (let level = 0; level < height; level++) {
|
|
119
|
+
lines.push(this.renderHeaderRow(widths, level, height, idColumnKey));
|
|
120
|
+
// Add middle border between levels (except after last level)
|
|
121
|
+
if (level < height - 1) {
|
|
122
|
+
lines.push(this.renderMiddleBorder(columns));
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// Add bottom border
|
|
126
|
+
lines.push(this.renderBottomBorder(columns));
|
|
127
|
+
return lines.join('\n');
|
|
128
|
+
}
|
|
129
|
+
static renderDataRows(docs, widths, idColumnKey) {
|
|
130
|
+
const lines = [];
|
|
131
|
+
const columns = this.flattenColumns(widths);
|
|
132
|
+
const entries = Object.entries(docs);
|
|
133
|
+
for (let i = 0; i < entries.length; i++) {
|
|
134
|
+
const [docId, doc] = entries[i];
|
|
135
|
+
// Render data row
|
|
136
|
+
lines.push(this.renderDataRow(docId, doc, widths, columns, idColumnKey));
|
|
137
|
+
// Add separator between rows (except for last row)
|
|
138
|
+
if (i < entries.length - 1) {
|
|
139
|
+
lines.push(this.renderRowSeparator(columns));
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
// Add final bottom border
|
|
143
|
+
lines.push(this.renderBottomBorder(columns));
|
|
144
|
+
return lines.join('\n');
|
|
145
|
+
}
|
|
146
|
+
static renderDataRow(docId, doc, widths, columns, idColumnKey) {
|
|
147
|
+
let line = '│';
|
|
148
|
+
// Handle the ID column (could be _id or another key)
|
|
149
|
+
if (idColumnKey in widths && typeof widths[idColumnKey] === 'number') {
|
|
150
|
+
const contentWidth = widths[idColumnKey] - 2;
|
|
151
|
+
const content = docId;
|
|
152
|
+
const padding = Math.max(0, contentWidth - content.length);
|
|
153
|
+
const leftPad = Math.floor(padding / 2);
|
|
154
|
+
const rightPad = padding - leftPad;
|
|
155
|
+
line += ' ' + ' '.repeat(leftPad) + content + ' '.repeat(rightPad) + ' │';
|
|
156
|
+
}
|
|
157
|
+
// Handle data columns
|
|
158
|
+
for (const column of columns) {
|
|
159
|
+
// Skip the ID column as it's handled separately
|
|
160
|
+
if (column.name === idColumnKey)
|
|
161
|
+
continue;
|
|
162
|
+
const value = this.getNestedValue(doc, column.path);
|
|
163
|
+
const stringValue = this.formatValue(value);
|
|
164
|
+
const contentWidth = column.width - 2; // Subtract padding
|
|
165
|
+
// Truncate if value is too long
|
|
166
|
+
const truncatedValue = stringValue.length > contentWidth
|
|
167
|
+
? stringValue.substring(0, contentWidth - 3) + '...'
|
|
168
|
+
: stringValue;
|
|
169
|
+
const padding = Math.max(0, contentWidth - truncatedValue.length);
|
|
170
|
+
const leftPad = Math.floor(padding / 2);
|
|
171
|
+
const rightPad = padding - leftPad;
|
|
172
|
+
line += ' ' + ' '.repeat(leftPad) + truncatedValue + ' '.repeat(rightPad) + ' │';
|
|
173
|
+
}
|
|
174
|
+
return line;
|
|
175
|
+
}
|
|
176
|
+
static getNestedValue(obj, path) {
|
|
177
|
+
let current = obj;
|
|
178
|
+
for (const key of path) {
|
|
179
|
+
if (current === null || current === undefined || typeof current !== 'object') {
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
current = current[key];
|
|
183
|
+
}
|
|
184
|
+
return current;
|
|
185
|
+
}
|
|
186
|
+
static formatValue(value) {
|
|
187
|
+
if (value === null)
|
|
188
|
+
return 'null';
|
|
189
|
+
if (value === undefined)
|
|
190
|
+
return '';
|
|
191
|
+
if (Array.isArray(value))
|
|
192
|
+
return JSON.stringify(value);
|
|
193
|
+
if (typeof value === 'object')
|
|
194
|
+
return JSON.stringify(value);
|
|
195
|
+
if (typeof value === 'string')
|
|
196
|
+
return value;
|
|
197
|
+
return String(value);
|
|
198
|
+
}
|
|
199
|
+
static renderRowSeparator(columns) {
|
|
200
|
+
let line = '├';
|
|
201
|
+
for (let i = 0; i < columns.length; i++) {
|
|
202
|
+
line += '─'.repeat(columns[i].width);
|
|
203
|
+
if (i < columns.length - 1) {
|
|
204
|
+
line += '┼';
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
line += '┤';
|
|
208
|
+
return line;
|
|
209
|
+
}
|
|
210
|
+
static flattenColumns(widths, path = []) {
|
|
211
|
+
const columns = [];
|
|
212
|
+
for (const key in widths) {
|
|
213
|
+
const currentPath = [...path, key];
|
|
214
|
+
if (typeof widths[key] === 'object' && widths[key] !== null) {
|
|
215
|
+
// Recursively flatten nested objects
|
|
216
|
+
columns.push(...this.flattenColumns(widths[key], currentPath));
|
|
217
|
+
}
|
|
218
|
+
else {
|
|
219
|
+
// This is a leaf column
|
|
220
|
+
columns.push({
|
|
221
|
+
name: key,
|
|
222
|
+
width: widths[key],
|
|
223
|
+
path: currentPath
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
return columns;
|
|
228
|
+
}
|
|
229
|
+
static renderHeaderRow(widths, currentLevel, totalHeight, idColumnKey) {
|
|
230
|
+
let line = '│';
|
|
231
|
+
// Handle the ID column specially (could be _id or another key)
|
|
232
|
+
if (idColumnKey in widths && typeof widths[idColumnKey] === 'number') {
|
|
233
|
+
if (currentLevel === 0) {
|
|
234
|
+
// Show the ID column header at the top level
|
|
235
|
+
const contentWidth = widths[idColumnKey] - 2;
|
|
236
|
+
const headerText = idColumnKey === '_id' ? '_id' : idColumnKey;
|
|
237
|
+
const padding = Math.max(0, contentWidth - headerText.length);
|
|
238
|
+
const leftPad = Math.floor(padding / 2);
|
|
239
|
+
const rightPad = padding - leftPad;
|
|
240
|
+
line += ' ' + ' '.repeat(leftPad) + headerText + ' '.repeat(rightPad) + ' │';
|
|
241
|
+
}
|
|
242
|
+
else {
|
|
243
|
+
// Empty cell for other levels
|
|
244
|
+
line += ' '.repeat(widths[idColumnKey]) + '│';
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
const processLevel = (obj, level, targetLevel) => {
|
|
248
|
+
let result = '';
|
|
249
|
+
for (const key in obj) {
|
|
250
|
+
// Skip the ID column as it's handled separately
|
|
251
|
+
if (key === idColumnKey)
|
|
252
|
+
continue;
|
|
253
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
254
|
+
if (level === targetLevel) {
|
|
255
|
+
// This is a column family at the target level
|
|
256
|
+
const totalWidth = this.calculateTotalWidth(obj[key]);
|
|
257
|
+
const contentWidth = totalWidth - 2; // Subtract padding
|
|
258
|
+
const padding = Math.max(0, contentWidth - key.length);
|
|
259
|
+
const leftPad = Math.floor(padding / 2);
|
|
260
|
+
const rightPad = padding - leftPad;
|
|
261
|
+
// Add 1 space padding + centered content + 1 space padding
|
|
262
|
+
result += ' ' + ' '.repeat(leftPad) + key + ' '.repeat(rightPad) + ' │';
|
|
263
|
+
}
|
|
264
|
+
else if (level < targetLevel) {
|
|
265
|
+
// Recurse deeper
|
|
266
|
+
result += processLevel(obj[key], level + 1, targetLevel);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
if (level === targetLevel) {
|
|
271
|
+
// This is a leaf column at the target level
|
|
272
|
+
const contentWidth = obj[key] - 2; // Subtract padding
|
|
273
|
+
const padding = Math.max(0, contentWidth - key.length);
|
|
274
|
+
const leftPad = Math.floor(padding / 2);
|
|
275
|
+
const rightPad = padding - leftPad;
|
|
276
|
+
// Add 1 space padding + centered content + 1 space padding
|
|
277
|
+
result += ' ' + ' '.repeat(leftPad) + key + ' '.repeat(rightPad) + ' │';
|
|
278
|
+
}
|
|
279
|
+
else if (level < targetLevel) {
|
|
280
|
+
// Empty cell - span the full width
|
|
281
|
+
result += ' '.repeat(obj[key]) + '│';
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return result;
|
|
286
|
+
};
|
|
287
|
+
line += processLevel(widths, 0, currentLevel);
|
|
288
|
+
return line;
|
|
289
|
+
}
|
|
290
|
+
static calculateTotalWidth(obj) {
|
|
291
|
+
let total = 0;
|
|
292
|
+
let columnCount = 0;
|
|
293
|
+
for (const key in obj) {
|
|
294
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
295
|
+
total += this.calculateTotalWidth(obj[key]);
|
|
296
|
+
columnCount += this.countLeafColumns(obj[key]);
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
total += obj[key];
|
|
300
|
+
columnCount++;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Add space for separators between columns (one less than column count)
|
|
304
|
+
return total + Math.max(0, columnCount - 1);
|
|
305
|
+
}
|
|
306
|
+
static countLeafColumns(obj) {
|
|
307
|
+
let count = 0;
|
|
308
|
+
for (const key in obj) {
|
|
309
|
+
if (typeof obj[key] === 'object' && obj[key] !== null) {
|
|
310
|
+
count += this.countLeafColumns(obj[key]);
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
count++;
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return count;
|
|
317
|
+
}
|
|
318
|
+
static renderTopBorder(columns) {
|
|
319
|
+
let line = '┌';
|
|
320
|
+
for (let i = 0; i < columns.length; i++) {
|
|
321
|
+
line += '─'.repeat(columns[i].width);
|
|
322
|
+
if (i < columns.length - 1) {
|
|
323
|
+
line += '┬';
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
line += '┐';
|
|
327
|
+
return line;
|
|
328
|
+
}
|
|
329
|
+
static renderMiddleBorder(columns) {
|
|
330
|
+
let line = '├';
|
|
331
|
+
for (let i = 0; i < columns.length; i++) {
|
|
332
|
+
line += '─'.repeat(columns[i].width);
|
|
333
|
+
if (i < columns.length - 1) {
|
|
334
|
+
line += '┼';
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
line += '┤';
|
|
338
|
+
return line;
|
|
339
|
+
}
|
|
340
|
+
static renderBottomBorder(columns) {
|
|
341
|
+
let line = '└';
|
|
342
|
+
for (let i = 0; i < columns.length; i++) {
|
|
343
|
+
line += '─'.repeat(columns[i].width);
|
|
344
|
+
if (i < columns.length - 1) {
|
|
345
|
+
line += '┴';
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
line += '┘';
|
|
349
|
+
return line;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
console.format = function (docs) {
|
|
353
|
+
Format.table(docs);
|
|
354
|
+
};
|
|
355
|
+
//# sourceMappingURL=format.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format.js","sourceRoot":"","sources":["../../src/core/format.ts"],"names":[],"mappings":"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"}
|