mythik-server 0.1.1 → 0.1.3

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 (39) hide show
  1. package/README.md +164 -28
  2. package/dist/audit.js +1 -1
  3. package/dist/audit.js.map +1 -1
  4. package/dist/auth/db-auth-provider.d.ts +2 -2
  5. package/dist/auth/db-auth-provider.d.ts.map +1 -1
  6. package/dist/auth/db-auth-provider.js +17 -15
  7. package/dist/auth/db-auth-provider.js.map +1 -1
  8. package/dist/auth/scope-filter.d.ts +9 -1
  9. package/dist/auth/scope-filter.d.ts.map +1 -1
  10. package/dist/auth/scope-filter.js +27 -5
  11. package/dist/auth/scope-filter.js.map +1 -1
  12. package/dist/catalog-builder.d.ts +2 -1
  13. package/dist/catalog-builder.d.ts.map +1 -1
  14. package/dist/catalog-builder.js +24 -13
  15. package/dist/catalog-builder.js.map +1 -1
  16. package/dist/connection.d.ts +4 -2
  17. package/dist/connection.d.ts.map +1 -1
  18. package/dist/connection.js +74 -7
  19. package/dist/connection.js.map +1 -1
  20. package/dist/crud-builder.d.ts +8 -3
  21. package/dist/crud-builder.d.ts.map +1 -1
  22. package/dist/crud-builder.js +40 -16
  23. package/dist/crud-builder.js.map +1 -1
  24. package/dist/middleware/error-handler.js +1 -1
  25. package/dist/middleware/error-handler.js.map +1 -1
  26. package/dist/query-engine.d.ts +22 -5
  27. package/dist/query-engine.d.ts.map +1 -1
  28. package/dist/query-engine.js +47 -18
  29. package/dist/query-engine.js.map +1 -1
  30. package/dist/server.d.ts.map +1 -1
  31. package/dist/server.js +114 -159
  32. package/dist/server.js.map +1 -1
  33. package/dist/spec-serving.d.ts +7 -3
  34. package/dist/spec-serving.d.ts.map +1 -1
  35. package/dist/spec-serving.js +36 -12
  36. package/dist/spec-serving.js.map +1 -1
  37. package/dist/types.d.ts +34 -11
  38. package/dist/types.d.ts.map +1 -1
  39. package/package.json +2 -3
@@ -1,18 +1,85 @@
1
- import sql from 'mssql';
1
+ import { createSqlDriver } from 'mythik/server';
2
2
  import { resolveEnvVars } from './spec-loader.js';
