fastify-auto-sqlapi 0.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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +422 -0
  3. package/dist/bin/generate-schema.d.ts +3 -0
  4. package/dist/bin/generate-schema.d.ts.map +1 -0
  5. package/dist/bin/generate-schema.js +122 -0
  6. package/dist/bin/generate-tables.d.ts +3 -0
  7. package/dist/bin/generate-tables.d.ts.map +1 -0
  8. package/dist/bin/generate-tables.js +135 -0
  9. package/dist/bin/utils.d.ts +18 -0
  10. package/dist/bin/utils.d.ts.map +1 -0
  11. package/dist/bin/utils.js +54 -0
  12. package/dist/index.d.ts +34 -0
  13. package/dist/index.d.ts.map +1 -0
  14. package/dist/index.js +48 -0
  15. package/dist/lib/adapters/mysql-adapter.d.ts +9 -0
  16. package/dist/lib/adapters/mysql-adapter.d.ts.map +1 -0
  17. package/dist/lib/adapters/mysql-adapter.js +21 -0
  18. package/dist/lib/adapters/pg-adapter.d.ts +9 -0
  19. package/dist/lib/adapters/pg-adapter.d.ts.map +1 -0
  20. package/dist/lib/adapters/pg-adapter.js +11 -0
  21. package/dist/lib/cli/config.d.ts +3 -0
  22. package/dist/lib/cli/config.d.ts.map +1 -0
  23. package/dist/lib/cli/config.js +29 -0
  24. package/dist/lib/cli/mysql-introspect.d.ts +16 -0
  25. package/dist/lib/cli/mysql-introspect.d.ts.map +1 -0
  26. package/dist/lib/cli/mysql-introspect.js +98 -0
  27. package/dist/lib/cli/pg-introspect.d.ts +4 -0
  28. package/dist/lib/cli/pg-introspect.d.ts.map +1 -0
  29. package/dist/lib/cli/pg-introspect.js +36 -0
  30. package/dist/lib/cli/schema-codegen.d.ts +8 -0
  31. package/dist/lib/cli/schema-codegen.d.ts.map +1 -0
  32. package/dist/lib/cli/schema-codegen.js +100 -0
  33. package/dist/lib/cli/tables-codegen.d.ts +18 -0
  34. package/dist/lib/cli/tables-codegen.d.ts.map +1 -0
  35. package/dist/lib/cli/tables-codegen.js +249 -0
  36. package/dist/lib/condition-methods.d.ts +11 -0
  37. package/dist/lib/condition-methods.d.ts.map +1 -0
  38. package/dist/lib/condition-methods.js +20 -0
  39. package/dist/lib/db.d.ts +28 -0
  40. package/dist/lib/db.d.ts.map +1 -0
  41. package/dist/lib/db.js +224 -0
  42. package/dist/lib/dialect.d.ts +17 -0
  43. package/dist/lib/dialect.d.ts.map +1 -0
  44. package/dist/lib/dialect.js +56 -0
  45. package/dist/lib/engine/bulk/bulk-delete.d.ts +3 -0
  46. package/dist/lib/engine/bulk/bulk-delete.d.ts.map +1 -0
  47. package/dist/lib/engine/bulk/bulk-delete.js +30 -0
  48. package/dist/lib/engine/bulk/bulk-upsert.d.ts +3 -0
  49. package/dist/lib/engine/bulk/bulk-upsert.d.ts.map +1 -0
  50. package/dist/lib/engine/bulk/bulk-upsert.js +74 -0
  51. package/dist/lib/engine/rest/delete.d.ts +3 -0
  52. package/dist/lib/engine/rest/delete.d.ts.map +1 -0
  53. package/dist/lib/engine/rest/delete.js +25 -0
  54. package/dist/lib/engine/rest/get.d.ts +3 -0
  55. package/dist/lib/engine/rest/get.d.ts.map +1 -0
  56. package/dist/lib/engine/rest/get.js +32 -0
  57. package/dist/lib/engine/rest/insert.d.ts +3 -0
  58. package/dist/lib/engine/rest/insert.d.ts.map +1 -0
  59. package/dist/lib/engine/rest/insert.js +58 -0
  60. package/dist/lib/engine/rest/update.d.ts +3 -0
  61. package/dist/lib/engine/rest/update.d.ts.map +1 -0
  62. package/dist/lib/engine/rest/update.js +110 -0
  63. package/dist/lib/engine/search/search.d.ts +3 -0
  64. package/dist/lib/engine/search/search.d.ts.map +1 -0
  65. package/dist/lib/engine/search/search.js +300 -0
  66. package/dist/lib/engine/write-helpers.d.ts +8 -0
  67. package/dist/lib/engine/write-helpers.d.ts.map +1 -0
  68. package/dist/lib/engine/write-helpers.js +83 -0
  69. package/dist/lib/naming.d.ts +6 -0
  70. package/dist/lib/naming.d.ts.map +1 -0
  71. package/dist/lib/naming.js +23 -0
  72. package/dist/lib/schema/bulk-delete.d.ts +10 -0
  73. package/dist/lib/schema/bulk-delete.d.ts.map +1 -0
  74. package/dist/lib/schema/bulk-delete.js +16 -0
  75. package/dist/lib/schema/bulk-upsert.d.ts +5 -0
  76. package/dist/lib/schema/bulk-upsert.d.ts.map +1 -0
  77. package/dist/lib/schema/bulk-upsert.js +43 -0
  78. package/dist/lib/schema/helpers.d.ts +14 -0
  79. package/dist/lib/schema/helpers.d.ts.map +1 -0
  80. package/dist/lib/schema/helpers.js +33 -0
  81. package/dist/lib/schema/insert.d.ts +5 -0
  82. package/dist/lib/schema/insert.d.ts.map +1 -0
  83. package/dist/lib/schema/insert.js +43 -0
  84. package/dist/lib/schema/search.d.ts +14 -0
  85. package/dist/lib/schema/search.d.ts.map +1 -0
  86. package/dist/lib/schema/search.js +99 -0
  87. package/dist/lib/schema/update.d.ts +5 -0
  88. package/dist/lib/schema/update.d.ts.map +1 -0
  89. package/dist/lib/schema/update.js +47 -0
  90. package/dist/lib/setup-swagger.d.ts +4 -0
  91. package/dist/lib/setup-swagger.d.ts.map +1 -0
  92. package/dist/lib/setup-swagger.js +27 -0
  93. package/dist/lib/sql-api.d.ts +49 -0
  94. package/dist/lib/sql-api.d.ts.map +1 -0
  95. package/dist/lib/sql-api.js +124 -0
  96. package/dist/lib/table-helpers.d.ts +17 -0
  97. package/dist/lib/table-helpers.d.ts.map +1 -0
  98. package/dist/lib/table-helpers.js +34 -0
  99. package/dist/lib/tenant.d.ts +19 -0
  100. package/dist/lib/tenant.d.ts.map +1 -0
  101. package/dist/lib/tenant.js +110 -0
  102. package/dist/routes/auto/bulk-delete.routes.d.ts +4 -0
  103. package/dist/routes/auto/bulk-delete.routes.d.ts.map +1 -0
  104. package/dist/routes/auto/bulk-delete.routes.js +27 -0
  105. package/dist/routes/auto/bulk-upsert.routes.d.ts +4 -0
  106. package/dist/routes/auto/bulk-upsert.routes.d.ts.map +1 -0
  107. package/dist/routes/auto/bulk-upsert.routes.js +25 -0
  108. package/dist/routes/auto/delete.routes.d.ts +4 -0
  109. package/dist/routes/auto/delete.routes.d.ts.map +1 -0
  110. package/dist/routes/auto/delete.routes.js +29 -0
  111. package/dist/routes/auto/get.routes.d.ts +4 -0
  112. package/dist/routes/auto/get.routes.d.ts.map +1 -0
  113. package/dist/routes/auto/get.routes.js +26 -0
  114. package/dist/routes/auto/insert.routes.d.ts +4 -0
  115. package/dist/routes/auto/insert.routes.d.ts.map +1 -0
  116. package/dist/routes/auto/insert.routes.js +29 -0
  117. package/dist/routes/auto/plugin.d.ts +11 -0
  118. package/dist/routes/auto/plugin.d.ts.map +1 -0
  119. package/dist/routes/auto/plugin.js +81 -0
  120. package/dist/routes/auto/route-helpers.d.ts +7 -0
  121. package/dist/routes/auto/route-helpers.d.ts.map +1 -0
  122. package/dist/routes/auto/route-helpers.js +12 -0
  123. package/dist/routes/auto/search.routes.d.ts +4 -0
  124. package/dist/routes/auto/search.routes.d.ts.map +1 -0
  125. package/dist/routes/auto/search.routes.js +50 -0
  126. package/dist/routes/auto/update.routes.d.ts +4 -0
  127. package/dist/routes/auto/update.routes.d.ts.map +1 -0
  128. package/dist/routes/auto/update.routes.js +30 -0
  129. package/dist/types.d.ts +240 -0
  130. package/dist/types.d.ts.map +1 -0
  131. package/dist/types.js +7 -0
  132. package/package.json +106 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"delete.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/delete.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAI/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,YAAY,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CA2Bf"}
