@oktis-works/core 0.1.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.
Files changed (201) hide show
  1. package/dist/bootstrap/index.d.ts +7 -0
  2. package/dist/bootstrap/index.d.ts.map +1 -0
  3. package/dist/bootstrap/index.js +16 -0
  4. package/dist/bootstrap/index.js.map +1 -0
  5. package/dist/build/service.d.ts +28 -0
  6. package/dist/build/service.d.ts.map +1 -0
  7. package/dist/build/service.js +71 -0
  8. package/dist/build/service.js.map +1 -0
  9. package/dist/cache/index.d.ts +31 -0
  10. package/dist/cache/index.d.ts.map +1 -0
  11. package/dist/cache/index.js +110 -0
  12. package/dist/cache/index.js.map +1 -0
  13. package/dist/category/service.d.ts +21 -0
  14. package/dist/category/service.d.ts.map +1 -0
  15. package/dist/category/service.js +67 -0
  16. package/dist/category/service.js.map +1 -0
  17. package/dist/content/field-resolver.d.ts +31 -0
  18. package/dist/content/field-resolver.d.ts.map +1 -0
  19. package/dist/content/field-resolver.js +40 -0
  20. package/dist/content/field-resolver.js.map +1 -0
  21. package/dist/content/post-types.d.ts +28 -0
  22. package/dist/content/post-types.d.ts.map +1 -0
  23. package/dist/content/post-types.js +127 -0
  24. package/dist/content/post-types.js.map +1 -0
  25. package/dist/content/publisher.d.ts +26 -0
  26. package/dist/content/publisher.d.ts.map +1 -0
  27. package/dist/content/publisher.js +156 -0
  28. package/dist/content/publisher.js.map +1 -0
  29. package/dist/content/service.d.ts +53 -0
  30. package/dist/content/service.d.ts.map +1 -0
  31. package/dist/content/service.js +335 -0
  32. package/dist/content/service.js.map +1 -0
  33. package/dist/deployment/service.d.ts +25 -0
  34. package/dist/deployment/service.d.ts.map +1 -0
  35. package/dist/deployment/service.js +102 -0
  36. package/dist/deployment/service.js.map +1 -0
  37. package/dist/events/bus.d.ts +25 -0
  38. package/dist/events/bus.d.ts.map +1 -0
  39. package/dist/events/bus.js +89 -0
  40. package/dist/events/bus.js.map +1 -0
  41. package/dist/events/store.d.ts +19 -0
  42. package/dist/events/store.d.ts.map +1 -0
  43. package/dist/events/store.js +52 -0
  44. package/dist/events/store.js.map +1 -0
  45. package/dist/fields/clone.d.ts +2 -0
  46. package/dist/fields/clone.d.ts.map +1 -0
  47. package/dist/fields/clone.js +3 -0
  48. package/dist/fields/clone.js.map +1 -0
  49. package/dist/fields/conditional.d.ts +2 -0
  50. package/dist/fields/conditional.d.ts.map +1 -0
  51. package/dist/fields/conditional.js +3 -0
  52. package/dist/fields/conditional.js.map +1 -0
  53. package/dist/fields/index.d.ts +5 -0
  54. package/dist/fields/index.d.ts.map +1 -0
  55. package/dist/fields/index.js +6 -0
  56. package/dist/fields/index.js.map +1 -0
  57. package/dist/fields/location-rules.d.ts +16 -0
  58. package/dist/fields/location-rules.d.ts.map +1 -0
  59. package/dist/fields/location-rules.js +22 -0
  60. package/dist/fields/location-rules.js.map +1 -0
  61. package/dist/fields/service.d.ts +77 -0
  62. package/dist/fields/service.d.ts.map +1 -0
  63. package/dist/fields/service.js +278 -0
  64. package/dist/fields/service.js.map +1 -0
  65. package/dist/fields/types/registry.d.ts +20 -0
  66. package/dist/fields/types/registry.d.ts.map +1 -0
  67. package/dist/fields/types/registry.js +68 -0
  68. package/dist/fields/types/registry.js.map +1 -0
  69. package/dist/fields/types/validators/basic.d.ts +2 -0
  70. package/dist/fields/types/validators/basic.d.ts.map +1 -0
  71. package/dist/fields/types/validators/basic.js +3 -0
  72. package/dist/fields/types/validators/basic.js.map +1 -0
  73. package/dist/fields/types/validators/choice.d.ts +2 -0
  74. package/dist/fields/types/validators/choice.d.ts.map +1 -0
  75. package/dist/fields/types/validators/choice.js +3 -0
  76. package/dist/fields/types/validators/choice.js.map +1 -0
  77. package/dist/fields/types/validators/client-validate.d.ts +2 -0
  78. package/dist/fields/types/validators/client-validate.d.ts.map +1 -0
  79. package/dist/fields/types/validators/client-validate.js +3 -0
  80. package/dist/fields/types/validators/client-validate.js.map +1 -0
  81. package/dist/fields/types/validators/index.d.ts +8 -0
  82. package/dist/fields/types/validators/index.d.ts.map +1 -0
  83. package/dist/fields/types/validators/index.js +10 -0
  84. package/dist/fields/types/validators/index.js.map +1 -0
  85. package/dist/fields/types/validators/media.d.ts +2 -0
  86. package/dist/fields/types/validators/media.d.ts.map +1 -0
  87. package/dist/fields/types/validators/media.js +3 -0
  88. package/dist/fields/types/validators/media.js.map +1 -0
  89. package/dist/fields/types/validators/relational.d.ts +2 -0
  90. package/dist/fields/types/validators/relational.d.ts.map +1 -0
  91. package/dist/fields/types/validators/relational.js +3 -0
  92. package/dist/fields/types/validators/relational.js.map +1 -0
  93. package/dist/fields/types/validators/structural.d.ts +2 -0
  94. package/dist/fields/types/validators/structural.d.ts.map +1 -0
  95. package/dist/fields/types/validators/structural.js +3 -0
  96. package/dist/fields/types/validators/structural.js.map +1 -0
  97. package/dist/fields/validation.d.ts +16 -0
  98. package/dist/fields/validation.d.ts.map +1 -0
  99. package/dist/fields/validation.js +123 -0
  100. package/dist/fields/validation.js.map +1 -0
  101. package/dist/hooks/catalog.d.ts +20 -0
  102. package/dist/hooks/catalog.d.ts.map +1 -0
  103. package/dist/hooks/catalog.js +59 -0
  104. package/dist/hooks/catalog.js.map +1 -0
  105. package/dist/hooks/points.d.ts +26 -0
  106. package/dist/hooks/points.d.ts.map +1 -0
  107. package/dist/hooks/points.js +33 -0
  108. package/dist/hooks/points.js.map +1 -0
  109. package/dist/index.d.ts +52 -0
  110. package/dist/index.d.ts.map +1 -0
  111. package/dist/index.js +45 -0
  112. package/dist/index.js.map +1 -0
  113. package/dist/lifecycle/index.d.ts +17 -0
  114. package/dist/lifecycle/index.d.ts.map +1 -0
  115. package/dist/lifecycle/index.js +79 -0
  116. package/dist/lifecycle/index.js.map +1 -0
  117. package/dist/media/service.d.ts +32 -0
  118. package/dist/media/service.d.ts.map +1 -0
  119. package/dist/media/service.js +87 -0
  120. package/dist/media/service.js.map +1 -0
  121. package/dist/menu/service.d.ts +19 -0
  122. package/dist/menu/service.d.ts.map +1 -0
  123. package/dist/menu/service.js +64 -0
  124. package/dist/menu/service.js.map +1 -0
  125. package/dist/observability/audit.d.ts +26 -0
  126. package/dist/observability/audit.d.ts.map +1 -0
  127. package/dist/observability/audit.js +67 -0
  128. package/dist/observability/audit.js.map +1 -0
  129. package/dist/observability/event-audit.d.ts +8 -0
  130. package/dist/observability/event-audit.d.ts.map +1 -0
  131. package/dist/observability/event-audit.js +20 -0
  132. package/dist/observability/event-audit.js.map +1 -0
  133. package/dist/observability/index.d.ts +5 -0
  134. package/dist/observability/index.d.ts.map +1 -0
  135. package/dist/observability/index.js +6 -0
  136. package/dist/observability/index.js.map +1 -0
  137. package/dist/observability/logger.d.ts +13 -0
  138. package/dist/observability/logger.d.ts.map +1 -0
  139. package/dist/observability/logger.js +45 -0
  140. package/dist/observability/logger.js.map +1 -0
  141. package/dist/observability/metrics.d.ts +34 -0
  142. package/dist/observability/metrics.d.ts.map +1 -0
  143. package/dist/observability/metrics.js +56 -0
  144. package/dist/observability/metrics.js.map +1 -0
  145. package/dist/plugin/service.d.ts +32 -0
  146. package/dist/plugin/service.d.ts.map +1 -0
  147. package/dist/plugin/service.js +190 -0
  148. package/dist/plugin/service.js.map +1 -0
  149. package/dist/role/service.d.ts +19 -0
  150. package/dist/role/service.d.ts.map +1 -0
  151. package/dist/role/service.js +65 -0
  152. package/dist/role/service.js.map +1 -0
  153. package/dist/settings/service.d.ts +16 -0
  154. package/dist/settings/service.d.ts.map +1 -0
  155. package/dist/settings/service.js +64 -0
  156. package/dist/settings/service.js.map +1 -0
  157. package/dist/storage/driver.d.ts +20 -0
  158. package/dist/storage/driver.d.ts.map +1 -0
  159. package/dist/storage/driver.js +3 -0
  160. package/dist/storage/driver.js.map +1 -0
  161. package/dist/storage/drivers/local.d.ts +17 -0
  162. package/dist/storage/drivers/local.d.ts.map +1 -0
  163. package/dist/storage/drivers/local.js +88 -0
  164. package/dist/storage/drivers/local.js.map +1 -0
  165. package/dist/storage/drivers/s3.d.ts +28 -0
  166. package/dist/storage/drivers/s3.d.ts.map +1 -0
  167. package/dist/storage/drivers/s3.js +105 -0
  168. package/dist/storage/drivers/s3.js.map +1 -0
  169. package/dist/storage/index.d.ts +16 -0
  170. package/dist/storage/index.d.ts.map +1 -0
  171. package/dist/storage/index.js +58 -0
  172. package/dist/storage/index.js.map +1 -0
  173. package/dist/storage/migrator.d.ts +18 -0
  174. package/dist/storage/migrator.d.ts.map +1 -0
  175. package/dist/storage/migrator.js +46 -0
  176. package/dist/storage/migrator.js.map +1 -0
  177. package/dist/tag/service.d.ts +13 -0
  178. package/dist/tag/service.d.ts.map +1 -0
  179. package/dist/tag/service.js +37 -0
  180. package/dist/tag/service.js.map +1 -0
  181. package/dist/taxonomies/service.d.ts +50 -0
  182. package/dist/taxonomies/service.d.ts.map +1 -0
  183. package/dist/taxonomies/service.js +179 -0
  184. package/dist/taxonomies/service.js.map +1 -0
  185. package/dist/tenant/context.d.ts +9 -0
  186. package/dist/tenant/context.d.ts.map +1 -0
  187. package/dist/tenant/context.js +67 -0
  188. package/dist/tenant/context.js.map +1 -0
  189. package/dist/tenant/service.d.ts +31 -0
  190. package/dist/tenant/service.d.ts.map +1 -0
  191. package/dist/tenant/service.js +90 -0
  192. package/dist/tenant/service.js.map +1 -0
  193. package/dist/theme/service.d.ts +16 -0
  194. package/dist/theme/service.d.ts.map +1 -0
  195. package/dist/theme/service.js +57 -0
  196. package/dist/theme/service.js.map +1 -0
  197. package/dist/user/service.d.ts +31 -0
  198. package/dist/user/service.d.ts.map +1 -0
  199. package/dist/user/service.js +95 -0
  200. package/dist/user/service.js.map +1 -0
  201. package/package.json +48 -0
