@balena/pinejs 17.1.0-build-joshbwlng-tasks-9f3f42ef1bf62714507bacc7842e99841b116d94-1 → 17.1.0-build-model-based-typings-c276ef4fb8482a246c25940d617d76b76847eff8-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 (64) hide show
  1. package/.pinejs-cache.json +1 -1
  2. package/.versionbot/CHANGELOG.yml +232 -10
  3. package/CHANGELOG.md +70 -3
  4. package/out/config-loader/env.d.ts +0 -4
  5. package/out/config-loader/env.js +1 -5
  6. package/out/config-loader/env.js.map +1 -1
  7. package/out/data-server/sbvr-server.js +3 -2
  8. package/out/data-server/sbvr-server.js.map +1 -1
  9. package/out/database-layer/db.d.ts +0 -3
  10. package/out/database-layer/db.js +0 -17
  11. package/out/database-layer/db.js.map +1 -1
  12. package/out/migrator/migrations.d.ts +58 -0
  13. package/out/migrator/migrations.js +3 -0
  14. package/out/migrator/migrations.js.map +1 -0
  15. package/out/migrator/sync.d.ts +17 -0
  16. package/out/migrator/sync.js +39 -40
  17. package/out/migrator/sync.js.map +1 -1
  18. package/out/sbvr-api/dev.d.ts +22 -0
  19. package/out/sbvr-api/dev.js +3 -0
  20. package/out/sbvr-api/dev.js.map +1 -0
  21. package/out/sbvr-api/hooks.d.ts +28 -28
  22. package/out/sbvr-api/hooks.js.map +1 -1
  23. package/out/sbvr-api/permissions.d.ts +26 -2
  24. package/out/sbvr-api/permissions.js +39 -40
  25. package/out/sbvr-api/permissions.js.map +1 -1
  26. package/out/sbvr-api/sbvr-utils.d.ts +46 -6
  27. package/out/sbvr-api/sbvr-utils.js +44 -44
  28. package/out/sbvr-api/sbvr-utils.js.map +1 -1
  29. package/out/sbvr-api/user.d.ts +236 -0
  30. package/out/sbvr-api/user.js +3 -0
  31. package/out/sbvr-api/user.js.map +1 -0
  32. package/out/server-glue/module.d.ts +0 -1
  33. package/out/server-glue/module.js +1 -4
  34. package/out/server-glue/module.js.map +1 -1
  35. package/package.json +19 -20
  36. package/src/config-loader/env.ts +1 -6
  37. package/src/data-server/sbvr-server.js +3 -2
  38. package/src/database-layer/db.ts +0 -25
  39. package/src/migrator/migrations.ts +64 -0
  40. package/src/migrator/sync.ts +46 -41
  41. package/src/sbvr-api/dev.ts +26 -0
  42. package/src/sbvr-api/hooks.ts +19 -18
  43. package/src/sbvr-api/permissions.ts +54 -48
  44. package/src/sbvr-api/sbvr-utils.ts +93 -53
  45. package/src/sbvr-api/user.ts +216 -0
  46. package/src/server-glue/module.ts +0 -3
  47. package/out/tasks/common.d.ts +0 -4
  48. package/out/tasks/common.js +0 -13
  49. package/out/tasks/common.js.map +0 -1
  50. package/out/tasks/index.d.ts +0 -8
  51. package/out/tasks/index.js +0 -140
  52. package/out/tasks/index.js.map +0 -1
  53. package/out/tasks/tasks.sbvr +0 -55
  54. package/out/tasks/types.d.ts +0 -37
  55. package/out/tasks/types.js +0 -10
  56. package/out/tasks/types.js.map +0 -1
  57. package/out/tasks/worker.d.ts +0 -16
  58. package/out/tasks/worker.js +0 -226
  59. package/out/tasks/worker.js.map +0 -1
  60. package/src/tasks/common.ts +0 -14
  61. package/src/tasks/index.ts +0 -155
  62. package/src/tasks/tasks.sbvr +0 -55
  63. package/src/tasks/types.ts +0 -56
  64. package/src/tasks/worker.ts +0 -276
@@ -49,7 +49,7 @@ export const cache = {
49
49
  apiKeyActorId: false as CacheOpts,
50
50
  };
51
51
 
52
- import { boolVar, intVar } from '@balena/env-parsing';
52
+ import { boolVar } from '@balena/env-parsing';
53
53
  import memoize from 'memoizee';
54
54
  import memoizeWeak = require('memoizee/weak');