3
- export async function createConnectionPool(config) {
3
+ const warnedLegacyDefaultConfigs = new WeakSet();
4
+ function withoutType(config) {
5
+ const { type: _type, ...rest } = config;
6
+ return rest;
7
+ }
8
+ function normalizePort(value, fallback) {
9
+ if (value === undefined || value === null || value === '')
10
+ return fallback;
11
+ const parsed = typeof value === 'number' ? value : Number(value);
12
+ return Number.isFinite(parsed) ? parsed : fallback;
13
+ }
14
+ export function resolveDatabaseDialect(config, expectedDialect) {
15
+ const declaredDialect = config.type ?? 'sqlserver';
16
+ if (expectedDialect && declaredDialect !== expectedDialect) {
17
+ throw new Error(`Database dialect mismatch: ApiSpec requested "${expectedDialect}" but database config is "${declaredDialect}".`);
18
+ }
19
+ if (!config.type && (!expectedDialect || expectedDialect === 'sqlserver') && !warnedLegacyDefaultConfigs.has(config)) {
20
+ warnedLegacyDefaultConfigs.add(config);
21
+ console.warn('Mythik server database config omitted "type"; defaulting to "sqlserver" for backwards compatibility.');
22
+ }
23
+ return expectedDialect ?? declaredDialect;
24
+ }
25
+ function sqlServerConnection(config) {
4
26
  const resolved = resolveEnvVars(config);
5
- const pool = new sql.ConnectionPool({
27
+ return {
6
28
  server: resolved.server,
7
29
  database: resolved.database,
8
30
  user: resolved.user,
9
31
  password: resolved.password,
10
- port: resolved.port ?? 1433,
32
+ port: normalizePort(resolved.port, 1433),
11
33
  options: {
12
34
  trustServerCertificate: resolved.trustServerCertificate ?? true,
35
+ trustedConnection: resolved.trustedConnection ?? false,
13
36
  },
14
- });
15
- await pool.connect();
16
- return pool;
37
+ };
38
+ }
39
+ function postgresConnection(config) {
40
+ const resolved = resolveEnvVars(config);
41
+ if (resolved.connectionString) {
42
+ return { ...withoutType(resolved), connectionString: resolved.connectionString };
43
+ }
44
+ return withoutType(resolved);
45
+ }
46
+ function mysqlConnection(config) {
47
+ const resolved = resolveEnvVars(config);
48
+ if (resolved.uri) {
49
+ return resolved.uri;
50
+ }
51
+ return withoutType(resolved);
52
+ }
53
+ function sqliteConnection(config) {
54
+ const resolved = resolveEnvVars(config);
55
+ return withoutType(resolved);
56
+ }
57
+ export function toSqlDriverConfig(config, expectedDialect) {
58
+ const dialect = resolveDatabaseDialect(config, expectedDialect);
59
+ if (dialect === 'sqlserver') {
60
+ return {
61
+ dialect,
62
+ connection: sqlServerConnection(config),
63
+ };
64
+ }
65
+ if (dialect === 'postgres') {
66
+ return {
67
+ dialect,
68
+ connection: postgresConnection(config),
69
+ };
70
+ }
71
+ if (dialect === 'mysql') {
72
+ return {
73
+ dialect,
74
+ connection: mysqlConnection(config),
75
+ };
76
+ }
77
+ return {
78
+ dialect,
79
+ connection: sqliteConnection(config),
80
+ };
81
+ }
82
+ export function createDatabaseDriver(config, expectedDialect) {
83
+ return createSqlDriver(toSqlDriverConfig(config, expectedDialect));
17
84
  }
18
85
  //# sourceMappingURL=connection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"AAAA,OAAO,GAA4B,MAAM,OAAO,CAAC;AAEjD,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAElD,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,MAAwB;IACjE,MAAM,QAAQ,GAAG,cAAc,CAAC,MAA4C,CAAC,CAAC;IAE9E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,cAAc,CAAC;QAClC,MAAM,EAAE,QAAQ,CAAC,MAAgB;QACjC,QAAQ,EAAE,QAAQ,CAAC,QAAkB;QACrC,IAAI,EAAE,QAAQ,CAAC,IAA0B;QACzC,QAAQ,EAAE,QAAQ,CAAC,QAA8B;QACjD,IAAI,EAAG,QAAQ,CAAC,IAAe,IAAI,IAAI;QACvC,OAAO,EAAE;YACP,sBAAsB,EAAG,QAAQ,CAAC,sBAAkC,IAAI,IAAI;SAC7E;KACF,CAAC,CAAC;IAEH,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;IACrB,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"connection.js","sourceRoot":"","sources":["../src/connection.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,18 @@
1
+ import type { SqlDriver, SqlStatement } from 'mythik/server';
1
2
  export declare function filterFields(body: Record<string, unknown>, allowedFields: string[]): Record<string, unknown>;
2
- export declare function buildInsertQuery(table: string, fields: Record<string, unknown>, primaryKey?: string): {
3
+ export declare function buildInsertQuery(driver: SqlDriver, table: string, fields: Record<string, unknown>): {
3
4
  sql: string;
4
5
  params: Record<string, unknown>;
5
6
  };
6
- export declare function buildUpdateQuery(table: string, primaryKey: string, pkValue: unknown, fields: Record<string, unknown>): {
7
+ export declare function buildUpdateQuery(driver: SqlDriver, table: string, primaryKey: string, pkValue: unknown, fields: Record<string, unknown>, extraWhere?: SqlStatement): {
7
8
  sql: string;
8
9
  params: Record<string, unknown>;
9
10
  };
10
- export declare function buildDeleteQuery(table: string, primaryKey: string, pkValue: unknown): {
11
+ export declare function buildDeleteQuery(driver: SqlDriver, table: string, primaryKey: string, pkValue: unknown, extraWhere?: SqlStatement): {
12
+ sql: string;
13
+ params: Record<string, unknown>;
14
+ };
15
+ export declare function buildSelectByPrimaryKeyQuery(driver: SqlDriver, table: string, primaryKey: string, pkValue: unknown, extraWhere?: SqlStatement): {
11
16
  sql: string;
12
17
  params: Record<string, unknown>;
13
18
  };
@@ -1 +1 @@
1
- {"version":3,"file":"crud-builder.d.ts","sourceRoot":"","sources":["../src/crud-builder.ts"],"names":[],"mappings":"AAEA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS5G;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,CAAC,EAAE,MAAM,GAClB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAelD;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAUlD;AAED,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,GACf;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAKlD"}
1
+ {"version":3,"file":"crud-builder.d.ts","sourceRoot":"","sources":["../src/crud-builder.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE7D,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,aAAa,EAAE,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAS5G;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC9B;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAQlD;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC/B,UAAU,CAAC,EAAE,YAAY,GACxB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAQlD;AAED,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,YAAY,GACxB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAKlD;AAED,wBAAgB,4BAA4B,CAC1C,MAAM,EAAE,SAAS,EACjB,KAAK,EAAE,MAAM,EACb,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,OAAO,EAChB,UAAU,CAAC,EAAE,YAAY,GACxB;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAQlD"}
@@ -9,35 +9,59 @@ export function filterFields(body, allowedFields) {
9
9
  }
10
10
  return filtered;
11
11
  }
12
- export function buildInsertQuery(table, fields, primaryKey) {
12
+ export function buildInsertQuery(driver, table, fields) {
13
13
  assertValidIdentifier(table, 'crud.table');
14
14
  const columns = Object.keys(fields);
15
15
  for (const col of columns) {
16
16
  assertValidIdentifier(col, 'crud field');
17
17
  }
18
- const columnsList = columns.map(c => `[${c}]`).join(', ');
19
- const paramsList = columns.map(c => `@${c}`).join(', ');
20
- // Trigger-safe: INSERT + SELECT back by SCOPE_IDENTITY() instead of OUTPUT INSERTED.*
21
- const selectBack = primaryKey
22
- ? `; SELECT * FROM [${table}] WHERE [${primaryKey}] = SCOPE_IDENTITY()`
23
- : '';
24
- const sql = `INSERT INTO [${table}] (${columnsList}) VALUES (${paramsList})${selectBack}`;
25
- return { sql, params: { ...fields } };
18
+ const statement = driver.buildInsertReturning(table, fields);
19
+ return { sql: statement.sql, params: objectParams(statement) };
26
20
  }
27
- export function buildUpdateQuery(table, primaryKey, pkValue, fields) {
21
+ export function buildUpdateQuery(driver, table, primaryKey, pkValue, fields, extraWhere) {
28
22
  assertValidIdentifier(table, 'crud.table');
29
23
  assertValidIdentifier(primaryKey, 'crud.primaryKey');
30
24
  for (const col of Object.keys(fields)) {
31
25
  assertValidIdentifier(col, 'crud field');
32
26
  }
33
- const setClauses = Object.keys(fields).map(c => `[${c}] = @${c}`).join(', ');
34
- const sql = `UPDATE [${table}] SET ${setClauses} WHERE [${primaryKey}] = @_pkValue; SELECT * FROM [${table}] WHERE [${primaryKey}] = @_pkValue`;
35
- return { sql, params: { ...fields, _pkValue: pkValue } };
27
+ const statement = driver.buildUpdateReturning(table, fields, primaryKeyWhere(driver, primaryKey, pkValue, extraWhere));
28
+ return { sql: statement.sql, params: objectParams(statement) };
36
29
  }
37
- export function buildDeleteQuery(table, primaryKey, pkValue) {
30
+ export function buildDeleteQuery(driver, table, primaryKey, pkValue, extraWhere) {
38
31
  assertValidIdentifier(table, 'crud.table');
39
32
  assertValidIdentifier(primaryKey, 'crud.primaryKey');
40
- const sql = `DELETE FROM [${table}] WHERE [${primaryKey}] = @_pkValue`;
41
- return { sql, params: { _pkValue: pkValue } };
33
+ const statement = driver.buildDelete(table, primaryKeyWhere(driver, primaryKey, pkValue, extraWhere));
34
+ return { sql: statement.sql, params: objectParams(statement) };
35
+ }
36
+ export function buildSelectByPrimaryKeyQuery(driver, table, primaryKey, pkValue, extraWhere) {
37
+ assertValidIdentifier(table, 'crud.table');
38
+ assertValidIdentifier(primaryKey, 'crud.primaryKey');
39
+ const where = primaryKeyWhere(driver, primaryKey, pkValue, extraWhere);
40
+ return {
41
+ sql: `SELECT * FROM ${driver.quoteIdent(table)} ${where.sql}`,
42
+ params: objectParams(where),
43
+ };
44
+ }
45
+ function primaryKeyWhere(driver, primaryKey, pkValue, extraWhere) {
46
+ const params = { _pkValue: pkValue };
47
+ if (extraWhere) {
48
+ return {
49
+ sql: `WHERE (${extraWhere.sql}) AND ${driver.quoteIdent(primaryKey)} = @_pkValue`,
50
+ params: { ...objectParams(extraWhere), ...params },
51
+ };
52
+ }
53
+ return {
54
+ sql: `WHERE ${driver.quoteIdent(primaryKey)} = @_pkValue`,
55
+ params,
56
+ };
57
+ }
58
+ function objectParams(statement) {
59
+ const params = statement.params;
60
+ if (!params)
61
+ return {};
62
+ if (Array.isArray(params)) {
63
+ throw new Error('CRUD statements require named object parameters.');
64
+ }
65
+ return params;
42
66
  }
43
67
  //# sourceMappingURL=crud-builder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"crud-builder.js","sourceRoot":"","sources":["../src/crud-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"crud-builder.js","sourceRoot":"","sources":["../src/crud-builder.ts"],"names":[],"mappings":"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"}
@@ -28,7 +28,7 @@ export function createErrorHandler(devMode) {
28
28
  });
29
29
  return;
30
30
  }
31
- // SQL errors (mssql errors have a 'number' property)
31
+ // SQL Server driver errors expose a numeric code.
32
32
  if ('number' in err && typeof err.number === 'number') {
33
33
  const message = devMode ? err.message : 'Database error';
34
34
  res.status(400).json({
@@ -1 +1 @@
1
- {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO,SAAS,YAAY,CAAC,GAAa,EAAE,IAAa,EAAE,GAAa,EAAE,KAAmB;QAC3F,oBAAoB;QACpB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aACjF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,YAAY;QACZ,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aACnD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,cAAc;QACd,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,YAAY,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aAChE,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,YAAY;QACZ,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;aAC3F,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,qDAAqD;QACrD,IAAI,QAAQ,IAAI,GAAG,IAAI,OAAQ,GAA+B,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACnF,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE;aACxC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,+BAA+B;QAC/B,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aAC3D,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,YAAY;QACZ,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAChE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../src/middleware/error-handler.ts"],"names":[],"mappings":"AASA,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,OAAO,SAAS,YAAY,CAAC,GAAa,EAAE,IAAa,EAAE,GAAa,EAAE,KAAmB;QAC3F,oBAAoB;QACpB,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aACjF,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,YAAY;QACZ,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aACnD,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,cAAc;QACd,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACxB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,YAAY,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aAChE,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,YAAY;QACZ,IAAI,GAAG,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7B,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,WAAW,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,EAAE;aAC3F,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,kDAAkD;QAClD,IAAI,QAAQ,IAAI,GAAG,IAAI,OAAQ,GAA+B,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;YACnF,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC;YACzD,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;gBACnB,KAAK,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,OAAO,EAAE;aACxC,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,+BAA+B;QAC/B,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;YACf,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC;gBAC1B,KAAK,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,IAAI,OAAO,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE;aAC3D,CAAC,CAAC;YACH,OAAO;QACT,CAAC;QAED,YAAY;QACZ,IAAI,OAAO,EAAE,CAAC;YACZ,OAAO,CAAC,KAAK,CAAC,uBAAuB,EAAE,GAAG,CAAC,CAAC;QAC9C,CAAC;QACD,MAAM,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,uBAAuB,CAAC;QAChE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;YACnB,KAAK,EAAE,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE;SAC3C,CAAC,CAAC;IACL,CAAC,CAAC;AACJ,CAAC"}
@@ -1,8 +1,25 @@
1
- import { type ISqlTypeFactoryWithNoParams } from 'mssql';
1
+ import type { SqlDriver } from 'mythik/server';
2
2
  import type { ParamConfig } from './types.js';
3
3
  export declare function parseParamValue(raw: string | undefined, type: ParamConfig['type'], max?: number): unknown;
4
- export declare function getSqlType(type: ParamConfig['type']): ISqlTypeFactoryWithNoParams;
5
- export declare function buildPaginatedQuery(query: string): string;
6
- export declare function buildCountQuery(query: string): string;
7
- export declare function buildTotalsQuery(query: string, totals: string[]): string | null;
4
+ export interface PaginationQueryOptions {
5
+ driver: SqlDriver;
6
+ limit: number;
7
+ offset: number;
8
+ }
9
+ export declare function buildPaginatedQuery(query: string, options: PaginationQueryOptions): string;
10
+ export interface CountQueryOptions {
11
+ scopeClause?: {
12
+ sql: string;
13
+ } | null;
14
+ driver?: SqlDriver;
15
+ }
16
+ export interface EndpointCountQueryOptions extends CountQueryOptions {
17
+ customCount?: string;
18
+ }
19
+ export declare function buildCountQuery(query: string, options?: CountQueryOptions): string;
20
+ export declare function buildEndpointCountQuery(query: string, options?: EndpointCountQueryOptions): string;
21
+ export interface TotalsQueryOptions {
22
+ driver?: SqlDriver;
23
+ }
24
+ export declare function buildTotalsQuery(query: string, totals: string[], options?: TotalsQueryOptions): string | null;
8
25
  //# sourceMappingURL=query-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../src/query-engine.ts"],"names":[],"mappings":"AAAA,OAAY,EAAE,KAAK,2BAA2B,EAAE,MAAM,OAAO,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EACzB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAqBT;AAED,wBAAgB,UAAU,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,2BAA2B,CASjF;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAEzD;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUrD;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,IAAI,CAmB/E"}
1
+ {"version":3,"file":"query-engine.d.ts","sourceRoot":"","sources":["../src/query-engine.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAI9C,wBAAgB,eAAe,CAC7B,GAAG,EAAE,MAAM,GAAG,SAAS,EACvB,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,EACzB,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAqBT;AAED,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,SAAS,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAE1F;AAED,MAAM,WAAW,iBAAiB;IAChC,WAAW,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IACrC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAED,MAAM,WAAW,yBAA0B,SAAQ,iBAAiB;IAClE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA0BD,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,iBAAsB,GAAG,MAAM,CAgBtF;AAED,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,yBAA8B,GACtC,MAAM,CAUR;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AAMD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,EAAE,OAAO,GAAE,kBAAuB,GAAG,MAAM,GAAG,IAAI,CAmBjH"}
@@ -1,4 +1,5 @@
1
- import sql from 'mssql';
1
+ import { SCOPE_ALIAS } from './auth/scope-filter.js';
2
+ import { assertValidIdentifier } from './validation/identifier-guard.js';
2
3
  export function parseParamValue(raw, type, max) {
3
4
  if (raw === undefined || raw === '')
4
5
  return null;
@@ -22,45 +23,73 @@ export function parseParamValue(raw, type, max) {
22
23
  return raw;
23
24
  }
24
25
  }
25
- export function getSqlType(type) {
26
- switch (type) {
27
- case 'int': return sql.Int;
28
- case 'float': return sql.Float;
29
- case 'boolean': return sql.Bit;
30
- case 'date': return sql.NVarChar;
31
- case 'string':
32
- default: return sql.NVarChar;
26
+ export function buildPaginatedQuery(query, options) {
27
+ return options.driver.paginate(query, options.limit, options.offset);
28
+ }
29
+ function stripTrailingOrderBy(query) {
30
+ return query.replace(/\s+ORDER\s+BY\s+[\s\S]+$/i, '').trim();
31
+ }
32
+ const SCOPE_COUNT_MACRO_PATTERN = /{{\s*scope(Where|And)(?::\s*([^}\s]+))?\s*}}/g;
33
+ function scopeSqlForAlias(sql, alias) {
34
+ if (alias) {
35
+ assertValidIdentifier(alias, 'endpoint.count scope macro alias');
36
+ return sql.replaceAll(`${SCOPE_ALIAS}.`, `${alias}.`);
33
37
  }
38
+ return sql.replaceAll(`${SCOPE_ALIAS}.`, '');
34
39
  }
35
- export function buildPaginatedQuery(query) {
36
- return `${query}\nOFFSET @_offset ROWS FETCH NEXT @_pageSize ROWS ONLY`;
40
+ function renderCountScopeMacros(countSql, scopeClause) {
41
+ return countSql
42
+ .replace(SCOPE_COUNT_MACRO_PATTERN, (_match, macroKind, alias) => {
43
+ if (!scopeClause)
44
+ return '';
45
+ const keyword = macroKind === 'Where' ? 'WHERE' : 'AND';
46
+ return `${keyword} ${scopeSqlForAlias(scopeClause.sql, alias)}`;
47
+ })
48
+ .trim();
37
49
  }
38
- export function buildCountQuery(query) {
50
+ export function buildCountQuery(query, options = {}) {
51
+ if (options.scopeClause) {
52
+ const source = stripTrailingOrderBy(query);
53
+ const scopedSource = `SELECT * FROM (\n${source}\n) AS ${SCOPE_ALIAS}\nWHERE ${options.scopeClause.sql}`;
54
+ return `SELECT COUNT(*) as _total FROM (\n${scopedSource}\n) AS _countSource`;
55
+ }
39
56
  const fromMatch = query.match(/\bFROM\b/i);
40
57
  if (!fromMatch || fromMatch.index === undefined) {
41
58
  return `SELECT COUNT(*) as _total FROM (${query}) as _countSource`;
42
59
  }
43
60
  const afterFrom = query.slice(fromMatch.index);
44
- const stripped = afterFrom.replace(/\s+ORDER\s+BY\s+[\s\S]+$/i, '');
61
+ const stripped = stripTrailingOrderBy(afterFrom);
45
62
  return `SELECT COUNT(*) as _total ${stripped}`;
46
63
  }
47
- export function buildTotalsQuery(query, totals) {
64
+ export function buildEndpointCountQuery(query, options = {}) {
65
+ if (options.customCount) {
66
+ return renderCountScopeMacros(options.customCount, options.scopeClause);
67
+ }
68
+ if (options.driver && !options.scopeClause) {
69
+ return options.driver.countQuery(query);
70
+ }
71
+ return buildCountQuery(query, options);
72
+ }
73
+ function quoteAlias(alias, driver) {
74
+ return driver ? driver.quoteIdent(alias) : `[${alias.replace(/]/g, ']]')}]`;
75
+ }
76
+ export function buildTotalsQuery(query, totals, options = {}) {
48
77
  if (!totals || totals.length === 0)
49
78
  return null;
50
79
  const aggregations = totals.map(t => {
51
80
  if (t === 'COUNT:*')
52
- return 'COUNT(*) as [COUNT:*]';
81
+ return `COUNT(*) as ${quoteAlias('COUNT:*', options.driver)}`;
53
82
  const [fn, field] = t.split(':');
54
83
  if (fn === 'COUNT_DISTINCT')
55
- return `COUNT(DISTINCT ${field}) as [COUNT_DISTINCT:${field}]`;
56
- return `${fn}(${field}) as [${fn}:${field}]`;
84
+ return `COUNT(DISTINCT ${field}) as ${quoteAlias(`COUNT_DISTINCT:${field}`, options.driver)}`;
85
+ return `${fn}(${field}) as ${quoteAlias(`${fn}:${field}`, options.driver)}`;
57
86
  });
58
87
  const selectClause = aggregations.join(', ');
59
88
  const fromMatch = query.match(/\bFROM\b/i);
60
89
  if (!fromMatch || fromMatch.index === undefined)
61
90
  return null;
62
91
  const afterFrom = query.slice(fromMatch.index);
63
- const stripped = afterFrom.replace(/\s+ORDER\s+BY\s+[\s\S]+$/i, '');
92
+ const stripped = stripTrailingOrderBy(afterFrom);
64
93
  return `SELECT ${selectClause} ${stripped}`;
65
94
  }
66
95
  //# sourceMappingURL=query-engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"query-engine.js","sourceRoot":"","sources":["../src/query-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query-engine.js","sourceRoot":"","sources":["../src/query-engine.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAW,YAAY,EAAE,kBAAkB,EAAqD,MAAM,YAAY,CAAC;AAkD/H,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CA2OrE"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAW,YAAY,EAAE,kBAAkB,EAAqD,MAAM,YAAY,CAAC;AAmD/H,wBAAgB,YAAY,CAAC,MAAM,EAAE,kBAAkB,GAAG,YAAY,CA8OrE"}