@@ -0,0 +1,67 @@
1
+ // @oktis-works/core - Tenant Context
2
+ import { setTenantContext, clearTenantContext, getCurrentTenantId } from '@oktis-works/database';
3
+ let _currentContext = null;
4
+ /**
5
+ * O espelho para o RLS do Postgres é opcional: sem conexão inicializada
6
+ * mantemos apenas o contexto em memória (útil em testes e boot antecipado).
7
+ * Outros erros de banco são propagados normalmente.
8
+ */
9
+ function ignoreIfNoConnection(error) {
10
+ if (error instanceof Error &&
11
+ error.message.startsWith('Database connection not initialized')) {
12
+ return;
13
+ }
14
+ throw error;
15
+ }
16
+ async function trySetTenantContext(tenantId) {
17
+ try {
18
+ await setTenantContext(tenantId);
19
+ }
20
+ catch (error) {
21
+ ignoreIfNoConnection(error);
22
+ }
23
+ }
24
+ async function tryClearTenantContext() {
25
+ try {
26
+ await clearTenantContext();
27
+ }
28
+ catch (error) {
29
+ ignoreIfNoConnection(error);
30
+ }
31
+ }
32
+ async function tryGetTenantId() {
33
+ try {
34
+ return await getCurrentTenantId();
35
+ }
36
+ catch (error) {
37
+ ignoreIfNoConnection(error);
38
+ return null;
39
+ }
40
+ }
41
+ export async function establishTenantContext(tenantId, userId) {
42
+ await trySetTenantContext(tenantId);
43
+ _currentContext = { tenantId, userId };
44
+ return _currentContext;
45
+ }
46
+ export async function getCurrentContext() {
47
+ if (_currentContext) {
48
+ return _currentContext;
49
+ }
50
+ const tenantId = await tryGetTenantId();
51
+ if (tenantId) {
52
+ _currentContext = { tenantId };
53
+ return _currentContext;
54
+ }
55
+ return null;
56
+ }
57
+ export async function clearCurrentContext() {
58
+ await tryClearTenantContext();
59
+ _currentContext = null;
60
+ }
61
+ export function requireTenantContext() {
62
+ if (!_currentContext) {
63
+ throw new Error('Tenant context not established. Call establishTenantContext() first.');
64
+ }
65
+ return _currentContext;
66
+ }
67
+ //# sourceMappingURL=context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/tenant/context.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAOjG,IAAI,eAAe,GAAyB,IAAI,CAAC;AAEjD;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,KAAc;IAC1C,IACE,KAAK,YAAY,KAAK;QACtB,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,qCAAqC,CAAC,EAC/D,CAAC;QACD,OAAO;IACT,CAAC;IACD,MAAM,KAAK,CAAC;AACd,CAAC;AAED,KAAK,UAAU,mBAAmB,CAAC,QAAgB;IACjD,IAAI,CAAC;QACH,MAAM,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,qBAAqB;IAClC,IAAI,CAAC;QACH,MAAM,kBAAkB,EAAE,CAAC;IAC7B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oBAAoB,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;AACH,CAAC;AAED,KAAK,UAAU,cAAc;IAC3B,IAAI,CAAC;QACH,OAAO,MAAM,kBAAkB,EAAE,CAAC;IACpC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAAC,QAAgB,EAAE,MAAe;IAC5E,MAAM,mBAAmB,CAAC,QAAQ,CAAC,CAAC;IAEpC,eAAe,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IACvC,OAAO,eAAe,CAAC;AACzB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB;IACrC,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,cAAc,EAAE,CAAC;IACxC,IAAI,QAAQ,EAAE,CAAC;QACb,eAAe,GAAG,EAAE,QAAQ,EAAE,CAAC;QAC/B,OAAO,eAAe,CAAC;IACzB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB;IACvC,MAAM,qBAAqB,EAAE,CAAC;IAC9B,eAAe,GAAG,IAAI,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,oBAAoB;IAClC,IAAI,CAAC,eAAe,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,sEAAsE,CAAC,CAAC;IAC1F,CAAC;IACD,OAAO,eAAe,CAAC;AACzB,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { Tenant } from '@oktis-works/types';
2
+ export declare class TenantService {
3
+ list(options: {
4
+ page?: number;
5
+ limit?: number;
6
+ search?: string;
7
+ }): Promise<{
8
+ data: Tenant[];
9
+ total: number;
10
+ }>;
11
+ getById(id: string): Promise<Tenant | null>;
12
+ getBySlug(slug: string): Promise<Tenant | null>;
13
+ create(input: {
14
+ name: string;
15
+ slug: string;
16
+ domain?: string;
17
+ subdomain?: string;
18
+ settings?: Record<string, unknown>;
19
+ }): Promise<Tenant>;
20
+ update(id: string, input: {
21
+ name?: string;
22
+ slug?: string;
23
+ domain?: string;
24
+ subdomain?: string;
25
+ status?: Tenant['status'];
26
+ settings?: Record<string, unknown>;
27
+ }): Promise<Tenant | null>;
28
+ delete(id: string): Promise<boolean>;
29
+ }
30
+ export declare const tenantService: TenantService;
31
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/tenant/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEjD,qBAAa,aAAa;IAClB,IAAI,CAAC,OAAO,EAAE;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IA6BxC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAM3C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IAM/C,MAAM,CAAC,KAAK,EAAE;QAClB,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBb,MAAM,CACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,MAAM,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;QAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KACpC,GACA,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC;IA+CnB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAU3C;AAED,eAAO,MAAM,aAAa,eAAsB,CAAC"}
@@ -0,0 +1,90 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { getConnection } from '@oktis-works/database';
3
+ export class TenantService {
4
+ async list(options) {
5
+ const sql = getConnection();
6
+ const { page = 1, limit = 20, search } = options;
7
+ const offset = (page - 1) * limit;
8
+ let whereClause = 'WHERE 1=1';
9
+ const params = [];
10
+ if (search) {
11
+ whereClause += ` AND (name ILIKE $${params.length + 1} OR slug ILIKE $${params.length + 2})`;
12
+ params.push(`%${search}%`);
13
+ params.push(`%${search}%`);
14
+ }
15
+ const dataResult = await sql.unsafe(`SELECT * FROM tenants ${whereClause} ORDER BY created_at DESC LIMIT ${limit} OFFSET ${offset}`, params);
16
+ const countResult = await sql.unsafe(`SELECT COUNT(*) as total FROM tenants ${whereClause}`, params);
17
+ return {
18
+ data: dataResult,
19
+ total: Number(countResult[0]?.['total'] ?? 0),
20
+ };
21
+ }
22
+ async getById(id) {
23
+ const sql = getConnection();
24
+ const result = await sql.unsafe('SELECT * FROM tenants WHERE id = $1', [id]);
25
+ return result[0] ?? null;
26
+ }
27
+ async getBySlug(slug) {
28
+ const sql = getConnection();
29
+ const result = await sql.unsafe('SELECT * FROM tenants WHERE slug = $1', [slug]);
30
+ return result[0] ?? null;
31
+ }
32
+ async create(input) {
33
+ const sql = getConnection();
34
+ const id = randomUUID();
35
+ const status = 'ACTIVE';
36
+ const settingsJson = input.settings ? JSON.stringify(input.settings) : null;
37
+ const result = await sql.unsafe(`INSERT INTO tenants (id, name, slug, domain, subdomain, status, settings)
38
+ VALUES ($1, $2, $3, $4, $5, $6, $7::jsonb)
39
+ RETURNING *`, [id, input.name, input.slug, input.domain ?? null, input.subdomain ?? null, status, settingsJson]);
40
+ return result[0];
41
+ }
42
+ async update(id, input) {
43
+ const sql = getConnection();
44
+ const existing = await this.getById(id);
45
+ if (!existing)
46
+ return null;
47
+ const setClauses = [];
48
+ const setParams = [];
49
+ if (input.name !== undefined) {
50
+ setClauses.push(`name = $${setParams.length + 1}`);
51
+ setParams.push(input.name);
52
+ }
53
+ if (input.slug !== undefined) {
54
+ setClauses.push(`slug = $${setParams.length + 1}`);
55
+ setParams.push(input.slug);
56
+ }
57
+ if (input.domain !== undefined) {
58
+ setClauses.push(`domain = $${setParams.length + 1}`);
59
+ setParams.push(input.domain);
60
+ }
61
+ if (input.subdomain !== undefined) {
62
+ setClauses.push(`subdomain = $${setParams.length + 1}`);
63
+ setParams.push(input.subdomain);
64
+ }
65
+ if (input.status !== undefined) {
66
+ setClauses.push(`status = $${setParams.length + 1}`);
67
+ setParams.push(input.status);
68
+ }
69
+ if (input.settings !== undefined) {
70
+ setClauses.push(`settings = $${setParams.length + 1}::jsonb`);
71
+ setParams.push(JSON.stringify(input.settings));
72
+ }
73
+ if (setClauses.length === 0)
74
+ return existing;
75
+ setClauses.push(`updated_at = NOW()`);
76
+ setParams.push(id);
77
+ const result = await sql.unsafe(`UPDATE tenants SET ${setClauses.join(', ')} WHERE id = $${setParams.length} RETURNING *`, setParams);
78
+ return result[0] ?? null;
79
+ }
80
+ async delete(id) {
81
+ const sql = getConnection();
82
+ const existing = await this.getById(id);
83
+ if (!existing)
84
+ return false;
85
+ await sql.unsafe(`UPDATE tenants SET status = $1, updated_at = NOW() WHERE id = $2`, ['DELETED', id]);
86
+ return true;
87
+ }
88
+ }
89
+ export const tenantService = new TenantService();
90
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/tenant/service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { Theme } from '@oktis-works/types';
2
+ export declare class ThemeService {
3
+ list(): Promise<Theme[]>;
4
+ getById(id: string): Promise<Theme | null>;
5
+ getByName(name: string): Promise<Theme | null>;
6
+ install(input: {
7
+ name: string;
8
+ version: string;
9
+ manifest: Record<string, unknown>;
10
+ config?: Record<string, unknown>;
11
+ }): Promise<Theme>;
12
+ activate(id: string): Promise<Theme | null>;
13
+ uninstall(id: string): Promise<boolean>;
14
+ }
15
+ export declare const themeService: ThemeService;
16
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/theme/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAEhD,qBAAa,YAAY;IACjB,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;IAMxB,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAM1C,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAM9C,OAAO,CAAC,KAAK,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;KAClC,GAAG,OAAO,CAAC,KAAK,CAAC;IAuBZ,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC;IAiB3C,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;CAU9C;AAED,eAAO,MAAM,YAAY,cAAqB,CAAC"}
@@ -0,0 +1,57 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { getConnection } from '@oktis-works/database';
3
+ export class ThemeService {
4
+ async list() {
5
+ const sql = getConnection();
6
+ const result = await sql.unsafe('SELECT * FROM themes ORDER BY name ASC');
7
+ return result;
8
+ }
9
+ async getById(id) {
10
+ const sql = getConnection();
11
+ const result = await sql.unsafe('SELECT * FROM themes WHERE id = $1', [id]);
12
+ return result[0] ?? null;
13
+ }
14
+ async getByName(name) {
15
+ const sql = getConnection();
16
+ const result = await sql.unsafe('SELECT * FROM themes WHERE name = $1', [name]);
17
+ return result[0] ?? null;
18
+ }
19
+ async install(input) {
20
+ const sql = getConnection();
21
+ const id = randomUUID();
22
+ const now = new Date().toISOString();
23
+ const result = await sql.unsafe(`INSERT INTO themes (id, name, version, status, manifest, config, created_at, updated_at)
24
+ VALUES ($1, $2, $3, $4, $5::jsonb, $6::jsonb, $7, $7)
25
+ RETURNING *`, [
26
+ id,
27
+ input.name,
28
+ input.version,
29
+ 'INSTALLED',
30
+ JSON.stringify(input.manifest),
31
+ input.config ? JSON.stringify(input.config) : '{}',
32
+ now,
33
+ ]);
34
+ return result[0];
35
+ }
36
+ async activate(id) {
37
+ const sql = getConnection();
38
+ const existing = await this.getById(id);
39
+ if (!existing)
40
+ return null;
41
+ const result = await sql.unsafe(`UPDATE themes
42
+ SET status = $1, activated_at = NOW(), updated_at = NOW()
43
+ WHERE id = $2
44
+ RETURNING *`, ['ACTIVE', id]);
45
+ return result[0] ?? null;
46
+ }
47
+ async uninstall(id) {
48
+ const sql = getConnection();
49
+ const existing = await this.getById(id);
50
+ if (!existing)
51
+ return false;
52
+ await sql.unsafe('DELETE FROM themes WHERE id = $1', [id]);
53
+ return true;
54
+ }
55
+ }
56
+ export const themeService = new ThemeService();
57
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/theme/service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGtD,MAAM,OAAO,YAAY;IACvB,KAAK,CAAC,IAAI;QACR,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,wCAAwC,CAAC,CAAC;QAC1E,OAAO,MAA4B,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,EAAU;QACtB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,oCAAoC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAC5E,OAAQ,MAAM,CAAC,CAAC,CAAsB,IAAI,IAAI,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,IAAY;QAC1B,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAAC,sCAAsC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC;QAChF,OAAQ,MAAM,CAAC,CAAC,CAAsB,IAAI,IAAI,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAKb;QACC,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAC5B,MAAM,EAAE,GAAG,UAAU,EAAE,CAAC;QACxB,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B;;mBAEa,EACb;YACE,EAAE;YACF,KAAK,CAAC,IAAI;YACV,KAAK,CAAC,OAAO;YACb,WAAW;YACX,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC;YAC9B,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI;YAClD,GAAG;SACJ,CACF,CAAC;QAEF,OAAO,MAAM,CAAC,CAAC,CAAqB,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,EAAU;QACvB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAE5B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ;YAAE,OAAO,IAAI,CAAC;QAE3B,MAAM,MAAM,GAAG,MAAM,GAAG,CAAC,MAAM,CAC7B;;;mBAGa,EACb,CAAC,QAAQ,EAAE,EAAE,CAAC,CACf,CAAC;QAEF,OAAQ,MAAM,CAAC,CAAC,CAAsB,IAAI,IAAI,CAAC;IACjD,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,MAAM,GAAG,GAAG,aAAa,EAAE,CAAC;QAE5B,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QACxC,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAE5B,MAAM,GAAG,CAAC,MAAM,CAAC,kCAAkC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;QAE3D,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAED,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,YAAY,EAAE,CAAC"}
@@ -0,0 +1,31 @@
1
+ import type { User } from '@oktis-works/types';
2
+ export declare class UserService {
3
+ list(options: {
4
+ page?: number;
5
+ limit?: number;
6
+ search?: string;
7
+ status?: User['status'];
8
+ }): Promise<{
9
+ data: User[];
10
+ total: number;
11
+ }>;
12
+ getById(id: string): Promise<User | null>;
13
+ getByEmail(email: string): Promise<User | null>;
14
+ create(input: {
15
+ email: string;
16
+ name: string;
17
+ passwordHash: string;
18
+ avatar?: string;
19
+ }): Promise<User>;
20
+ update(id: string, input: {
21
+ name?: string;
22
+ email?: string;
23
+ avatar?: string;
24
+ status?: User['status'];
25
+ }): Promise<User | null>;
26
+ delete(id: string): Promise<boolean>;
27
+ addToTenant(userId: string, tenantId: string, roleId: string): Promise<void>;
28
+ removeFromTenant(userId: string, tenantId: string): Promise<void>;
29
+ }
30
+ export declare const userService: UserService;
31
+ //# sourceMappingURL=service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/user/service.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE/C,qBAAa,WAAW;IAChB,IAAI,CAAC,OAAO,EAAE;QAClB,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;KACzB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,IAAI,EAAE,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IAiCtC,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAMzC,UAAU,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAM/C,MAAM,CAAC,KAAK,EAAE;QAClB,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,YAAY,EAAE,MAAM,CAAC;QACrB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,GAAG,OAAO,CAAC,IAAI,CAAC;IAeX,MAAM,CACV,EAAE,EAAE,MAAM,EACV,KAAK,EAAE;QACL,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;KACzB,GACA,OAAO,CAAC,IAAI,GAAG,IAAI,CAAC;IAuCjB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAWpC,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW5E,gBAAgB,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAQxE;AAED,eAAO,MAAM,WAAW,aAAoB,CAAC"}
@@ -0,0 +1,95 @@
1
+ import { randomUUID } from 'node:crypto';
2
+ import { getConnection } from '@oktis-works/database';
3
+ export class UserService {
4
+ async list(options) {
5
+ const sql = getConnection();
6
+ const { page = 1, limit = 20, search, status } = options;
7
+ const offset = (page - 1) * limit;
8
+ let whereClause = 'WHERE 1=1';
9
+ const params = [];
10
+ if (status) {
11
+ whereClause += ` AND status = $${params.length + 1}`;
12
+ params.push(status);
13
+ }
14
+ if (search) {
15
+ whereClause += ` AND (name ILIKE $${params.length + 1} OR email ILIKE $${params.length + 2})`;
16
+ params.push(`%${search}%`);
17
+ params.push(`%${search}%`);
18
+ }
19
+ const dataResult = await sql.unsafe(`SELECT * FROM users ${whereClause} ORDER BY created_at DESC LIMIT ${limit} OFFSET ${offset}`, params);
20
+ const countResult = await sql.unsafe(`SELECT COUNT(*) as total FROM users ${whereClause}`, params);
21
+ return {
22
+ data: dataResult,
23
+ total: Number(countResult[0]?.['total'] ?? 0),
24
+ };
25
+ }
26
+ async getById(id) {
27
+ const sql = getConnection();
28
+ const result = await sql.unsafe('SELECT * FROM users WHERE id = $1', [id]);
29
+ return result[0] ?? null;
30
+ }
31
+ async getByEmail(email) {
32
+ const sql = getConnection();
33
+ const result = await sql.unsafe('SELECT * FROM users WHERE email = $1', [email]);
34
+ return result[0] ?? null;
35
+ }
36
+ async create(input) {
37
+ const sql = getConnection();
38
+ const id = randomUUID();
39
+ const status = 'ACTIVE';
40
+ const result = await sql.unsafe(`INSERT INTO users (id, email, name, password_hash, avatar, status)
41
+ VALUES ($1, $2, $3, $4, $5, $6)
42
+ RETURNING *`, [id, input.email, input.name, input.passwordHash, input.avatar ?? null, status]);
43
+ return result[0];
44
+ }
45
+ async update(id, input) {
46
+ const sql = getConnection();
47
+ const existing = await this.getById(id);
48
+ if (!existing)
49
+ return null;
50
+ const setClauses = [];
51
+ const setParams = [];
52
+ if (input.name !== undefined) {
53
+ setClauses.push(`name = $${setParams.length + 1}`);
54
+ setParams.push(input.name);
55
+ }
56
+ if (input.email !== undefined) {
57
+ setClauses.push(`email = $${setParams.length + 1}`);
58
+ setParams.push(input.email);
59
+ }
60
+ if (input.avatar !== undefined) {
61
+ setClauses.push(`avatar = $${setParams.length + 1}`);
62
+ setParams.push(input.avatar);
63
+ }
64
+ if (input.status !== undefined) {
65
+ setClauses.push(`status = $${setParams.length + 1}`);
66
+ setParams.push(input.status);
67
+ }
68
+ if (setClauses.length === 0)
69
+ return existing;
70
+ setClauses.push(`updated_at = NOW()`);
71
+ setParams.push(id);
72
+ const result = await sql.unsafe(`UPDATE users SET ${setClauses.join(', ')} WHERE id = $${setParams.length} RETURNING *`, setParams);
73
+ return result[0] ?? null;
74
+ }
75
+ async delete(id) {
76
+ const sql = getConnection();
77
+ const existing = await this.getById(id);
78
+ if (!existing)
79
+ return false;
80
+ await sql.unsafe('DELETE FROM users WHERE id = $1', [id]);
81
+ return true;
82
+ }
83
+ async addToTenant(userId, tenantId, roleId) {
84
+ const sql = getConnection();
85
+ const id = randomUUID();
86
+ await sql.unsafe(`INSERT INTO tenant_users (id, tenant_id, user_id, role_id, status)
87
+ VALUES ($1, $2, $3, $4, $5)`, [id, tenantId, userId, roleId, 'ACTIVE']);
88
+ }
89
+ async removeFromTenant(userId, tenantId) {
90
+ const sql = getConnection();
91
+ await sql.unsafe('DELETE FROM tenant_users WHERE user_id = $1 AND tenant_id = $2', [userId, tenantId]);
92
+ }
93
+ }
94
+ export const userService = new UserService();
95
+ //# sourceMappingURL=service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/user/service.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@oktis-works/core",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./validators": {
14
+ "types": "./dist/fields/types/validators/index.d.ts",
15
+ "import": "./dist/fields/types/validators/index.js"
16
+ }
17
+ },
18
+ "scripts": {
19
+ "build": "tsc",
20
+ "dev": "tsc --watch",
21
+ "clean": "rm -rf dist tsconfig.tsbuildinfo"
22
+ },
23
+ "dependencies": {
24
+ "@oktis-works/types": "0.1.0",
25
+ "@oktis-works/validation": "0.1.0",
26
+ "@oktis-works/config": "0.1.0",
27
+ "@oktis-works/database": "0.1.0",
28
+ "@oktis-works/plugin-runtime": "0.1.0",
29
+ "@aws-sdk/client-s3": "3.700.0",
30
+ "semver": "7"
31
+ },
32
+ "devDependencies": {
33
+ "typescript": "5.7.3"
34
+ },
35
+ "files": [
36
+ "dist"
37
+ ],
38
+ "publishConfig": {
39
+ "access": "public",
40
+ "registry": "https://registry.npmjs.org/"
41
+ },
42
+ "license": "MIT",
43
+ "repository": {
44
+ "type": "git",
45
+ "url": "https://github.com/blacklotus/blacklotus-cms",
46
+ "directory": "packages/core"
47
+ }
48
+ }