@sudobility/entity_service 1.0.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/CLAUDE.md +124 -0
- package/dist/helpers/EntityHelper.cjs +234 -0
- package/dist/helpers/EntityHelper.d.ts +60 -0
- package/dist/helpers/EntityHelper.d.ts.map +1 -0
- package/dist/helpers/EntityHelper.js +234 -0
- package/dist/helpers/EntityHelper.js.map +1 -0
- package/dist/helpers/EntityMemberHelper.cjs +215 -0
- package/dist/helpers/EntityMemberHelper.d.ts +45 -0
- package/dist/helpers/EntityMemberHelper.d.ts.map +1 -0
- package/dist/helpers/EntityMemberHelper.js +215 -0
- package/dist/helpers/EntityMemberHelper.js.map +1 -0
- package/dist/helpers/InvitationHelper.cjs +251 -0
- package/dist/helpers/InvitationHelper.d.ts +59 -0
- package/dist/helpers/InvitationHelper.d.ts.map +1 -0
- package/dist/helpers/InvitationHelper.js +251 -0
- package/dist/helpers/InvitationHelper.js.map +1 -0
- package/dist/helpers/PermissionHelper.cjs +197 -0
- package/dist/helpers/PermissionHelper.d.ts +86 -0
- package/dist/helpers/PermissionHelper.d.ts.map +1 -0
- package/dist/helpers/PermissionHelper.js +197 -0
- package/dist/helpers/PermissionHelper.js.map +1 -0
- package/dist/helpers/index.cjs +15 -0
- package/dist/helpers/index.d.ts +8 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +15 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/index.cjs +76 -0
- package/dist/index.d.ts +36 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +76 -0
- package/dist/index.js.map +1 -0
- package/dist/middleware/hono.cjs +148 -0
- package/dist/middleware/hono.d.ts +102 -0
- package/dist/middleware/hono.d.ts.map +1 -0
- package/dist/middleware/hono.js +148 -0
- package/dist/middleware/hono.js.map +1 -0
- package/dist/middleware/index.cjs +12 -0
- package/dist/middleware/index.d.ts +5 -0
- package/dist/middleware/index.d.ts.map +1 -0
- package/dist/middleware/index.js +12 -0
- package/dist/middleware/index.js.map +1 -0
- package/dist/migrations/001_add_entities.cjs +269 -0
- package/dist/migrations/001_add_entities.d.ts +29 -0
- package/dist/migrations/001_add_entities.d.ts.map +1 -0
- package/dist/migrations/001_add_entities.js +269 -0
- package/dist/migrations/001_add_entities.js.map +1 -0
- package/dist/migrations/index.cjs +10 -0
- package/dist/migrations/index.d.ts +5 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +10 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/schema/entities.cjs +304 -0
- package/dist/schema/entities.d.ts +1047 -0
- package/dist/schema/entities.d.ts.map +1 -0
- package/dist/schema/entities.js +304 -0
- package/dist/schema/entities.js.map +1 -0
- package/dist/types/index.cjs +14 -0
- package/dist/types/index.d.ts +71 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +14 -0
- package/dist/types/index.js.map +1 -0
- package/dist/utils/index.cjs +21 -0
- package/dist/utils/index.d.ts +5 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +21 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/slug-generator.cjs +92 -0
- package/dist/utils/slug-generator.d.ts +41 -0
- package/dist/utils/slug-generator.d.ts.map +1 -0
- package/dist/utils/slug-generator.js +92 -0
- package/dist/utils/slug-generator.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* @fileoverview Entity Slug Generation Utilities
|
|
4
|
+
* @description Functions for generating unique entity slugs and invitation tokens
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.generateEntitySlug = generateEntitySlug;
|
|
8
|
+
exports.generateInvitationToken = generateInvitationToken;
|
|
9
|
+
exports.normalizeSlug = normalizeSlug;
|
|
10
|
+
exports.validateSlug = validateSlug;
|
|
11
|
+
exports.generateUniqueSlug = generateUniqueSlug;
|
|
12
|
+
exports.calculateInvitationExpiry = calculateInvitationExpiry;
|
|
13
|
+
/** Characters allowed in entity slugs (lowercase alphanumeric) */
|
|
14
|
+
const SLUG_CHARS = 'abcdefghijklmnopqrstuvwxyz0123456789';
|
|
15
|
+
/** Default length for generated entity slugs */
|
|
16
|
+
const DEFAULT_SLUG_LENGTH = 8;
|
|
17
|
+
/** Length for invitation tokens (hex characters) */
|
|
18
|
+
const INVITATION_TOKEN_LENGTH = 32;
|
|
19
|
+
/**
|
|
20
|
+
* Generate a random entity slug.
|
|
21
|
+
* @param length - Length of the slug (default 8, max 12)
|
|
22
|
+
* @returns A random alphanumeric slug
|
|
23
|
+
*/
|
|
24
|
+
function generateEntitySlug(length = DEFAULT_SLUG_LENGTH) {
|
|
25
|
+
const actualLength = Math.min(Math.max(length, 8), 12);
|
|
26
|
+
let slug = '';
|
|
27
|
+
for (let i = 0; i < actualLength; i++) {
|
|
28
|
+
slug += SLUG_CHARS[Math.floor(Math.random() * SLUG_CHARS.length)];
|
|
29
|
+
}
|
|
30
|
+
return slug;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Generate a unique invitation token.
|
|
34
|
+
* @returns A 64-character hex string
|
|
35
|
+
*/
|
|
36
|
+
function generateInvitationToken() {
|
|
37
|
+
const bytes = new Uint8Array(INVITATION_TOKEN_LENGTH);
|
|
38
|
+
crypto.getRandomValues(bytes);
|
|
39
|
+
return Array.from(bytes, (b) => b.toString(16).padStart(2, '0')).join('');
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Normalize a user-provided slug to valid format.
|
|
43
|
+
* Converts to lowercase and removes invalid characters.
|
|
44
|
+
* @param input - The user-provided slug
|
|
45
|
+
* @returns Normalized slug
|
|
46
|
+
*/
|
|
47
|
+
function normalizeSlug(input) {
|
|
48
|
+
return input
|
|
49
|
+
.toLowerCase()
|
|
50
|
+
.replace(/[^a-z0-9]/g, '')
|
|
51
|
+
.slice(0, 12);
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate that a slug meets the requirements.
|
|
55
|
+
* @param slug - The slug to validate
|
|
56
|
+
* @returns Whether the slug is valid
|
|
57
|
+
*/
|
|
58
|
+
function validateSlug(slug) {
|
|
59
|
+
return /^[a-z0-9]{8,12}$/.test(slug);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Generate a slug with a numeric suffix to avoid collisions.
|
|
63
|
+
* @param baseSlug - The base slug to append suffix to
|
|
64
|
+
* @param existingSlugs - Set of existing slugs to avoid
|
|
65
|
+
* @returns A unique slug with suffix if needed
|
|
66
|
+
*/
|
|
67
|
+
function generateUniqueSlug(baseSlug, existingSlugs) {
|
|
68
|
+
const normalized = normalizeSlug(baseSlug).slice(0, 8);
|
|
69
|
+
if (!existingSlugs.has(normalized) && validateSlug(normalized)) {
|
|
70
|
+
return normalized;
|
|
71
|
+
}
|
|
72
|
+
// Try adding numeric suffixes
|
|
73
|
+
for (let i = 1; i < 1000; i++) {
|
|
74
|
+
const suffix = i.toString();
|
|
75
|
+
const candidate = (normalized.slice(0, 12 - suffix.length) + suffix).slice(0, 12);
|
|
76
|
+
if (!existingSlugs.has(candidate) && validateSlug(candidate)) {
|
|
77
|
+
return candidate;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// Fall back to random slug
|
|
81
|
+
return generateEntitySlug();
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Calculate invitation expiry date (7 days from now).
|
|
85
|
+
* @returns ISO 8601 string for expiry date
|
|
86
|
+
*/
|
|
87
|
+
function calculateInvitationExpiry() {
|
|
88
|
+
const expiryDate = new Date();
|
|
89
|
+
expiryDate.setDate(expiryDate.getDate() + 7);
|
|
90
|
+
return expiryDate.toISOString();
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=slug-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"slug-generator.js","sourceRoot":"","sources":["../../src/utils/slug-generator.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@sudobility/entity_service",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "Shared entity/organization management library for multi-tenant workspaces",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.cjs",
|
|
7
|
+
"module": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.cjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
},
|
|
15
|
+
"./middleware/hono": {
|
|
16
|
+
"import": "./dist/middleware/hono.js",
|
|
17
|
+
"require": "./dist/middleware/hono.cjs",
|
|
18
|
+
"types": "./dist/middleware/hono.d.ts"
|
|
19
|
+
},
|
|
20
|
+
"./schema": {
|
|
21
|
+
"import": "./dist/schema/entities.js",
|
|
22
|
+
"require": "./dist/schema/entities.cjs",
|
|
23
|
+
"types": "./dist/schema/entities.d.ts"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "bun run build:esm && bun run build:cjs",
|
|
28
|
+
"build:esm": "bunx tsc -p tsconfig.esm.json",
|
|
29
|
+
"build:cjs": "bunx tsc -p tsconfig.cjs.json && bun run build:cjs-rename",
|
|
30
|
+
"build:cjs-rename": "find dist -name '*.js' -not -name '*.cjs' -exec sh -c 'cp \"$1\" \"${1%.js}.cjs\"' _ {} \\;",
|
|
31
|
+
"clean": "rm -rf dist",
|
|
32
|
+
"dev": "bunx tsc --watch",
|
|
33
|
+
"test": "bun test",
|
|
34
|
+
"lint": "bunx eslint src/",
|
|
35
|
+
"lint:fix": "bunx eslint src/ --fix",
|
|
36
|
+
"typecheck": "bunx tsc --noEmit",
|
|
37
|
+
"format": "bunx prettier --write \"src/**/*.ts\"",
|
|
38
|
+
"format:check": "bunx prettier --check \"src/**/*.ts\"",
|
|
39
|
+
"verify": "bun run typecheck && bun run lint && bun run build",
|
|
40
|
+
"prepublishOnly": "bun run clean && bun run verify"
|
|
41
|
+
},
|
|
42
|
+
"files": [
|
|
43
|
+
"dist/**/*",
|
|
44
|
+
"CLAUDE.md"
|
|
45
|
+
],
|
|
46
|
+
"keywords": [
|
|
47
|
+
"entity",
|
|
48
|
+
"organization",
|
|
49
|
+
"workspace",
|
|
50
|
+
"multi-tenant",
|
|
51
|
+
"hono",
|
|
52
|
+
"drizzle"
|
|
53
|
+
],
|
|
54
|
+
"author": "Sudobility",
|
|
55
|
+
"license": "MIT",
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"@sudobility/types": "^1.9.40",
|
|
58
|
+
"drizzle-orm": "^0.45.0",
|
|
59
|
+
"hono": "^4.0.0"
|
|
60
|
+
},
|
|
61
|
+
"devDependencies": {
|
|
62
|
+
"@sudobility/types": "^1.9.40",
|
|
63
|
+
"@types/bun": "latest",
|
|
64
|
+
"@types/node": "^24.0.0",
|
|
65
|
+
"@typescript-eslint/eslint-plugin": "^8.50.0",
|
|
66
|
+
"@typescript-eslint/parser": "^8.50.0",
|
|
67
|
+
"drizzle-orm": "^0.45.0",
|
|
68
|
+
"eslint": "^9.39.0",
|
|
69
|
+
"eslint-plugin-import": "^2.32.0",
|
|
70
|
+
"hono": "^4.10.0",
|
|
71
|
+
"postgres": "^3.4.0",
|
|
72
|
+
"prettier": "^3.7.0",
|
|
73
|
+
"typescript": "^5.9.0"
|
|
74
|
+
},
|
|
75
|
+
"publishConfig": {
|
|
76
|
+
"access": "public"
|
|
77
|
+
}
|
|
78
|
+
}
|