@pgpm/utils 0.4.0 → 0.6.0
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/Makefile
CHANGED
package/README.md
CHANGED
|
@@ -1,5 +1,468 @@
|
|
|
1
1
|
# @pgpm/utils
|
|
2
2
|
|
|
3
|
-
General utility functions for PostgreSQL extensions
|
|
3
|
+
General utility functions for PostgreSQL extensions
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
`@pgpm/utils` provides essential utility functions and helper procedures used across LaunchQL extension modules. This package includes functions for error handling, data masking, and singleton pattern enforcement. These utilities form the foundation for building robust PostgreSQL extensions with consistent error handling and data protection patterns.
|
|
8
|
+
|
|
9
|
+
## Features
|
|
10
|
+
|
|
11
|
+
- **Error Handling**: Throw custom exceptions with detailed messages
|
|
12
|
+
- **Data Masking**: Mask sensitive data with padding characters
|
|
13
|
+
- **Singleton Enforcement**: Ensure tables contain exactly one row
|
|
14
|
+
- **Reusable Utilities**: Common functions used across multiple extensions
|
|
15
|
+
- **Pure plpgsql**: No external dependencies required
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
If you have `pgpm` installed:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pgpm install @pgpm/utils
|
|
23
|
+
pgpm deploy
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
This is a quick way to get started. The sections below provide more detailed installation options.
|
|
27
|
+
|
|
28
|
+
### Prerequisites
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# Install pgpm globally
|
|
32
|
+
npm install -g pgpm
|
|
33
|
+
|
|
34
|
+
# Start PostgreSQL
|
|
35
|
+
pgpm docker start
|
|
36
|
+
|
|
37
|
+
# Set environment variables
|
|
38
|
+
eval "$(pgpm env)"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Deploy
|
|
42
|
+
|
|
43
|
+
#### Option 1: Deploy by installing with pgpm
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
pgpm install @pgpm/utils
|
|
47
|
+
pgpm deploy
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
#### Option 2: Deploy from Package Directory
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
cd packages/utils/utils
|
|
54
|
+
pgpm deploy --createdb
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
#### Option 3: Deploy from Workspace Root
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
# Install workspace dependencies
|
|
61
|
+
pnpm install
|
|
62
|
+
|
|
63
|
+
# Deploy with dependencies
|
|
64
|
+
pgpm deploy mydb1 --yes --createdb
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## Core Functions
|
|
68
|
+
|
|
69
|
+
### utils.throw(message text)
|
|
70
|
+
|
|
71
|
+
Throw a custom exception with a specific message.
|
|
72
|
+
|
|
73
|
+
**Signature:**
|
|
74
|
+
```sql
|
|
75
|
+
utils.throw(message text) RETURNS void
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
**Usage:**
|
|
79
|
+
```sql
|
|
80
|
+
-- Throw an error
|
|
81
|
+
SELECT utils.throw('Invalid user ID provided');
|
|
82
|
+
-- ERROR: Invalid user ID provided
|
|
83
|
+
|
|
84
|
+
-- Use in conditional logic
|
|
85
|
+
DO $$
|
|
86
|
+
BEGIN
|
|
87
|
+
IF NOT EXISTS (SELECT 1 FROM users WHERE id = 'some-uuid') THEN
|
|
88
|
+
PERFORM utils.throw('User not found');
|
|
89
|
+
END IF;
|
|
90
|
+
END $$;
|
|
91
|
+
|
|
92
|
+
-- Use in functions
|
|
93
|
+
CREATE FUNCTION validate_email(email text)
|
|
94
|
+
RETURNS boolean AS $$
|
|
95
|
+
BEGIN
|
|
96
|
+
IF email !~ '^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}$' THEN
|
|
97
|
+
PERFORM utils.throw('Invalid email format: ' || email);
|
|
98
|
+
END IF;
|
|
99
|
+
RETURN true;
|
|
100
|
+
END;
|
|
101
|
+
$$ LANGUAGE plpgsql;
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### utils.mask_pad(value text, visible_chars int, pad_char text)
|
|
105
|
+
|
|
106
|
+
Mask sensitive data by showing only a specified number of characters and padding the rest.
|
|
107
|
+
|
|
108
|
+
**Signature:**
|
|
109
|
+
```sql
|
|
110
|
+
utils.mask_pad(
|
|
111
|
+
value text,
|
|
112
|
+
visible_chars int DEFAULT 4,
|
|
113
|
+
pad_char text DEFAULT '*'
|
|
114
|
+
) RETURNS text
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
**Parameters:**
|
|
118
|
+
- `value`: The text to mask
|
|
119
|
+
- `visible_chars`: Number of characters to show at the end (default: 4)
|
|
120
|
+
- `pad_char`: Character to use for masking (default: '*')
|
|
121
|
+
|
|
122
|
+
**Usage:**
|
|
123
|
+
```sql
|
|
124
|
+
-- Mask credit card number
|
|
125
|
+
SELECT utils.mask_pad('4532123456789012', 4, '*');
|
|
126
|
+
-- ************9012
|
|
127
|
+
|
|
128
|
+
-- Mask email
|
|
129
|
+
SELECT utils.mask_pad('user@example.com', 6, 'x');
|
|
130
|
+
-- xxxxxxxxple.com
|
|
131
|
+
|
|
132
|
+
-- Mask phone number
|
|
133
|
+
SELECT utils.mask_pad('+1-555-123-4567', 4, '#');
|
|
134
|
+
-- ###########4567
|
|
135
|
+
|
|
136
|
+
-- Use in queries
|
|
137
|
+
SELECT
|
|
138
|
+
user_id,
|
|
139
|
+
utils.mask_pad(credit_card, 4, '*') as masked_card,
|
|
140
|
+
utils.mask_pad(ssn, 4, 'X') as masked_ssn
|
|
141
|
+
FROM sensitive_data;
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### utils.ensure_singleton()
|
|
145
|
+
|
|
146
|
+
Trigger function to ensure a table contains exactly one row.
|
|
147
|
+
|
|
148
|
+
**Signature:**
|
|
149
|
+
```sql
|
|
150
|
+
utils.ensure_singleton() RETURNS trigger
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Usage:**
|
|
154
|
+
```sql
|
|
155
|
+
-- Create a settings table that should only have one row
|
|
156
|
+
CREATE TABLE app_settings (
|
|
157
|
+
id int PRIMARY KEY DEFAULT 1,
|
|
158
|
+
app_name text NOT NULL,
|
|
159
|
+
max_users int DEFAULT 100,
|
|
160
|
+
maintenance_mode boolean DEFAULT false,
|
|
161
|
+
updated_at timestamptz DEFAULT now(),
|
|
162
|
+
CONSTRAINT singleton_check CHECK (id = 1)
|
|
163
|
+
);
|
|
164
|
+
|
|
165
|
+
-- Add trigger to enforce singleton pattern
|
|
166
|
+
CREATE TRIGGER ensure_singleton_trigger
|
|
167
|
+
BEFORE INSERT OR UPDATE ON app_settings
|
|
168
|
+
FOR EACH ROW
|
|
169
|
+
EXECUTE FUNCTION utils.ensure_singleton();
|
|
170
|
+
|
|
171
|
+
-- First insert works
|
|
172
|
+
INSERT INTO app_settings (app_name) VALUES ('My App');
|
|
173
|
+
|
|
174
|
+
-- Second insert fails
|
|
175
|
+
INSERT INTO app_settings (app_name) VALUES ('Another App');
|
|
176
|
+
-- ERROR: Table app_settings can only contain one row
|
|
177
|
+
|
|
178
|
+
-- Updates work fine
|
|
179
|
+
UPDATE app_settings SET max_users = 200;
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
## Usage Examples
|
|
183
|
+
|
|
184
|
+
### Error Handling in Business Logic
|
|
185
|
+
|
|
186
|
+
Use `utils.throw()` for consistent error handling:
|
|
187
|
+
|
|
188
|
+
```sql
|
|
189
|
+
CREATE FUNCTION process_payment(
|
|
190
|
+
user_id uuid,
|
|
191
|
+
amount numeric
|
|
192
|
+
) RETURNS void AS $$
|
|
193
|
+
DECLARE
|
|
194
|
+
user_balance numeric;
|
|
195
|
+
BEGIN
|
|
196
|
+
-- Check if user exists
|
|
197
|
+
IF NOT EXISTS (SELECT 1 FROM users WHERE id = user_id) THEN
|
|
198
|
+
PERFORM utils.throw('User not found: ' || user_id);
|
|
199
|
+
END IF;
|
|
200
|
+
|
|
201
|
+
-- Check balance
|
|
202
|
+
SELECT balance INTO user_balance FROM accounts WHERE user_id = user_id;
|
|
203
|
+
|
|
204
|
+
IF user_balance IS NULL THEN
|
|
205
|
+
PERFORM utils.throw('Account not found for user: ' || user_id);
|
|
206
|
+
END IF;
|
|
207
|
+
|
|
208
|
+
IF user_balance < amount THEN
|
|
209
|
+
PERFORM utils.throw('Insufficient funds. Balance: ' || user_balance || ', Required: ' || amount);
|
|
210
|
+
END IF;
|
|
211
|
+
|
|
212
|
+
-- Process payment
|
|
213
|
+
UPDATE accounts SET balance = balance - amount WHERE user_id = user_id;
|
|
214
|
+
END;
|
|
215
|
+
$$ LANGUAGE plpgsql;
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### Data Masking for Privacy
|
|
219
|
+
|
|
220
|
+
Protect sensitive data in logs and reports:
|
|
221
|
+
|
|
222
|
+
```sql
|
|
223
|
+
-- Create view with masked data for reporting
|
|
224
|
+
CREATE VIEW user_report AS
|
|
225
|
+
SELECT
|
|
226
|
+
id,
|
|
227
|
+
username,
|
|
228
|
+
utils.mask_pad(email, 8, '*') as email,
|
|
229
|
+
utils.mask_pad(phone, 4, 'X') as phone,
|
|
230
|
+
utils.mask_pad(credit_card, 4, '*') as credit_card,
|
|
231
|
+
created_at
|
|
232
|
+
FROM users;
|
|
233
|
+
|
|
234
|
+
-- Audit log with masked sensitive data
|
|
235
|
+
CREATE FUNCTION log_user_access(user_id uuid)
|
|
236
|
+
RETURNS void AS $$
|
|
237
|
+
DECLARE
|
|
238
|
+
user_email text;
|
|
239
|
+
BEGIN
|
|
240
|
+
SELECT email INTO user_email FROM users WHERE id = user_id;
|
|
241
|
+
|
|
242
|
+
INSERT INTO access_logs (user_id, masked_email, accessed_at)
|
|
243
|
+
VALUES (user_id, utils.mask_pad(user_email, 6, '*'), now());
|
|
244
|
+
END;
|
|
245
|
+
$$ LANGUAGE plpgsql;
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
### Singleton Configuration Tables
|
|
249
|
+
|
|
250
|
+
Ensure configuration tables have exactly one row:
|
|
251
|
+
|
|
252
|
+
```sql
|
|
253
|
+
-- System configuration table
|
|
254
|
+
CREATE TABLE system_config (
|
|
255
|
+
id int PRIMARY KEY DEFAULT 1,
|
|
256
|
+
site_name text NOT NULL,
|
|
257
|
+
admin_email text NOT NULL,
|
|
258
|
+
max_upload_size_mb int DEFAULT 10,
|
|
259
|
+
enable_registration boolean DEFAULT true,
|
|
260
|
+
created_at timestamptz DEFAULT now(),
|
|
261
|
+
updated_at timestamptz DEFAULT now(),
|
|
262
|
+
CONSTRAINT singleton_check CHECK (id = 1)
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
CREATE TRIGGER ensure_singleton_trigger
|
|
266
|
+
BEFORE INSERT OR UPDATE ON system_config
|
|
267
|
+
FOR EACH ROW
|
|
268
|
+
EXECUTE FUNCTION utils.ensure_singleton();
|
|
269
|
+
|
|
270
|
+
-- Initialize with default values
|
|
271
|
+
INSERT INTO system_config (site_name, admin_email)
|
|
272
|
+
VALUES ('My Application', 'admin@example.com');
|
|
273
|
+
|
|
274
|
+
-- Helper function to get config
|
|
275
|
+
CREATE FUNCTION get_config()
|
|
276
|
+
RETURNS system_config AS $$
|
|
277
|
+
SELECT * FROM system_config LIMIT 1;
|
|
278
|
+
$$ LANGUAGE sql STABLE;
|
|
279
|
+
|
|
280
|
+
-- Helper function to update config
|
|
281
|
+
CREATE FUNCTION update_config(
|
|
282
|
+
p_site_name text DEFAULT NULL,
|
|
283
|
+
p_admin_email text DEFAULT NULL,
|
|
284
|
+
p_max_upload_size_mb int DEFAULT NULL
|
|
285
|
+
) RETURNS void AS $$
|
|
286
|
+
BEGIN
|
|
287
|
+
UPDATE system_config SET
|
|
288
|
+
site_name = COALESCE(p_site_name, site_name),
|
|
289
|
+
admin_email = COALESCE(p_admin_email, admin_email),
|
|
290
|
+
max_upload_size_mb = COALESCE(p_max_upload_size_mb, max_upload_size_mb),
|
|
291
|
+
updated_at = now();
|
|
292
|
+
END;
|
|
293
|
+
$$ LANGUAGE plpgsql;
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Integration Examples
|
|
297
|
+
|
|
298
|
+
### With @pgpm/encrypted-secrets
|
|
299
|
+
|
|
300
|
+
Combine error handling with secrets management:
|
|
301
|
+
|
|
302
|
+
```sql
|
|
303
|
+
CREATE FUNCTION get_api_key(service_name text)
|
|
304
|
+
RETURNS text AS $$
|
|
305
|
+
DECLARE
|
|
306
|
+
api_key text;
|
|
307
|
+
BEGIN
|
|
308
|
+
api_key := encrypted_secrets.secrets_getter(
|
|
309
|
+
current_user_id(),
|
|
310
|
+
service_name
|
|
311
|
+
);
|
|
312
|
+
|
|
313
|
+
IF api_key IS NULL THEN
|
|
314
|
+
PERFORM utils.throw('API key not found for service: ' || service_name);
|
|
315
|
+
END IF;
|
|
316
|
+
|
|
317
|
+
RETURN api_key;
|
|
318
|
+
END;
|
|
319
|
+
$$ LANGUAGE plpgsql;
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### With @pgpm/jobs
|
|
323
|
+
|
|
324
|
+
Use error handling in job processing:
|
|
325
|
+
|
|
326
|
+
```sql
|
|
327
|
+
CREATE FUNCTION process_job_with_validation(job_id int)
|
|
328
|
+
RETURNS void AS $$
|
|
329
|
+
DECLARE
|
|
330
|
+
job_data jsonb;
|
|
331
|
+
BEGIN
|
|
332
|
+
SELECT payload INTO job_data FROM app_jobs.jobs WHERE id = job_id;
|
|
333
|
+
|
|
334
|
+
IF job_data IS NULL THEN
|
|
335
|
+
PERFORM utils.throw('Job not found: ' || job_id);
|
|
336
|
+
END IF;
|
|
337
|
+
|
|
338
|
+
IF NOT (job_data ? 'email') THEN
|
|
339
|
+
PERFORM utils.throw('Job payload missing required field: email');
|
|
340
|
+
END IF;
|
|
341
|
+
|
|
342
|
+
-- Process job
|
|
343
|
+
-- ...
|
|
344
|
+
END;
|
|
345
|
+
$$ LANGUAGE plpgsql;
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### With @pgpm/achievements
|
|
349
|
+
|
|
350
|
+
Mask user data in achievement displays:
|
|
351
|
+
|
|
352
|
+
```sql
|
|
353
|
+
CREATE VIEW public_achievements AS
|
|
354
|
+
SELECT
|
|
355
|
+
utils.mask_pad(u.email, 8, '*') as masked_email,
|
|
356
|
+
a.achievement_name,
|
|
357
|
+
a.count,
|
|
358
|
+
a.achieved_at
|
|
359
|
+
FROM user_achievements a
|
|
360
|
+
JOIN users u ON u.id = a.user_id
|
|
361
|
+
WHERE a.achieved_at IS NOT NULL;
|
|
362
|
+
```
|
|
363
|
+
|
|
364
|
+
## Use Cases
|
|
365
|
+
|
|
366
|
+
- **Error Handling**: Consistent exception throwing across extensions
|
|
367
|
+
- **Data Privacy**: Mask sensitive information in logs and reports
|
|
368
|
+
- **Configuration Management**: Singleton tables for application settings
|
|
369
|
+
- **Validation**: Input validation with clear error messages
|
|
370
|
+
- **Audit Logging**: Log events with masked sensitive data
|
|
371
|
+
- **API Responses**: Return masked data to clients
|
|
372
|
+
- **Development**: Shared utilities for extension development
|
|
373
|
+
|
|
374
|
+
## Testing
|
|
375
|
+
|
|
376
|
+
```bash
|
|
377
|
+
pnpm test
|
|
378
|
+
```
|
|
379
|
+
|
|
380
|
+
## Dependencies
|
|
381
|
+
|
|
382
|
+
- `@pgpm/verify`: Verification utilities
|
|
383
|
+
|
|
384
|
+
## Development
|
|
385
|
+
|
|
386
|
+
See the [Development](#development-1) section below for information on working with this package.
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Development
|
|
391
|
+
|
|
392
|
+
### **Before You Begin**
|
|
393
|
+
|
|
394
|
+
```bash
|
|
395
|
+
# 1. Install pgpm
|
|
396
|
+
npm install -g pgpm
|
|
397
|
+
|
|
398
|
+
# 2. Start Postgres (Docker or local)
|
|
399
|
+
pgpm docker start
|
|
400
|
+
|
|
401
|
+
# 3. Load PG* environment variables (PGHOST, PGUSER, ...)
|
|
402
|
+
eval "$(pgpm env)"
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
---
|
|
406
|
+
|
|
407
|
+
### **Starting a New Project**
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
# 1. Create a workspace
|
|
411
|
+
pgpm init --workspace
|
|
412
|
+
cd my-app
|
|
413
|
+
|
|
414
|
+
# 2. Create your first module
|
|
415
|
+
pgpm init
|
|
416
|
+
|
|
417
|
+
# 3. Add a migration
|
|
418
|
+
pgpm add some_change
|
|
419
|
+
|
|
420
|
+
# 4. Deploy (auto-creates database)
|
|
421
|
+
pgpm deploy --createdb
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
### **Working With an Existing Project**
|
|
427
|
+
|
|
428
|
+
```bash
|
|
429
|
+
# 1. Clone and enter the project
|
|
430
|
+
git clone <repo> && cd <project>
|
|
431
|
+
|
|
432
|
+
# 2. Install dependencies
|
|
433
|
+
pnpm install
|
|
434
|
+
|
|
435
|
+
# 3. Deploy locally
|
|
436
|
+
pgpm deploy --createdb
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
---
|
|
440
|
+
|
|
441
|
+
### **Testing a Module Inside a Workspace**
|
|
442
|
+
|
|
443
|
+
```bash
|
|
444
|
+
# 1. Install workspace deps
|
|
445
|
+
pnpm install
|
|
446
|
+
|
|
447
|
+
# 2. Enter the module directory
|
|
448
|
+
cd packages/<some-module>
|
|
449
|
+
|
|
450
|
+
# 3. Run tests in watch mode
|
|
451
|
+
pnpm test:watch
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Related Tooling
|
|
455
|
+
|
|
456
|
+
* [pgpm](https://github.com/launchql/launchql/tree/main/packages/pgpm): **🖥️ PostgreSQL Package Manager** for modular Postgres development. Works with database workspaces, scaffolding, migrations, seeding, and installing database packages.
|
|
457
|
+
* [pgsql-test](https://github.com/launchql/launchql/tree/main/packages/pgsql-test): **📊 Isolated testing environments** with per-test transaction rollbacks—ideal for integration tests, complex migrations, and RLS simulation.
|
|
458
|
+
* [supabase-test](https://github.com/launchql/launchql/tree/main/packages/supabase-test): **🧪 Supabase-native test harness** preconfigured for the local Supabase stack—per-test rollbacks, JWT/role context helpers, and CI/GitHub Actions ready.
|
|
459
|
+
* [graphile-test](https://github.com/launchql/launchql/tree/main/packages/graphile-test): **🔐 Authentication mocking** for Graphile-focused test helpers and emulating row-level security contexts.
|
|
460
|
+
* [pgsql-parser](https://github.com/launchql/pgsql-parser): **🔄 SQL conversion engine** that interprets and converts PostgreSQL syntax.
|
|
461
|
+
* [libpg-query-node](https://github.com/launchql/libpg-query-node): **🌉 Node.js bindings** for `libpg_query`, converting SQL into parse trees.
|
|
462
|
+
* [pg-proto-parser](https://github.com/launchql/pg-proto-parser): **📦 Protobuf parser** for parsing PostgreSQL Protocol Buffers definitions to generate TypeScript interfaces, utility functions, and JSON mappings for enums.
|
|
463
|
+
|
|
464
|
+
## Disclaimer
|
|
465
|
+
|
|
466
|
+
AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
|
|
467
|
+
|
|
468
|
+
No developer or entity involved in creating this software will be liable for any claims or damages whatsoever associated with your use, inability to use, or your interaction with other users of the code, including any direct, indirect, incidental, special, exemplary, punitive or consequential damages, or loss of profits, cryptocurrencies, tokens, or anything else of value.
|
package/launchql-utils.control
CHANGED
package/package.json
CHANGED
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgpm/utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "General utility functions for PostgreSQL extensions",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"scripts": {
|
|
9
|
-
"bundle": "
|
|
9
|
+
"bundle": "pgpm package",
|
|
10
10
|
"test": "jest",
|
|
11
11
|
"test:watch": "jest --watch"
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@pgpm/verify": "0.
|
|
14
|
+
"@pgpm/verify": "0.6.0"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"
|
|
17
|
+
"pgpm": "^0.2.0"
|
|
18
18
|
},
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
21
|
-
"url": "https://github.com/launchql/
|
|
21
|
+
"url": "https://github.com/launchql/pgpm-modules"
|
|
22
22
|
},
|
|
23
|
-
"homepage": "https://github.com/launchql/
|
|
23
|
+
"homepage": "https://github.com/launchql/pgpm-modules",
|
|
24
24
|
"bugs": {
|
|
25
|
-
"url": "https://github.com/launchql/
|
|
25
|
+
"url": "https://github.com/launchql/pgpm-modules/issues"
|
|
26
26
|
},
|
|
27
|
-
"gitHead": "
|
|
27
|
+
"gitHead": "c7d0eae588d7a764b382a330c8b853b341b13fb2"
|
|
28
28
|
}
|
|
File without changes
|
|
File without changes
|