55
55
  export const createCache = <T extends (...args: any[]) => any>(
@@ -146,8 +146,3 @@ export const migrator = {
146
146
  */
147
147
  asyncMigrationIsEnabled: boolVar('PINEJS_ASYNC_MIGRATION_ENABLED', true),
148
148
  };
149
-
150
- export const tasks = {
151
- queueConcurrency: intVar('PINEJS_QUEUE_CONCURRENCY', 0),
152
- queueIntervalMS: intVar('PINEJS_QUEUE_INTERVAL_MS', 1000),
153
- };
@@ -133,14 +133,15 @@ export async function setup(app, sbvrUtils, db) {
133
133
  },
134
134
  },
135
135
  })
136
- .then(async (/** @type { Array<{ [key: string]: any }> } */ result) => {
136
+ .then(async (result) => {
137
137
  if (result.length === 0) {
138
138
  throw new Error('No SE data model found');
139
139
  }
140
140
  const instance = result[0];
141
141
  await sbvrUtils.executeModel(tx, {
142
142
  apiRoot: instance.is_of__vocabulary,
143
- modelText: instance.model_value.value,
143
+ // prettier-ignore
144
+ modelText: /** @type { string } */ (instance.model_value.value),
144
145
  });
145
146
  });
146
147
  await isServerOnAir(true);
@@ -98,13 +98,6 @@ export interface Database extends BaseDatabase {
98
98
  ) => Promise<Result>;
99
99
  transaction: TransactionFn;
100
100
  readTransaction: TransactionFn;
101
- on?: (
102
- name: 'notification',
103
- fn: (...args: any[]) => Promise<void>,
104
- options?: {
105
- channel?: string;
106
- },
107
- ) => void;
108
101
  }
109
102
 
110
103
  interface EngineParams {
@@ -696,24 +689,6 @@ if (maybePg != null) {
696
689
  return {
697
690
  engine: Engines.postgres,
698
691
  executeSql: atomicExecuteSql,
699
- on: async (name, fn, options) => {
700
- if (name === 'notification' && options?.channel === undefined) {
701
- throw new Error('Missing channel option for notification listener');
702
- }
703
-
704
- const client = await pool.connect();
705
- client.on(name, async (msg) => {
706
- try {
707
- await fn(msg);
708
- } catch (error) {
709
- console.error('Error handling message:', error);
710
- }
711
- });
712
-
713
- if (name === 'notification' && options?.channel !== undefined) {
714
- await client.query(`LISTEN "${options.channel}";`);
715
- }
716
- },
717
692
  transaction: createTransaction(async (stackTraceErr) => {
718
693
  const client = await pool.connect();
719
694
  const tx = new PostgresTx(client, false, stackTraceErr);
@@ -0,0 +1,64 @@
1
+ // These types were generated by @balena/abstract-sql-to-typescript v3.2.1
2
+
3
+ import type { Types } from '@balena/abstract-sql-to-typescript';
4
+
5
+ export interface Migration {
6
+ Read: {
7
+ created_at: Types['Date Time']['Read'];
8
+ modified_at: Types['Date Time']['Read'];
9
+ model_name: Types['Short Text']['Read'];
10
+ executed_migrations: Types['JSON']['Read'];
11
+ };
12
+ Write: {
13
+ created_at: Types['Date Time']['Write'];
14
+ modified_at: Types['Date Time']['Write'];
15
+ model_name: Types['Short Text']['Write'];
16
+ executed_migrations: Types['JSON']['Write'];
17
+ };
18
+ }
19
+
20
+ export interface MigrationLock {
21
+ Read: {
22
+ created_at: Types['Date Time']['Read'];
23
+ modified_at: Types['Date Time']['Read'];
24
+ model_name: Types['Short Text']['Read'];
25
+ };
26
+ Write: {
27
+ created_at: Types['Date Time']['Write'];
28
+ modified_at: Types['Date Time']['Write'];
29
+ model_name: Types['Short Text']['Write'];
30
+ };
31
+ }
32
+
33
+ export interface MigrationStatus {
34
+ Read: {
35
+ created_at: Types['Date Time']['Read'];
36
+ modified_at: Types['Date Time']['Read'];
37
+ migration_key: Types['Short Text']['Read'];
38
+ start_time: Types['Date Time']['Read'] | null;
39
+ last_run_time: Types['Date Time']['Read'] | null;
40
+ run_count: Types['Integer']['Read'];
41
+ migrated_row_count: Types['Integer']['Read'] | null;
42
+ error_count: Types['Integer']['Read'] | null;
43
+ is_backing_off: Types['Boolean']['Read'];
44
+ converged_time: Types['Date Time']['Read'] | null;
45
+ };
46
+ Write: {
47
+ created_at: Types['Date Time']['Write'];
48
+ modified_at: Types['Date Time']['Write'];
49
+ migration_key: Types['Short Text']['Write'];
50
+ start_time: Types['Date Time']['Write'] | null;
51
+ last_run_time: Types['Date Time']['Write'] | null;
52
+ run_count: Types['Integer']['Write'];
53
+ migrated_row_count: Types['Integer']['Write'] | null;
54
+ error_count: Types['Integer']['Write'] | null;
55
+ is_backing_off: Types['Boolean']['Write'];
56
+ converged_time: Types['Date Time']['Write'] | null;
57
+ };
58
+ }
59
+
60
+ export default interface $Model {
61
+ migration: Migration;
62
+ migration_lock: MigrationLock;
63
+ migration_status: MigrationStatus;
64
+ }
@@ -1,3 +1,4 @@
1
+ import type MigrationsModel from './migrations';
1
2
  import {
2
3
  type MigrationTuple,
3
4
  MigrationError,
@@ -16,7 +17,7 @@ import _ from 'lodash';
16
17
  import * as sbvrUtils from '../sbvr-api/sbvr-utils';
17
18
 
18
19
  // eslint-disable-next-line @typescript-eslint/no-var-requires
19
- const modelText = require('./migrations.sbvr');
20
+ const migrationsModel = require('./migrations.sbvr');
20
21
 
21
22
  type ApiRootModel = Model & { apiRoot: string };
22
23
 
@@ -136,45 +137,49 @@ const executeMigration = async (
136
137
  }
137
138
  };
138
139
 
139
- export const config: Config = {
140
- models: [
141
- {
142
- modelName: 'migrations',
143
- apiRoot: 'migrations',
144
- modelText,
145
- migrations: {
146
- '11.0.0-modified-at': `
147
- ALTER TABLE "migration"
148
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
149
- `,
150
- '11.0.1-modified-at': `
151
- ALTER TABLE "migration lock"
152
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
153
- `,
154
- '15.0.0-data-types': async (tx, { db }) => {
155
- switch (db.engine) {
156
- case 'mysql':
157
- await tx.executeSql(`\
158
- ALTER TABLE "migration"
159
- MODIFY "executed migrations" JSON NOT NULL;`);
160
- await tx.executeSql(`\
161
- ALTER TABLE "migration status"
162
- MODIFY "is backing off" BOOLEAN NOT NULL;`);
163
- break;
164
- case 'postgres':
165
- await tx.executeSql(`\
166
- ALTER TABLE "migration"
167
- ALTER COLUMN "executed migrations" SET DATA TYPE JSONB USING "executed migrations"::JSONB;`);
168
- await tx.executeSql(`\
169
- ALTER TABLE "migration status"
170
- ALTER COLUMN "is backing off" DROP DEFAULT,
171
- ALTER COLUMN "is backing off" SET DATA TYPE BOOLEAN USING "is backing off"::BOOLEAN,
172
- ALTER COLUMN "is backing off" SET DEFAULT FALSE;`);
173
- break;
174
- // No need to migrate for websql
175
- }
176
- },
177
- },
140
+ declare module '../sbvr-api/sbvr-utils' {
141
+ export interface API {
142
+ [migrationModelConfig.apiRoot]: PinejsClient<MigrationsModel>;
143
+ }
144
+ }
145
+ const migrationModelConfig = {
146
+ modelName: 'migrations',
147
+ apiRoot: 'migrations',
148
+ modelText: migrationsModel,
149
+ migrations: {
150
+ '11.0.0-modified-at': `
151
+ ALTER TABLE "migration"
152
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
153
+ `,
154
+ '11.0.1-modified-at': `
155
+ ALTER TABLE "migration lock"
156
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
157
+ `,
158
+ '15.0.0-data-types': async (tx, { db }) => {
159
+ switch (db.engine) {
160
+ case 'mysql':
161
+ await tx.executeSql(`\
162
+ ALTER TABLE "migration"
163
+ MODIFY "executed migrations" JSON NOT NULL;`);
164
+ await tx.executeSql(`\
165
+ ALTER TABLE "migration status"
166
+ MODIFY "is backing off" BOOLEAN NOT NULL;`);
167
+ break;
168
+ case 'postgres':
169
+ await tx.executeSql(`\
170
+ ALTER TABLE "migration"
171
+ ALTER COLUMN "executed migrations" SET DATA TYPE JSONB USING "executed migrations"::JSONB;`);
172
+ await tx.executeSql(`\
173
+ ALTER TABLE "migration status"
174
+ ALTER COLUMN "is backing off" DROP DEFAULT,
175
+ ALTER COLUMN "is backing off" SET DATA TYPE BOOLEAN USING "is backing off"::BOOLEAN,
176
+ ALTER COLUMN "is backing off" SET DEFAULT FALSE;`);
177
+ break;
178
+ // No need to migrate for websql
179
+ }
178
180
  },
179
- ],
181
+ },
182
+ } as const satisfies sbvrUtils.ExecutableModel;
183
+ export const config: Config = {
184
+ models: [migrationModelConfig],
180
185
  };
@@ -0,0 +1,26 @@
1
+ // These types were generated by @balena/abstract-sql-to-typescript v3.2.1
2
+
3
+ import type { Types } from '@balena/abstract-sql-to-typescript';
4
+
5
+ export interface Model {
6
+ Read: {
7
+ created_at: Types['Date Time']['Read'];
8
+ modified_at: Types['Date Time']['Read'];
9
+ id: Types['Serial']['Read'];
10
+ is_of__vocabulary: Types['Short Text']['Read'];
11
+ model_type: Types['Short Text']['Read'];
12
+ model_value: Types['JSON']['Read'];
13
+ };
14
+ Write: {
15
+ created_at: Types['Date Time']['Write'];
16
+ modified_at: Types['Date Time']['Write'];
17
+ id: Types['Serial']['Write'];
18
+ is_of__vocabulary: Types['Short Text']['Write'];
19
+ model_type: Types['Short Text']['Write'];
20
+ model_value: Types['JSON']['Write'];
21
+ };
22
+ }
23
+
24
+ export default interface $Model {
25
+ model: Model;
26
+ }
@@ -9,7 +9,6 @@ import _ from 'lodash';
9
9
  import { settleMapSeries } from './control-flow';
10
10
  import memoize from 'memoizee';
11
11
  import {
12
- type PinejsClient,
13
12
  type User,
14
13
  type ApiKey,
15
14
  resolveSynonym,
@@ -31,25 +30,27 @@ export interface HookReq {
31
30
  hooks?: InstantiatedHooks;
32
31
  is?: (type: string | string[]) => string | false | null;
33
32
  }
34
- export interface HookArgs {
33
+ export interface HookArgs<Vocab extends string = string> {
35
34
  req: HookReq;
36
35
  request: ODataRequest;
37
- api: PinejsClient;
36
+ api: (typeof api)[Vocab];
38
37
  tx?: Tx | undefined;
39
38
  }
40
39
  export type HookResponse = PromiseLike<any> | null | void;
41
40
 
42
- export interface Hooks {
43
- PREPARSE?: (options: Omit<HookArgs, 'request' | 'api'>) => HookResponse;
44
- POSTPARSE?: (options: HookArgs) => HookResponse;
45
- PRERUN?: (options: HookArgs & { tx: Tx }) => HookResponse;
41
+ export interface Hooks<Vocab extends string = string> {
42
+ PREPARSE?: (
43
+ options: Omit<HookArgs<Vocab>, 'request' | 'api'>,
44
+ ) => HookResponse;
45
+ POSTPARSE?: (options: HookArgs<Vocab>) => HookResponse;
46
+ PRERUN?: (options: HookArgs<Vocab> & { tx: Tx }) => HookResponse;
46
47
  /** These are run in reverse translation order from newest to oldest */
47
48
  POSTRUN?: (
48
- options: HookArgs & { tx: Tx; result: Result | number | undefined },
49
+ options: HookArgs<Vocab> & { tx: Tx; result: Result | number | undefined },
49
50
  ) => HookResponse;
50
51
  /** These are run in reverse translation order from newest to oldest */
51
52
  PRERESPOND?: (
52
- options: HookArgs & {
53
+ options: HookArgs<Vocab> & {
53
54
  tx: Tx;
54
55
  result?: Result | number | AnyObject;
55
56
  /** This can be mutated to modify the response sent to the client */
@@ -58,7 +59,7 @@ export interface Hooks {
58
59
  ) => HookResponse;
59
60
  /** These are run in reverse translation order from newest to oldest */
60
61
  'POSTRUN-ERROR'?: (
61
- options: HookArgs & { tx: Tx; error: TypedError | any },
62
+ options: HookArgs<Vocab> & { tx: Tx; error: TypedError | any },
62
63
  ) => HookResponse;
63
64
  }
64
65
  export type HookBlueprints = {
@@ -264,9 +265,9 @@ const apiHooks = {
264
265
  // Share hooks between merge and patch since they are the same operation,
265
266
  // just MERGE was the OData intermediary until the HTTP spec added PATCH.
266
267
  apiHooks.MERGE = apiHooks.PATCH;
267
- export const addHook = (
268
+ export const addHook = <Vocab extends string>(
268
269
  method: keyof typeof apiHooks,
269
- vocabulary: string,
270
+ vocabulary: Vocab,
270
271
  resourceName: string,
271
272
  hooks:
272
273
  | { [key in keyof Hooks]: HookBlueprint<NonNullable<Hooks[key]>> }
@@ -345,11 +346,11 @@ export const addHook = (
345
346
  getHooks.clear();
346
347
  };
347
348
 
348
- export const addSideEffectHook = (
349
+ export const addSideEffectHook = <Vocab extends string>(
349
350
  method: HookMethod,
350
- apiRoot: string,
351
+ apiRoot: Vocab,
351
352
  resourceName: string,
352
- hooks: Hooks,
353
+ hooks: Hooks<NoInfer<Vocab>>,
353
354
  ): void => {
354
355
  addHook(method, apiRoot, resourceName, {
355
356
  ...hooks,
@@ -358,11 +359,11 @@ export const addSideEffectHook = (
358
359
  });
359
360
  };
360
361
 
361
- export const addPureHook = (
362
+ export const addPureHook = <Vocab extends string>(
362
363
  method: HookMethod,
363
- apiRoot: string,
364
+ apiRoot: Vocab,
364
365
  resourceName: string,
365
- hooks: Hooks,
366
+ hooks: Hooks<NoInfer<Vocab>>,
366
367
  ): void => {
367
368
  addHook(method, apiRoot, resourceName, {
368
369
  ...hooks,
@@ -1,3 +1,4 @@
1
+ import type AuthModel from './user';
1
2
  import type {
2
3
  AbstractSqlModel,
3
4
  AbstractSqlQuery,
@@ -51,6 +52,7 @@ import {
51
52
  type ODataRequest,
52
53
  } from './uri-parser';
53
54
  import memoizeWeak = require('memoizee/weak');
55
+ import type { Config } from '../config-loader/config-loader';
54
56
 
55
57
  // eslint-disable-next-line @typescript-eslint/no-var-requires
56
58
  const userModel: string = require('./user.sbvr');
@@ -1118,7 +1120,7 @@ const memoizedGetConstrainedModel = (
1118
1120
  getBoundConstrainedMemoizer(abstractSqlModel)(permissionsLookup, vocabulary);
1119
1121
 
1120
1122
  const getCheckPasswordQuery = _.once(() =>
1121
- sbvrUtils.api.Auth.prepare<{ username: string }>({
1123
+ sbvrUtils.api.Auth.prepare<{ username: string }, 'user'>({
1122
1124
  resource: 'user',
1123
1125
  passthrough: {
1124
1126
  req: rootRead,
@@ -1164,7 +1166,7 @@ export const checkPassword = async (
1164
1166
 
1165
1167
  const $getUserPermissions = (() => {
1166
1168
  const getUserPermissionsQuery = _.once(() =>
1167
- sbvrUtils.api.Auth.prepare<{ userId: number }>({
1169
+ sbvrUtils.api.Auth.prepare<{ userId: number }, 'permission'>({
1168
1170
  resource: 'permission',
1169
1171
  passthrough: {
1170
1172
  req: rootRead,
@@ -1275,7 +1277,7 @@ export const getUserPermissions = async (
1275
1277
 
1276
1278
  const $getApiKeyPermissions = (() => {
1277
1279
  const getApiKeyPermissionsQuery = _.once(() =>
1278
- sbvrUtils.api.Auth.prepare<{ apiKey: string }>({
1280
+ sbvrUtils.api.Auth.prepare<{ apiKey: string }, 'permission'>({
1279
1281
  resource: 'permission',
1280
1282
  passthrough: {
1281
1283
  req: rootRead,
@@ -1403,7 +1405,7 @@ export const getApiKeyPermissions = async (
1403
1405
 
1404
1406
  const getApiKeyActorId = (() => {
1405
1407
  const getApiKeyActorIdQuery = _.once(() =>
1406
- sbvrUtils.api.Auth.prepare<{ apiKey: string }>({
1408
+ sbvrUtils.api.Auth.prepare<{ apiKey: string }, 'api_key'>({
1407
1409
  resource: 'api_key',
1408
1410
  passthrough: {
1409
1411
  req: rootRead,
@@ -1586,7 +1588,7 @@ let guestPermissionsInitialized = false;
1586
1588
  const getGuestPermissions = memoize(
1587
1589
  async () => {
1588
1590
  // Get guest user
1589
- const result = (await sbvrUtils.api.Auth.get({
1591
+ const result = await sbvrUtils.api.Auth.get({
1590
1592
  resource: 'user',
1591
1593
  passthrough: {
1592
1594
  req: rootRead,
@@ -1597,7 +1599,7 @@ const getGuestPermissions = memoize(
1597
1599
  options: {
1598
1600
  $select: 'id',
1599
1601
  },
1600
- })) as { id: number } | undefined;
1602
+ });
1601
1603
  if (result == null) {
1602
1604
  throw new Error('No guest user');
1603
1605
  }
@@ -1686,49 +1688,53 @@ export const addPermissions = async (
1686
1688
  }
1687
1689
  };
1688
1690
 
1691
+ declare module './sbvr-utils' {
1692
+ export interface API {
1693
+ [authModelConfig.apiRoot]: PinejsClient<AuthModel>;
1694
+ }
1695
+ }
1696
+ const authModelConfig = {
1697
+ apiRoot: 'Auth',
1698
+ modelText: userModel,
1699
+ customServerCode: exports,
1700
+ migrations: {
1701
+ '11.0.0-modified-at': `
1702
+ ALTER TABLE "actor"
1703
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1704
+
1705
+ ALTER TABLE "api key"
1706
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1707
+ ALTER TABLE "api key-has-permission"
1708
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1709
+ ALTER TABLE "api key-has-role"
1710
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1711
+
1712
+ ALTER TABLE "permission"
1713
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1714
+
1715
+ ALTER TABLE "role"
1716
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1717
+
1718
+ ALTER TABLE "user"
1719
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1720
+ ALTER TABLE "user-has-role"
1721
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1722
+ ALTER TABLE "user-has-permission"
1723
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1724
+ `,
1725
+ '11.0.1-modified-at': `
1726
+ ALTER TABLE "role-has-permission"
1727
+ ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1728
+ `,
1729
+ '14.42.0-api-key-expiry-date': `
1730
+ ALTER TABLE "api key"
1731
+ ADD COLUMN IF NOT EXISTS "expiry date" TIMESTAMP NULL;
1732
+ `,
1733
+ },
1734
+ } as const satisfies sbvrUtils.ExecutableModel;
1689
1735
  export const config = {
1690
- models: [
1691
- {
1692
- apiRoot: 'Auth',
1693
- modelText: userModel,
1694
- customServerCode: exports,
1695
- migrations: {
1696
- '11.0.0-modified-at': `
1697
- ALTER TABLE "actor"
1698
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1699
-
1700
- ALTER TABLE "api key"
1701
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1702
- ALTER TABLE "api key-has-permission"
1703
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1704
- ALTER TABLE "api key-has-role"
1705
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1706
-
1707
- ALTER TABLE "permission"
1708
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1709
-
1710
- ALTER TABLE "role"
1711
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1712
-
1713
- ALTER TABLE "user"
1714
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1715
- ALTER TABLE "user-has-role"
1716
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1717
- ALTER TABLE "user-has-permission"
1718
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1719
- `,
1720
- '11.0.1-modified-at': `
1721
- ALTER TABLE "role-has-permission"
1722
- ADD COLUMN IF NOT EXISTS "modified at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP NOT NULL;
1723
- `,
1724
- '14.42.0-api-key-expiry-date': `
1725
- ALTER TABLE "api key"
1726
- ADD COLUMN IF NOT EXISTS "expiry date" TIMESTAMP NULL;
1727
- `,
1728
- },
1729
- },
1730
- ] as sbvrUtils.ExecutableModel[],
1731
- };
1736
+ models: [authModelConfig],
1737
+ } satisfies Config;
1732
1738
  export const setup = () => {
1733
1739
  addHook('all', 'all', 'all', {
1734
1740
  sideEffects: false,