@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.
Files changed (72) hide show
  1. package/CLAUDE.md +124 -0
  2. package/dist/helpers/EntityHelper.cjs +234 -0
  3. package/dist/helpers/EntityHelper.d.ts +60 -0
  4. package/dist/helpers/EntityHelper.d.ts.map +1 -0
  5. package/dist/helpers/EntityHelper.js +234 -0
  6. package/dist/helpers/EntityHelper.js.map +1 -0
  7. package/dist/helpers/EntityMemberHelper.cjs +215 -0
  8. package/dist/helpers/EntityMemberHelper.d.ts +45 -0
  9. package/dist/helpers/EntityMemberHelper.d.ts.map +1 -0
  10. package/dist/helpers/EntityMemberHelper.js +215 -0
  11. package/dist/helpers/EntityMemberHelper.js.map +1 -0
  12. package/dist/helpers/InvitationHelper.cjs +251 -0
  13. package/dist/helpers/InvitationHelper.d.ts +59 -0
  14. package/dist/helpers/InvitationHelper.d.ts.map +1 -0
  15. package/dist/helpers/InvitationHelper.js +251 -0
  16. package/dist/helpers/InvitationHelper.js.map +1 -0
  17. package/dist/helpers/PermissionHelper.cjs +197 -0
  18. package/dist/helpers/PermissionHelper.d.ts +86 -0
  19. package/dist/helpers/PermissionHelper.d.ts.map +1 -0
  20. package/dist/helpers/PermissionHelper.js +197 -0
  21. package/dist/helpers/PermissionHelper.js.map +1 -0
  22. package/dist/helpers/index.cjs +15 -0
  23. package/dist/helpers/index.d.ts +8 -0
  24. package/dist/helpers/index.d.ts.map +1 -0
  25. package/dist/helpers/index.js +15 -0
  26. package/dist/helpers/index.js.map +1 -0
  27. package/dist/index.cjs +76 -0
  28. package/dist/index.d.ts +36 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +76 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/middleware/hono.cjs +148 -0
  33. package/dist/middleware/hono.d.ts +102 -0
  34. package/dist/middleware/hono.d.ts.map +1 -0
  35. package/dist/middleware/hono.js +148 -0
  36. package/dist/middleware/hono.js.map +1 -0
  37. package/dist/middleware/index.cjs +12 -0
  38. package/dist/middleware/index.d.ts +5 -0
  39. package/dist/middleware/index.d.ts.map +1 -0
  40. package/dist/middleware/index.js +12 -0
  41. package/dist/middleware/index.js.map +1 -0
  42. package/dist/migrations/001_add_entities.cjs +269 -0
  43. package/dist/migrations/001_add_entities.d.ts +29 -0
  44. package/dist/migrations/001_add_entities.d.ts.map +1 -0
  45. package/dist/migrations/001_add_entities.js +269 -0
  46. package/dist/migrations/001_add_entities.js.map +1 -0
  47. package/dist/migrations/index.cjs +10 -0
  48. package/dist/migrations/index.d.ts +5 -0
  49. package/dist/migrations/index.d.ts.map +1 -0
  50. package/dist/migrations/index.js +10 -0
  51. package/dist/migrations/index.js.map +1 -0
  52. package/dist/schema/entities.cjs +304 -0
  53. package/dist/schema/entities.d.ts +1047 -0
  54. package/dist/schema/entities.d.ts.map +1 -0
  55. package/dist/schema/entities.js +304 -0
  56. package/dist/schema/entities.js.map +1 -0
  57. package/dist/types/index.cjs +14 -0
  58. package/dist/types/index.d.ts +71 -0
  59. package/dist/types/index.d.ts.map +1 -0
  60. package/dist/types/index.js +14 -0
  61. package/dist/types/index.js.map +1 -0
  62. package/dist/utils/index.cjs +21 -0
  63. package/dist/utils/index.d.ts +5 -0
  64. package/dist/utils/index.d.ts.map +1 -0
  65. package/dist/utils/index.js +21 -0
  66. package/dist/utils/index.js.map +1 -0
  67. package/dist/utils/slug-generator.cjs +92 -0
  68. package/dist/utils/slug-generator.d.ts +41 -0
  69. package/dist/utils/slug-generator.d.ts.map +1 -0
  70. package/dist/utils/slug-generator.js +92 -0
  71. package/dist/utils/slug-generator.js.map +1 -0
  72. 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
+ }