@pgpm/inflection 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
@@ -1,5 +1,5 @@
1
1
  EXTENSION = launchql-inflection
2
- DATA = sql/launchql-inflection--0.4.7.sql
2
+ DATA = sql/launchql-inflection--0.5.0.sql
3
3
 
4
4
  PG_CONFIG = pg_config
5
5
  PGXS := $(shell $(PG_CONFIG) --pgxs)
package/README.md CHANGED
@@ -1,5 +1,465 @@
1
1
  # @pgpm/inflection
2
2
 
3
- String inflection utilities for PostgreSQL naming conventions.
3
+ String inflection utilities for PostgreSQL naming conventions
4
4
 
5
- Provides string transformation functions for converting between different naming conventions (camelCase, snake_case, etc.) in PostgreSQL.
5
+ ## Overview
6
+
7
+ `@pgpm/inflection` provides comprehensive string transformation functions for PostgreSQL, enabling seamless conversion between different naming conventions. This package is essential for code generation, schema introspection, and maintaining consistent naming patterns across your database. It includes pluralization, singularization, case conversion, and slugification utilities.
8
+
9
+ ## Features
10
+
11
+ - **Case Conversion**: Transform between camelCase, PascalCase, snake_case, and kebab-case
12
+ - **Pluralization**: Convert singular words to plural forms with English grammar rules
13
+ - **Singularization**: Convert plural words to singular forms
14
+ - **Slugification**: Create URL-friendly slugs from strings
15
+ - **Rule-Based System**: Extensible inflection rules stored in database table
16
+ - **Uncountable Words**: Handles special cases like "sheep", "fish", "data"
17
+ - **Pure plpgsql**: No external dependencies required
18
+
19
+ ## Installation
20
+
21
+ If you have `pgpm` installed:
22
+
23
+ ```bash
24
+ pgpm install @pgpm/inflection
25
+ pgpm deploy
26
+ ```
27
+
28
+ This is a quick way to get started. The sections below provide more detailed installation options.
29
+
30
+ ### Prerequisites
31
+
32
+ ```bash
33
+ # Install pgpm globally
34
+ npm install -g pgpm
35
+
36
+ # Start PostgreSQL
37
+ pgpm docker start
38
+
39
+ # Set environment variables
40
+ eval "$(pgpm env)"
41
+ ```
42
+
43
+ ### Deploy
44
+
45
+ #### Option 1: Deploy by installing with pgpm
46
+
47
+ ```bash
48
+ pgpm install @pgpm/inflection
49
+ pgpm deploy
50
+ ```
51
+
52
+ #### Option 2: Deploy from Package Directory
53
+
54
+ ```bash
55
+ cd packages/utils/inflection
56
+ pgpm deploy --createdb
57
+ ```
58
+
59
+ #### Option 3: Deploy from Workspace Root
60
+
61
+ ```bash
62
+ # Install workspace dependencies
63
+ pnpm install
64
+
65
+ # Deploy with dependencies
66
+ pgpm deploy mydb1 --yes --createdb
67
+ ```
68
+
69
+ ## Core Functions
70
+
71
+ ### Case Conversion Functions
72
+
73
+ #### inflection.camel(text)
74
+
75
+ Convert string to camelCase.
76
+
77
+ ```sql
78
+ SELECT inflection.camel('user_profile_image');
79
+ -- userProfileImage
80
+
81
+ SELECT inflection.camel('UserProfileImage');
82
+ -- userProfileImage
83
+
84
+ SELECT inflection.camel('user-profile-image');
85
+ -- userProfileImage
86
+ ```
87
+
88
+ #### inflection.pascal(text)
89
+
90
+ Convert string to PascalCase.
91
+
92
+ ```sql
93
+ SELECT inflection.pascal('user_profile_image');
94
+ -- UserProfileImage
95
+
96
+ SELECT inflection.pascal('user-profile-image');
97
+ -- UserProfileImage
98
+ ```
99
+
100
+ #### inflection.underscore(text)
101
+
102
+ Convert string to snake_case.
103
+
104
+ ```sql
105
+ SELECT inflection.underscore('UserProfileImage');
106
+ -- user_profile_image
107
+
108
+ SELECT inflection.underscore('userProfileImage');
109
+ -- user_profile_image
110
+
111
+ SELECT inflection.underscore('user-profile-image');
112
+ -- user_profile_image
113
+ ```
114
+
115
+ #### inflection.dashed(text)
116
+
117
+ Convert string to kebab-case.
118
+
119
+ ```sql
120
+ SELECT inflection.dashed('UserProfileImage');
121
+ -- user-profile-image
122
+
123
+ SELECT inflection.dashed('user_profile_image');
124
+ -- user-profile-image
125
+ ```
126
+
127
+ ### Pluralization Functions
128
+
129
+ #### inflection.plural(text)
130
+
131
+ Convert singular word to plural form.
132
+
133
+ ```sql
134
+ SELECT inflection.plural('user');
135
+ -- users
136
+
137
+ SELECT inflection.plural('person');
138
+ -- people
139
+
140
+ SELECT inflection.plural('child');
141
+ -- children
142
+
143
+ SELECT inflection.plural('category');
144
+ -- categories
145
+
146
+ SELECT inflection.plural('status');
147
+ -- statuses
148
+ ```
149
+
150
+ #### inflection.singular(text)
151
+
152
+ Convert plural word to singular form.
153
+
154
+ ```sql
155
+ SELECT inflection.singular('users');
156
+ -- user
157
+
158
+ SELECT inflection.singular('people');
159
+ -- person
160
+
161
+ SELECT inflection.singular('children');
162
+ -- child
163
+
164
+ SELECT inflection.singular('categories');
165
+ -- category
166
+ ```
167
+
168
+ ### Slugification Functions
169
+
170
+ #### inflection.slugify(text)
171
+
172
+ Create URL-friendly slug from string.
173
+
174
+ ```sql
175
+ SELECT inflection.slugify('Hello World!');
176
+ -- hello-world
177
+
178
+ SELECT inflection.slugify('User Profile & Settings');
179
+ -- user-profile-settings
180
+
181
+ SELECT inflection.slugify(' Multiple Spaces ');
182
+ -- multiple-spaces
183
+ ```
184
+
185
+ ## Usage Examples
186
+
187
+ ### Database Schema Generation
188
+
189
+ Generate table and column names following conventions:
190
+
191
+ ```sql
192
+ -- Convert API field names to database columns
193
+ CREATE TABLE users (
194
+ id uuid PRIMARY KEY,
195
+ user_name text, -- from userName
196
+ email_address text, -- from emailAddress
197
+ created_at timestamptz DEFAULT now()
198
+ );
199
+
200
+ -- Function to convert camelCase to snake_case
201
+ CREATE FUNCTION api_to_db_column(field_name text)
202
+ RETURNS text AS $$
203
+ BEGIN
204
+ RETURN inflection.underscore(field_name);
205
+ END;
206
+ $$ LANGUAGE plpgsql;
207
+
208
+ SELECT api_to_db_column('firstName'); -- first_name
209
+ SELECT api_to_db_column('emailAddress'); -- email_address
210
+ ```
211
+
212
+ ### GraphQL Schema Generation
213
+
214
+ Generate GraphQL type names from database tables:
215
+
216
+ ```sql
217
+ -- Convert table names to GraphQL types
218
+ SELECT inflection.pascal(inflection.singular(table_name)) as graphql_type
219
+ FROM information_schema.tables
220
+ WHERE table_schema = 'public';
221
+
222
+ -- user_profiles → UserProfile
223
+ -- blog_posts → BlogPost
224
+ -- categories → Category
225
+ ```
226
+
227
+ ### REST API Endpoint Generation
228
+
229
+ Create consistent API endpoints:
230
+
231
+ ```sql
232
+ -- Generate REST endpoints from table names
233
+ SELECT
234
+ '/' || inflection.dashed(inflection.plural(table_name)) as endpoint,
235
+ table_name
236
+ FROM information_schema.tables
237
+ WHERE table_schema = 'public';
238
+
239
+ -- users → /users
240
+ -- blog_posts → /blog-posts
241
+ -- user_profiles → /user-profiles
242
+ ```
243
+
244
+ ### Code Generation
245
+
246
+ Generate TypeScript interfaces from database schema:
247
+
248
+ ```sql
249
+ -- Generate TypeScript interface names
250
+ CREATE FUNCTION generate_ts_interface(table_name text)
251
+ RETURNS text AS $$
252
+ BEGIN
253
+ RETURN 'export interface ' ||
254
+ inflection.pascal(inflection.singular(table_name)) ||
255
+ ' {';
256
+ END;
257
+ $$ LANGUAGE plpgsql;
258
+
259
+ SELECT generate_ts_interface('user_profiles');
260
+ -- export interface UserProfile {
261
+ ```
262
+
263
+ ### URL Slug Generation
264
+
265
+ Create SEO-friendly URLs:
266
+
267
+ ```sql
268
+ -- Generate slugs for blog posts
269
+ CREATE TABLE blog_posts (
270
+ id serial PRIMARY KEY,
271
+ title text NOT NULL,
272
+ slug text GENERATED ALWAYS AS (inflection.slugify(title)) STORED,
273
+ content text,
274
+ created_at timestamptz DEFAULT now()
275
+ );
276
+
277
+ INSERT INTO blog_posts (title, content)
278
+ VALUES ('How to Use PostgreSQL', 'Content here...');
279
+
280
+ SELECT slug FROM blog_posts;
281
+ -- how-to-use-postgresql
282
+ ```
283
+
284
+ ## Integration Examples
285
+
286
+ ### With @pgpm/meta-db
287
+
288
+ Use inflection for schema introspection and code generation:
289
+
290
+ ```sql
291
+ -- Generate model names from tables
292
+ SELECT
293
+ table_name,
294
+ inflection.pascal(inflection.singular(table_name)) as model_name,
295
+ inflection.camel(inflection.plural(table_name)) as collection_name
296
+ FROM information_schema.tables
297
+ WHERE table_schema = 'public';
298
+
299
+ -- user_profiles → UserProfile (model), userProfiles (collection)
300
+ -- blog_posts → BlogPost (model), blogPosts (collection)
301
+ ```
302
+
303
+ ### With @pgpm/utils
304
+
305
+ Combine with other utilities for advanced transformations:
306
+
307
+ ```sql
308
+ -- Generate API response field names
309
+ SELECT
310
+ column_name,
311
+ inflection.camel(column_name) as api_field_name
312
+ FROM information_schema.columns
313
+ WHERE table_name = 'users';
314
+
315
+ -- user_name → userName
316
+ -- email_address → emailAddress
317
+ -- created_at → createdAt
318
+ ```
319
+
320
+ ## Inflection Rules
321
+
322
+ The package uses a rule-based system stored in the `inflection.inflection_rules` table:
323
+
324
+ ```sql
325
+ -- View pluralization rules
326
+ SELECT * FROM inflection.inflection_rules WHERE type = 'plural';
327
+
328
+ -- View singularization rules
329
+ SELECT * FROM inflection.inflection_rules WHERE type = 'singular';
330
+ ```
331
+
332
+ ### Adding Custom Rules
333
+
334
+ You can extend the inflection system with custom rules:
335
+
336
+ ```sql
337
+ -- Add custom pluralization rule
338
+ INSERT INTO inflection.inflection_rules (type, test, replacement)
339
+ VALUES ('plural', '(ox)$', '\1en');
340
+
341
+ -- Now "ox" → "oxen"
342
+ SELECT inflection.plural('ox');
343
+ -- oxen
344
+ ```
345
+
346
+ ### Uncountable Words
347
+
348
+ Some words don't change between singular and plural:
349
+
350
+ ```sql
351
+ SELECT inflection.plural('sheep');
352
+ -- sheep
353
+
354
+ SELECT inflection.plural('fish');
355
+ -- fish
356
+
357
+ SELECT inflection.plural('data');
358
+ -- data
359
+ ```
360
+
361
+ ## Use Cases
362
+
363
+ - **ORM Code Generation**: Generate model classes from database tables
364
+ - **API Development**: Convert between database and API naming conventions
365
+ - **GraphQL Schema**: Generate GraphQL types from database schema
366
+ - **Documentation**: Create consistent naming in generated documentation
367
+ - **Migration Scripts**: Transform legacy naming to modern conventions
368
+ - **URL Generation**: Create SEO-friendly slugs for content
369
+ - **Multi-Language Support**: Handle naming conventions across different programming languages
370
+
371
+ ## Testing
372
+
373
+ ```bash
374
+ pnpm test
375
+ ```
376
+
377
+ ## Dependencies
378
+
379
+ - `@pgpm/verify`: Verification utilities
380
+
381
+ ## Development
382
+
383
+ See the [Development](#development-1) section below for information on working with this package.
384
+
385
+ ---
386
+
387
+ ## Development
388
+
389
+ ### **Before You Begin**
390
+
391
+ ```bash
392
+ # 1. Install pgpm
393
+ npm install -g pgpm
394
+
395
+ # 2. Start Postgres (Docker or local)
396
+ pgpm docker start
397
+
398
+ # 3. Load PG* environment variables (PGHOST, PGUSER, ...)
399
+ eval "$(pgpm env)"
400
+ ```
401
+
402
+ ---
403
+
404
+ ### **Starting a New Project**
405
+
406
+ ```bash
407
+ # 1. Create a workspace
408
+ pgpm init --workspace
409
+ cd my-app
410
+
411
+ # 2. Create your first module
412
+ pgpm init
413
+
414
+ # 3. Add a migration
415
+ pgpm add some_change
416
+
417
+ # 4. Deploy (auto-creates database)
418
+ pgpm deploy --createdb
419
+ ```
420
+
421
+ ---
422
+
423
+ ### **Working With an Existing Project**
424
+
425
+ ```bash
426
+ # 1. Clone and enter the project
427
+ git clone <repo> && cd <project>
428
+
429
+ # 2. Install dependencies
430
+ pnpm install
431
+
432
+ # 3. Deploy locally
433
+ pgpm deploy --createdb
434
+ ```
435
+
436
+ ---
437
+
438
+ ### **Testing a Module Inside a Workspace**
439
+
440
+ ```bash
441
+ # 1. Install workspace deps
442
+ pnpm install
443
+
444
+ # 2. Enter the module directory
445
+ cd packages/<some-module>
446
+
447
+ # 3. Run tests in watch mode
448
+ pnpm test:watch
449
+ ```
450
+
451
+ ## Related Tooling
452
+
453
+ * [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.
454
+ * [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.
455
+ * [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.
456
+ * [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.
457
+ * [pgsql-parser](https://github.com/launchql/pgsql-parser): **🔄 SQL conversion engine** that interprets and converts PostgreSQL syntax.
458
+ * [libpg-query-node](https://github.com/launchql/libpg-query-node): **🌉 Node.js bindings** for `libpg_query`, converting SQL into parse trees.
459
+ * [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.
460
+
461
+ ## Disclaimer
462
+
463
+ AS DESCRIBED IN THE LICENSES, THE SOFTWARE IS PROVIDED "AS IS", AT YOUR OWN RISK, AND WITHOUT WARRANTIES OF ANY KIND.
464
+
465
+ 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.
@@ -1,6 +1,6 @@
1
1
  # launchql-inflection extension
2
2
  comment = 'launchql-inflection extension'
3
- default_version = '0.4.7'
3
+ default_version = '0.5.0'
4
4
  module_pathname = '$libdir/launchql-inflection'
5
5
  requires = 'plpgsql,unaccent,uuid-ossp,launchql-verify'
6
6
  relocatable = false
package/package.json CHANGED
@@ -1,28 +1,28 @@
1
1
  {
2
2
  "name": "@pgpm/inflection",
3
- "version": "0.4.0",
3
+ "version": "0.6.0",
4
4
  "description": "String inflection utilities for PostgreSQL naming conventions",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
8
8
  "scripts": {
9
- "bundle": "lql package",
9
+ "bundle": "pgpm package",
10
10
  "test": "jest",
11
11
  "test:watch": "jest --watch"
12
12
  },
13
13
  "dependencies": {
14
- "@pgpm/verify": "0.4.0"
14
+ "@pgpm/verify": "0.6.0"
15
15
  },
16
16
  "devDependencies": {
17
- "@launchql/cli": "^4.9.0"
17
+ "pgpm": "^0.2.0"
18
18
  },
19
19
  "repository": {
20
20
  "type": "git",
21
- "url": "https://github.com/launchql/extensions"
21
+ "url": "https://github.com/launchql/pgpm-modules"
22
22
  },
23
- "homepage": "https://github.com/launchql/extensions",
23
+ "homepage": "https://github.com/launchql/pgpm-modules",
24
24
  "bugs": {
25
- "url": "https://github.com/launchql/extensions/issues"
25
+ "url": "https://github.com/launchql/pgpm-modules/issues"
26
26
  },
27
- "gitHead": "cc9f52a335caa6e21ee7751b04b77c84ce6cb809"
27
+ "gitHead": "c7d0eae588d7a764b382a330c8b853b341b13fb2"
28
28
  }
File without changes