@@ -0,0 +1,29 @@
1
+ import { Type } from '@sinclair/typebox';
2
+ import { primaryAsString } from '../../types.js';
3
+ import { mergeOnRequests } from './route-helpers.js';
4
+ export default async function deleteRoutes(fastify, options) {
5
+ const { DbTables } = options;
6
+ for (const [tableName, tableConf] of Object.entries(DbTables)) {
7
+ const pkField = primaryAsString(tableConf.primary);
8
+ const pkType = tableConf.Schema.fields[pkField];
9
+ const responseSchema = Type.Object({
10
+ main: Type.Object({ [pkField]: pkType }),
11
+ });
12
+ fastify.route({
13
+ method: 'DELETE',
14
+ url: `/rest/${tableConf.Schema.tableName}/:id`,
15
+ schema: {
16
+ params: Type.Object({ id: Type.String() }),
17
+ response: { 200: responseSchema },
18
+ tags: [`SqlAPI-${tableName}`],
19
+ summary: `Delete ${tableName}`,
20
+ description: `Delete a record from ${tableName} by primary key`,
21
+ },
22
+ onRequest: mergeOnRequests(options, tableConf),
23
+ handler: async (request, reply) => {
24
+ const { id } = request.params;
25
+ reply.send(await fastify.sqlApi.delete(tableName, id, request));
26
+ },
27
+ });
28
+ }
29
+ }
@@ -0,0 +1,4 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { SqlApiPluginOptions } from '../../types.js';
3
+ export default function getRoutes(fastify: FastifyInstance, options: SqlApiPluginOptions): Promise<void>;
4
+ //# sourceMappingURL=get.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/get.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,SAAS,CACrC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAyBf"}
@@ -0,0 +1,26 @@
1
+ import { Type } from '@sinclair/typebox';
2
+ import { mergeOnRequests } from './route-helpers.js';
3
+ export default async function getRoutes(fastify, options) {
4
+ const { DbTables } = options;
5
+ for (const [tableName, tableConf] of Object.entries(DbTables)) {
6
+ const responseSchema = Type.Object({
7
+ main: Type.Partial(Type.Object(tableConf.Schema.fields)),
8
+ });
9
+ fastify.route({
10
+ method: 'GET',
11
+ url: `/rest/${tableConf.Schema.tableName}/:id`,
12
+ schema: {
13
+ params: Type.Object({ id: Type.String() }),
14
+ response: { 200: responseSchema },
15
+ tags: [`SqlAPI-${tableName}`],
16
+ summary: `Get ${tableName}`,
17
+ description: `Get a record from ${tableName} by primary key`,
18
+ },
19
+ onRequest: mergeOnRequests(options, tableConf),
20
+ handler: async (request, reply) => {
21
+ const { id } = request.params;
22
+ reply.send(await fastify.sqlApi.get(tableName, id, request));
23
+ },
24
+ });
25
+ }
26
+ }
@@ -0,0 +1,4 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { SqlApiPluginOptions } from '../../types.js';
3
+ export default function insertRoutes(fastify: FastifyInstance, options: SqlApiPluginOptions): Promise<void>;
4
+ //# sourceMappingURL=insert.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"insert.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/insert.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,YAAY,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAiCf"}
@@ -0,0 +1,29 @@
1
+ import { InsertTableBody, InsertTableResponse } from '../../lib/schema/insert.js';
2
+ import { mergeOnRequests, buildWriteDescription } from './route-helpers.js';
3
+ export default async function insertRoutes(fastify, options) {
4
+ const { DbTables } = options;
5
+ for (const [tableName, tableConf] of Object.entries(DbTables)) {
6
+ const bodySchema = InsertTableBody(DbTables, tableName);
7
+ const responseSchema = InsertTableResponse(DbTables, tableName);
8
+ fastify.route({
9
+ method: 'POST',
10
+ url: `/rest/${tableConf.Schema.tableName}`,
11
+ schema: {
12
+ body: bodySchema,
13
+ response: { 201: responseSchema },
14
+ tags: [`SqlAPI-${tableName}`],
15
+ summary: `Insert ${tableName}`,
16
+ description: buildWriteDescription('Insert a record into', tableName, tableConf),
17
+ },
18
+ onRequest: mergeOnRequests(options, tableConf),
19
+ handler: async (request, reply) => {
20
+ const body = request.body;
21
+ const result = await fastify.sqlApi.insert(tableName, {
22
+ record: body.main,
23
+ secondaries: body.secondaries,
24
+ }, request);
25
+ reply.status(201).send(result);
26
+ },
27
+ });
28
+ }
29
+ }
@@ -0,0 +1,11 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import { type SqlApi } from '../../lib/sql-api.js';
3
+ import type { SqlApiPluginOptions } from '../../types.js';
4
+ declare module 'fastify' {
5
+ interface FastifyInstance {
6
+ sqlApi: SqlApi;
7
+ }
8
+ }
9
+ declare const _default: (fastify: FastifyInstance, options: SqlApiPluginOptions) => Promise<void>;
10
+ export default _default;
11
+ //# sourceMappingURL=plugin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAgB,MAAM,SAAS,CAAC;AAO7D,OAAO,EAAgB,KAAK,MAAM,EAAE,MAAM,sBAAsB,CAAC;AASjE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,OAAO,QAAQ,SAAS,CAAC;IACvB,UAAU,eAAe;QACvB,MAAM,EAAE,MAAM,CAAC;KAChB;CACF;kCAGU,eAAe,WACf,mBAAmB,KAC3B,OAAO,CAAC,IAAI,CAAC;AAHhB,wBAwEoC"}
@@ -0,0 +1,81 @@
1
+ import fp from 'fastify-plugin';
2
+ import { ConditionBuilder } from 'node-condition-builder';
3
+ import { getDialect } from '../../lib/dialect.js';
4
+ import { createQueryClient } from '../../lib/db.js';
5
+ import { pgQueryable } from '../../lib/adapters/pg-adapter.js';
6
+ import { mysqlQueryable } from '../../lib/adapters/mysql-adapter.js';
7
+ import { createSqlApi } from '../../lib/sql-api.js';
8
+ import { setupSwagger } from '../../lib/setup-swagger.js';
9
+ import searchRoutes from './search.routes.js';
10
+ import getRoutes from './get.routes.js';
11
+ import insertRoutes from './insert.routes.js';
12
+ import updateRoutes from './update.routes.js';
13
+ import deleteRoutes from './delete.routes.js';
14
+ import bulkUpsertRoutes from './bulk-upsert.routes.js';
15
+ import bulkDeleteRoutes from './bulk-delete.routes.js';
16
+ export default fp(async function fastifyAutoSqlApi(fastify, options) {
17
+ // Set ConditionBuilder dialect globally
18
+ const dialect = getDialect(options.dialect || 'postgres');
19
+ ConditionBuilder.DIALECT = dialect.cbDialect;
20
+ // Lazy-init QueryClient (internal closure — not decorated on fastify)
21
+ let cachedDb;
22
+ function getDb() {
23
+ if (!cachedDb) {
24
+ const pool = (options.dialect === 'mysql' || options.dialect === 'mariadb')
25
+ ? mysqlQueryable(fastify.mysql)
26
+ : pgQueryable(fastify.pg);
27
+ cachedDb = createQueryClient(pool, options.dialect);
28
+ if (options.debug)
29
+ cachedDb.setDebug(true);
30
+ }
31
+ return cachedDb;
32
+ }
33
+ // SqlApi: exposed to parent scope via fp
34
+ let cachedSqlApi;
35
+ fastify.decorate('sqlApi', {
36
+ getter() {
37
+ if (!cachedSqlApi) {
38
+ cachedSqlApi = createSqlApi(getDb(), options.DbTables, {
39
+ getTenantId: options.getTenantId,
40
+ });
41
+ }
42
+ return cachedSqlApi;
43
+ },
44
+ });
45
+ // Routes in a child scope — prefix applies here, not at fp level
46
+ const { prefix, ...routeOptions } = options;
47
+ await fastify.register(async (instance) => {
48
+ // Structured validation errors with field-level detail
49
+ instance.setErrorHandler((error, request, reply) => {
50
+ if (error.validation) {
51
+ const fields = error.validation.map((v) => ({
52
+ path: `${error.validationContext}${v.instancePath || ''}`.replace(/\//g, '.').replace(/^\./, ''),
53
+ message: v.message || 'invalid',
54
+ code: v.keyword || 'unknown',
55
+ }));
56
+ return reply.status(400).send({
57
+ statusCode: 400,
58
+ error: 'Bad Request',
59
+ message: 'Validation failed',
60
+ fields,
61
+ });
62
+ }
63
+ const statusCode = error.statusCode || 500;
64
+ reply.status(statusCode).send({
65
+ statusCode,
66
+ error: error.name || 'Error',
67
+ message: error.message,
68
+ });
69
+ });
70
+ if (options.swagger) {
71
+ await setupSwagger(instance, options);
72
+ }
73
+ await instance.register(searchRoutes, routeOptions);
74
+ await instance.register(getRoutes, routeOptions);
75
+ await instance.register(insertRoutes, routeOptions);
76
+ await instance.register(updateRoutes, routeOptions);
77
+ await instance.register(deleteRoutes, routeOptions);
78
+ await instance.register(bulkUpsertRoutes, routeOptions);
79
+ await instance.register(bulkDeleteRoutes, routeOptions);
80
+ }, { prefix });
81
+ }, { name: 'fastify-auto-sqlapi' });
@@ -0,0 +1,7 @@
1
+ import type { FastifyRequest, FastifyReply } from 'fastify';
2
+ import type { ITable, SqlApiPluginOptions } from '../../types.js';
3
+ type RequestHook = (request: FastifyRequest, reply: FastifyReply) => Promise<void | FastifyReply>;
4
+ export declare function mergeOnRequests(options: SqlApiPluginOptions, tableConf: ITable): RequestHook[];
5
+ export declare function buildWriteDescription(action: string, tableName: string, tableConf: ITable): string;
6
+ export {};
7
+ //# sourceMappingURL=route-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-helpers.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/route-helpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAC5D,OAAO,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAElE,KAAK,WAAW,GAAG,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,GAAG,YAAY,CAAC,CAAC;AAElG,wBAAgB,eAAe,CAAC,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,EAAE,CAE9F;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,CAQlG"}
@@ -0,0 +1,12 @@
1
+ export function mergeOnRequests(options, tableConf) {
2
+ return [...(options.onRequests || []), ...(tableConf.onRequests || [])];
3
+ }
4
+ export function buildWriteDescription(action, tableName, tableConf) {
5
+ const joinList = tableConf.allowedWriteJoins
6
+ ?.map(([joinSchema]) => joinSchema.tableName)
7
+ .join(', ');
8
+ return [
9
+ `${action} ${tableName}`,
10
+ joinList && `Available secondaries: ${joinList}`,
11
+ ].filter(Boolean).join('. ');
12
+ }
@@ -0,0 +1,4 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { SqlApiPluginOptions } from '../../types.js';
3
+ export default function searchRoutes(fastify: FastifyInstance, options: SqlApiPluginOptions): Promise<void>;
4
+ //# sourceMappingURL=search.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/search.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,YAAY,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAoDf"}
@@ -0,0 +1,50 @@
1
+ import { SearchTableBodyPost, SearchTableQueryString, SearchTableResponse } from '../../lib/schema/search.js';
2
+ import { mergeOnRequests } from './route-helpers.js';
3
+ export default async function searchRoutes(fastify, options) {
4
+ const { DbTables } = options;
5
+ for (const [tableName, tableConf] of Object.entries(DbTables)) {
6
+ const bodySchema = SearchTableBodyPost(DbTables, tableName);
7
+ const responseSchema = SearchTableResponse(DbTables, tableName);
8
+ const joinList = Object.keys(bodySchema.properties.joins?.properties || {}).join(', ');
9
+ const description = [
10
+ `Search records in ${tableName}`,
11
+ joinList && `Available joins: ${joinList}`,
12
+ ].filter(Boolean).join('. ');
13
+ fastify.route({
14
+ method: 'POST',
15
+ url: `/search/${tableConf.Schema.tableName}`,
16
+ schema: {
17
+ body: bodySchema,
18
+ querystring: SearchTableQueryString,
19
+ response: { 200: responseSchema },
20
+ tags: [`SqlAPI-${tableName}`],
21
+ summary: `Search ${tableName}`,
22
+ description,
23
+ },
24
+ onRequest: mergeOnRequests(options, tableConf),
25
+ handler: async (request, reply) => {
26
+ const body = request.body;
27
+ const query = request.query;
28
+ const result = await fastify.sqlApi.search(tableName, {
29
+ filters: body.filters,
30
+ conditions: body.conditions,
31
+ joinFilters: body.joinFilters,
32
+ joins: body.joins,
33
+ joinGroups: body.joinGroups,
34
+ orderBy: query.orderBy,
35
+ paginator: (query.page || query.itemsPerPage)
36
+ ? {
37
+ page: query.page || 1,
38
+ itemsPerPage: query.itemsPerPage || 500,
39
+ }
40
+ : undefined,
41
+ computeMin: query.computeMin,
42
+ computeMax: query.computeMax,
43
+ computeSum: query.computeSum,
44
+ computeAvg: query.computeAvg,
45
+ }, request);
46
+ reply.send({ table: tableConf.Schema.tableName, ...result });
47
+ },
48
+ });
49
+ }
50
+ }
@@ -0,0 +1,4 @@
1
+ import type { FastifyInstance } from 'fastify';
2
+ import type { SqlApiPluginOptions } from '../../types.js';
3
+ export default function updateRoutes(fastify: FastifyInstance, options: SqlApiPluginOptions): Promise<void>;
4
+ //# sourceMappingURL=update.routes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"update.routes.d.ts","sourceRoot":"","sources":["../../../src/routes/auto/update.routes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,wBAA8B,YAAY,CACxC,OAAO,EAAE,eAAe,EACxB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAmCf"}
@@ -0,0 +1,30 @@
1
+ import { UpdateTableBody, UpdateTableResponse } from '../../lib/schema/update.js';
2
+ import { mergeOnRequests, buildWriteDescription } from './route-helpers.js';
3
+ export default async function updateRoutes(fastify, options) {
4
+ const { DbTables } = options;
5
+ for (const [tableName, tableConf] of Object.entries(DbTables)) {
6
+ const bodySchema = UpdateTableBody(DbTables, tableName);
7
+ const responseSchema = UpdateTableResponse(DbTables, tableName);
8
+ fastify.route({
9
+ method: 'PUT',
10
+ url: `/rest/${tableConf.Schema.tableName}`,
11
+ schema: {
12
+ body: bodySchema,
13
+ response: { 200: responseSchema },
14
+ tags: [`SqlAPI-${tableName}`],
15
+ summary: `Update ${tableName}`,
16
+ description: buildWriteDescription('Update a record in', tableName, tableConf),
17
+ },
18
+ onRequest: mergeOnRequests(options, tableConf),
19
+ handler: async (request, reply) => {
20
+ const body = request.body;
21
+ const result = await fastify.sqlApi.update(tableName, {
22
+ record: body.main,
23
+ secondaries: body.secondaries,
24
+ deletions: body.deletions,
25
+ }, request);
26
+ reply.send(result);
27
+ },
28
+ });
29
+ }
30
+ }
@@ -0,0 +1,240 @@
1
+ import type { Expression, ConditionBuilder, ConditionValueOrUndefined } from 'node-condition-builder';
2
+ import type { TSchema, TObject } from '@sinclair/typebox';
3
+ import type { FastifyRequest, FastifyReply } from 'fastify';
4
+ import type { QueryClient } from './lib/db.js';
5
+ import type { DialectName } from './lib/dialect.js';
6
+ export type { DialectName } from './lib/dialect.js';
7
+ export interface SqlApiConfig {
8
+ outputDir: string;
9
+ schema?: string;
10
+ dialect?: DialectName;
11
+ }
12
+ export interface ColumnInfo {
13
+ table_name: string;
14
+ column_name: string;
15
+ udt_name: string;
16
+ column_default: string | null;
17
+ is_nullable: string;
18
+ }
19
+ export interface TableMap {
20
+ [schemaName: string]: {
21
+ name: string;
22
+ fields: Record<string, string>;
23
+ };
24
+ }
25
+ export interface SqlResult<T = Record<string, unknown>> {
26
+ rows: T[];
27
+ affectedRows: number;
28
+ insertId?: number;
29
+ }
30
+ export interface Queryable {
31
+ query<T = Record<string, unknown>>(text: string, values?: unknown[]): Promise<SqlResult<T>>;
32
+ }
33
+ export type DbRecordValue = string | number | boolean | null | Expression;
34
+ export type DbRecord = Record<string, DbRecordValue>;
35
+ export interface SelectOptions {
36
+ tableName: string;
37
+ columns?: string;
38
+ where: string;
39
+ values: unknown[];
40
+ limit?: string | null;
41
+ orderBy?: string;
42
+ joins?: string[];
43
+ distinct?: boolean;
44
+ }
45
+ export interface SchemaDefinition<T = Record<string, TSchema>> {
46
+ col(field: string): string;
47
+ fields: T;
48
+ validation: TObject;
49
+ tableName: string;
50
+ partialValidation: TObject;
51
+ }
52
+ export type TenantId = string | number;
53
+ export interface TenantScopeDirect {
54
+ column: string;
55
+ }
56
+ export interface TenantScopeIndirect {
57
+ column: string;
58
+ through: {
59
+ schema: SchemaDefinition;
60
+ localField: string;
61
+ foreignField: string;
62
+ };
63
+ }
64
+ export type TenantScope = TenantScopeDirect | TenantScopeIndirect;
65
+ export interface TenantContext {
66
+ ids: TenantId[];
67
+ scope: TenantScope;
68
+ }
69
+ export type JoinDefinition = [SchemaDefinition, string, string | string[], string];
70
+ export type FilterRecord = Record<string, ConditionValueOrUndefined>;
71
+ export type ExtendedConditionFn = (condition: ConditionBuilder, filters: FilterRecord) => void;
72
+ export type TableFilterFn = (filters: FilterRecord) => ConditionBuilder;
73
+ export interface ITable<F extends Record<string, TSchema> = Record<string, TSchema>> {
74
+ primary: (string & keyof F) | (string & keyof F)[];
75
+ Schema: SchemaDefinition<F>;
76
+ filters: TableFilterFn;
77
+ extraFilters: Record<string, TSchema>;
78
+ allowedReadJoins?: JoinDefinition[];
79
+ allowedWriteJoins?: JoinDefinition[];
80
+ upsertMap?: Map<SchemaDefinition, string[]>;
81
+ beforeInsert?: (db: QueryClient, req: FastifyRequest, record: Record<string, unknown>) => Promise<void>;
82
+ beforeUpdate?: (db: QueryClient, req: FastifyRequest, fields: Record<string, unknown>, secondaryFieldsFetcher?: unknown) => void | Promise<void>;
83
+ afterInsert?: (db: QueryClient, req: FastifyRequest, record: Record<string, unknown>, secondaryRecords?: unknown) => Promise<void>;
84
+ defaultOrder?: string;
85
+ excludeFromCreation?: (string & keyof F)[];
86
+ distinctResults?: boolean;
87
+ onRequests?: ((request: FastifyRequest, reply: FastifyReply) => Promise<void | FastifyReply>)[];
88
+ tenantScope?: TenantScope;
89
+ }
90
+ export type DbTables = Record<string, ITable<any>>;
91
+ export declare function primaryAsString(pk: string | string[]): string;
92
+ export declare function primaryAsCols(pk: string | string[], colFn: (f: string) => string): string | string[];
93
+ export interface SwaggerOptions {
94
+ title?: string;
95
+ description?: string;
96
+ version?: string;
97
+ routePrefix?: string;
98
+ }
99
+ export interface SqlApiPluginOptions {
100
+ DbTables: DbTables;
101
+ onRequests?: ((request: FastifyRequest, reply: FastifyReply) => Promise<void | FastifyReply>)[];
102
+ prefix?: string;
103
+ swagger?: boolean | SwaggerOptions;
104
+ dialect?: DialectName;
105
+ getTenantId?: (request: FastifyRequest) => TenantId | TenantId[] | null | undefined | Promise<TenantId | TenantId[] | null | undefined>;
106
+ debug?: boolean;
107
+ }
108
+ import type { ConditionBuilder as CB } from 'node-condition-builder';
109
+ type SingleValueMethods = 'isEqual' | 'isNotEqual' | 'isGreater' | 'isNotGreater' | 'isGreaterOrEqual' | 'isNotGreaterOrEqual' | 'isLess' | 'isNotLess' | 'isLessOrEqual' | 'isNotLessOrEqual' | 'isLike' | 'isNotLike' | 'isILike' | 'isNotILike';
110
+ type BetweenMethods = 'isBetween' | 'isNotBetween';
111
+ type InMethods = 'isIn' | 'isNotIn';
112
+ type NullMethods = 'isNull' | 'isNotNull';
113
+ export type ConditionMethod = SingleValueMethods | BetweenMethods | InMethods | NullMethods;
114
+ type ConditionParams<M extends ConditionMethod> = M extends SingleValueMethods ? [value: Parameters<CB[M]>[1]] : M extends BetweenMethods ? [from: Parameters<CB[M]>[1], to: Parameters<CB[M]>[2]] : M extends InMethods ? [values: Parameters<CB[M]>[1]] : M extends NullMethods ? [] : never;
115
+ export type SearchCondition<F extends string = string> = {
116
+ [M in ConditionMethod]: {
117
+ field: F;
118
+ method: M;
119
+ params: ConditionParams<M>;
120
+ };
121
+ }[ConditionMethod];
122
+ export interface Paginator {
123
+ page: number;
124
+ itemsPerPage: number;
125
+ }
126
+ export interface AggregationRequest {
127
+ by?: string;
128
+ distinctCount?: string[];
129
+ min?: string[];
130
+ max?: string[];
131
+ sum?: string[];
132
+ }
133
+ export interface JoinGroupRequest {
134
+ aggregations: AggregationRequest;
135
+ filters?: FilterRecord;
136
+ }
137
+ export interface SearchParams {
138
+ db: QueryClient;
139
+ tableConf: ITable;
140
+ filters?: FilterRecord;
141
+ conditions?: SearchCondition[];
142
+ joinFilters?: Record<string, FilterRecord>;
143
+ joins?: Record<string, {
144
+ filters?: FilterRecord;
145
+ }>;
146
+ joinGroups?: Record<string, JoinGroupRequest>;
147
+ orderBy?: string;
148
+ paginator?: Paginator;
149
+ computeMin?: string;
150
+ computeMax?: string;
151
+ computeSum?: string;
152
+ computeAvg?: string;
153
+ tenant?: TenantContext;
154
+ }
155
+ export interface PaginationResult {
156
+ total: number;
157
+ pages: number;
158
+ computed?: Record<string, Record<string, unknown>>;
159
+ paginator: Paginator;
160
+ }
161
+ export interface SearchResult {
162
+ main: Record<string, unknown>[];
163
+ joins?: Record<string, Record<string, unknown>[]>;
164
+ joinGroups?: Record<string, Record<string, unknown>>;
165
+ pagination?: PaginationResult;
166
+ }
167
+ export interface InsertParams {
168
+ db: QueryClient;
169
+ tableConf: ITable;
170
+ dbTables: DbTables;
171
+ request: FastifyRequest;
172
+ record: Record<string, unknown>;
173
+ secondaries?: Record<string, Record<string, unknown>[]>;
174
+ tenant?: TenantContext;
175
+ }
176
+ export interface InsertResult {
177
+ main: Record<string, unknown>;
178
+ secondaries?: Record<string, Record<string, unknown>[]>;
179
+ }
180
+ export interface GetParams {
181
+ db: QueryClient;
182
+ tableConf: ITable;
183
+ id: string | number;
184
+ tenant?: TenantContext;
185
+ }
186
+ export interface GetResult {
187
+ main: Record<string, unknown>;
188
+ }
189
+ export interface DeleteParams {
190
+ db: QueryClient;
191
+ tableConf: ITable;
192
+ id: string | number;
193
+ tenant?: TenantContext;
194
+ }
195
+ export interface DeleteResult {
196
+ main: Record<string, unknown>;
197
+ }
198
+ export interface BulkUpsertItem {
199
+ main: Record<string, unknown>;
200
+ secondaries?: Record<string, Record<string, unknown>[]>;
201
+ deletions?: Record<string, Record<string, unknown>[]>;
202
+ }
203
+ export interface BulkUpsertParams {
204
+ db: QueryClient;
205
+ tableConf: ITable;
206
+ dbTables: DbTables;
207
+ request: FastifyRequest;
208
+ items: BulkUpsertItem[];
209
+ tenant?: TenantContext;
210
+ }
211
+ export interface BulkUpsertResult {
212
+ main: Record<string, unknown>;
213
+ secondaries?: Record<string, Record<string, unknown>[]>;
214
+ deletions?: Record<string, Record<string, unknown>[]>;
215
+ }
216
+ export interface BulkDeleteParams {
217
+ db: QueryClient;
218
+ tableConf: ITable;
219
+ ids: (string | number)[];
220
+ tenant?: TenantContext;
221
+ }
222
+ export interface BulkDeleteResult {
223
+ main: Record<string, unknown>;
224
+ }
225
+ export interface UpdateParams {
226
+ db: QueryClient;
227
+ tableConf: ITable;
228
+ dbTables: DbTables;
229
+ request: FastifyRequest;
230
+ record: Record<string, unknown>;
231
+ secondaries?: Record<string, Record<string, unknown>[]>;
232
+ deletions?: Record<string, Record<string, unknown>[]>;
233
+ tenant?: TenantContext;
234
+ }
235
+ export interface UpdateResult {
236
+ main: Record<string, unknown>;
237
+ secondaries?: Record<string, Record<string, unknown>[]>;
238
+ deletions?: Record<string, Record<string, unknown>[]>;
239
+ }
240
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
1
+ // Primary key helpers
2
+ export function primaryAsString(pk) {
3
+ return Array.isArray(pk) ? pk[0] : pk;
4
+ }
5
+ export function primaryAsCols(pk, colFn) {
6
+ return Array.isArray(pk) ? pk.map(colFn) : colFn(pk);
7
+ }