@balena/pinejs 17.1.0-build-joshbwlng-tasks-149b21c81ddf7cbb2a934500dc16e0b5ed4c74a7-1 → 17.1.0-build-model-based-typings-a10277597a28577bcb204b378925c9df795a10e8-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.
- package/.pinejs-cache.json +1 -1
- package/.versionbot/CHANGELOG.yml +232 -7
- package/CHANGELOG.md +71 -3
- package/out/config-loader/env.d.ts +0 -4
- package/out/config-loader/env.js +1 -5
- package/out/config-loader/env.js.map +1 -1
- package/out/data-server/sbvr-server.js +3 -2
- package/out/data-server/sbvr-server.js.map +1 -1
- package/out/database-layer/db.d.ts +0 -3
- package/out/database-layer/db.js +0 -17
- package/out/database-layer/db.js.map +1 -1
- package/out/http-transactions/transactions.js +1 -6
- package/out/http-transactions/transactions.js.map +1 -1
- package/out/migrator/migrations.d.ts +113 -0
- package/out/migrator/migrations.js +3 -0
- package/out/migrator/migrations.js.map +1 -0
- package/out/migrator/sync.d.ts +17 -0
- package/out/migrator/sync.js +39 -40
- package/out/migrator/sync.js.map +1 -1
- package/out/sbvr-api/abstract-sql.js +1 -1
- package/out/sbvr-api/abstract-sql.js.map +1 -1
- package/out/sbvr-api/dev.d.ts +41 -0
- package/out/sbvr-api/dev.js +3 -0
- package/out/sbvr-api/dev.js.map +1 -0
- package/out/sbvr-api/hooks.d.ts +26 -26
- package/out/sbvr-api/hooks.js.map +1 -1
- package/out/sbvr-api/odata-response.js +3 -3
- package/out/sbvr-api/odata-response.js.map +1 -1
- package/out/sbvr-api/permissions.d.ts +26 -2
- package/out/sbvr-api/permissions.js +41 -42
- package/out/sbvr-api/permissions.js.map +1 -1
- package/out/sbvr-api/sbvr-utils.d.ts +46 -6
- package/out/sbvr-api/sbvr-utils.js +44 -44
- package/out/sbvr-api/sbvr-utils.js.map +1 -1
- package/out/sbvr-api/uri-parser.js +1 -1
- package/out/sbvr-api/uri-parser.js.map +1 -1
- package/out/sbvr-api/user.d.ts +467 -0
- package/out/sbvr-api/user.js +3 -0
- package/out/sbvr-api/user.js.map +1 -0
- package/out/server-glue/module.d.ts +0 -1
- package/out/server-glue/module.js +1 -4
- package/out/server-glue/module.js.map +1 -1
- package/package.json +18 -19
- package/src/config-loader/env.ts +1 -6
- package/src/data-server/sbvr-server.js +3 -2
- package/src/database-layer/db.ts +0 -25
- package/src/http-transactions/transactions.js +1 -6
- package/src/migrator/migrations.ts +120 -0
- package/src/migrator/sync.ts +46 -41
- package/src/sbvr-api/abstract-sql.ts +1 -1
- package/src/sbvr-api/dev.ts +44 -0
- package/src/sbvr-api/hooks.ts +21 -18
- package/src/sbvr-api/odata-response.ts +3 -4
- package/src/sbvr-api/permissions.ts +52 -46
- package/src/sbvr-api/sbvr-utils.ts +90 -53
- package/src/sbvr-api/uri-parser.ts +1 -1
- package/src/sbvr-api/user.ts +421 -0
- package/src/server-glue/module.ts +0 -3
- package/out/tasks/common.d.ts +0 -4
- package/out/tasks/common.js +0 -13
- package/out/tasks/common.js.map +0 -1
- package/out/tasks/index.d.ts +0 -8
- package/out/tasks/index.js +0 -142
- package/out/tasks/index.js.map +0 -1
- package/out/tasks/tasks.sbvr +0 -60
- package/out/tasks/types.d.ts +0 -38
- package/out/tasks/types.js +0 -10
- package/out/tasks/types.js.map +0 -1
- package/out/tasks/worker.d.ts +0 -16
- package/out/tasks/worker.js +0 -228
- package/out/tasks/worker.js.map +0 -1
- package/src/tasks/common.ts +0 -14
- package/src/tasks/index.ts +0 -158
- package/src/tasks/tasks.sbvr +0 -60
- package/src/tasks/types.ts +0 -58
- package/src/tasks/worker.ts +0 -281
package/src/database-layer/db.ts
CHANGED
@@ -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);
|
@@ -130,12 +130,7 @@ WHERE "conditional field"."conditional resource" = ?;`,
|
|
130
130
|
modelField.dataType === 'ForeignKey' &&
|
131
131
|
Number.isNaN(Number(fieldValue))
|
132
132
|
) {
|
133
|
-
if (
|
134
|
-
!Object.prototype.hasOwnProperty.call(
|
135
|
-
placeholders,
|
136
|
-
fieldValue,
|
137
|
-
)
|
138
|
-
) {
|
133
|
+
if (!Object.hasOwn(placeholders, fieldValue)) {
|
139
134
|
throw new Error('Cannot resolve placeholder' + fieldValue);
|
140
135
|
} else {
|
141
136
|
try {
|
@@ -0,0 +1,120 @@
|
|
1
|
+
import type { Types } from '@balena/abstract-sql-to-typescript';
|
2
|
+
|
3
|
+
export interface Migration {
|
4
|
+
Read: {
|
5
|
+
created_at: Types['Date Time']['Read'];
|
6
|
+
modified_at: Types['Date Time']['Read'];
|
7
|
+
model_name: Types['Short Text']['Read'];
|
8
|
+
executed_migrations: Types['JSON']['Read'];
|
9
|
+
};
|
10
|
+
Write: {
|
11
|
+
created_at: Types['Date Time']['Write'];
|
12
|
+
modified_at: Types['Date Time']['Write'];
|
13
|
+
model_name: Types['Short Text']['Write'];
|
14
|
+
executed_migrations: Types['JSON']['Write'];
|
15
|
+
};
|
16
|
+
}
|
17
|
+
|
18
|
+
export interface MigrationLock {
|
19
|
+
Read: {
|
20
|
+
created_at: Types['Date Time']['Read'];
|
21
|
+
modified_at: Types['Date Time']['Read'];
|
22
|
+
model_name: Types['Short Text']['Read'];
|
23
|
+
};
|
24
|
+
Write: {
|
25
|
+
created_at: Types['Date Time']['Write'];
|
26
|
+
modified_at: Types['Date Time']['Write'];
|
27
|
+
model_name: Types['Short Text']['Write'];
|
28
|
+
};
|
29
|
+
}
|
30
|
+
|
31
|
+
export interface MigrationStatus {
|
32
|
+
Read: {
|
33
|
+
created_at: Types['Date Time']['Read'];
|
34
|
+
modified_at: Types['Date Time']['Read'];
|
35
|
+
migration_key: Types['Short Text']['Read'];
|
36
|
+
start_time: Types['Date Time']['Read'] | null;
|
37
|
+
last_run_time: Types['Date Time']['Read'] | null;
|
38
|
+
run_count: Types['Integer']['Read'];
|
39
|
+
migrated_row_count: Types['Integer']['Read'] | null;
|
40
|
+
error_count: Types['Integer']['Read'] | null;
|
41
|
+
is_backing_off: Types['Boolean']['Read'];
|
42
|
+
converged_time: Types['Date Time']['Read'] | null;
|
43
|
+
};
|
44
|
+
Write: {
|
45
|
+
created_at: Types['Date Time']['Write'];
|
46
|
+
modified_at: Types['Date Time']['Write'];
|
47
|
+
migration_key: Types['Short Text']['Write'];
|
48
|
+
start_time: Types['Date Time']['Write'] | null;
|
49
|
+
last_run_time: Types['Date Time']['Write'] | null;
|
50
|
+
run_count: Types['Integer']['Write'];
|
51
|
+
migrated_row_count: Types['Integer']['Write'] | null;
|
52
|
+
error_count: Types['Integer']['Write'] | null;
|
53
|
+
is_backing_off: Types['Boolean']['Write'];
|
54
|
+
converged_time: Types['Date Time']['Write'] | null;
|
55
|
+
};
|
56
|
+
}
|
57
|
+
|
58
|
+
export interface Migration {
|
59
|
+
Read: {
|
60
|
+
created_at: Types['Date Time']['Read'];
|
61
|
+
modified_at: Types['Date Time']['Read'];
|
62
|
+
model_name: Types['Short Text']['Read'];
|
63
|
+
executed_migrations: Types['JSON']['Read'];
|
64
|
+
};
|
65
|
+
Write: {
|
66
|
+
created_at: Types['Date Time']['Write'];
|
67
|
+
modified_at: Types['Date Time']['Write'];
|
68
|
+
model_name: Types['Short Text']['Write'];
|
69
|
+
executed_migrations: Types['JSON']['Write'];
|
70
|
+
};
|
71
|
+
}
|
72
|
+
|
73
|
+
export interface MigrationLock {
|
74
|
+
Read: {
|
75
|
+
created_at: Types['Date Time']['Read'];
|
76
|
+
modified_at: Types['Date Time']['Read'];
|
77
|
+
model_name: Types['Short Text']['Read'];
|
78
|
+
};
|
79
|
+
Write: {
|
80
|
+
created_at: Types['Date Time']['Write'];
|
81
|
+
modified_at: Types['Date Time']['Write'];
|
82
|
+
model_name: Types['Short Text']['Write'];
|
83
|
+
};
|
84
|
+
}
|
85
|
+
|
86
|
+
export interface MigrationStatus {
|
87
|
+
Read: {
|
88
|
+
created_at: Types['Date Time']['Read'];
|
89
|
+
modified_at: Types['Date Time']['Read'];
|
90
|
+
migration_key: Types['Short Text']['Read'];
|
91
|
+
start_time: Types['Date Time']['Read'] | null;
|
92
|
+
last_run_time: Types['Date Time']['Read'] | null;
|
93
|
+
run_count: Types['Integer']['Read'];
|
94
|
+
migrated_row_count: Types['Integer']['Read'] | null;
|
95
|
+
error_count: Types['Integer']['Read'] | null;
|
96
|
+
is_backing_off: Types['Boolean']['Read'];
|
97
|
+
converged_time: Types['Date Time']['Read'] | null;
|
98
|
+
};
|
99
|
+
Write: {
|
100
|
+
created_at: Types['Date Time']['Write'];
|
101
|
+
modified_at: Types['Date Time']['Write'];
|
102
|
+
migration_key: Types['Short Text']['Write'];
|
103
|
+
start_time: Types['Date Time']['Write'] | null;
|
104
|
+
last_run_time: Types['Date Time']['Write'] | null;
|
105
|
+
run_count: Types['Integer']['Write'];
|
106
|
+
migrated_row_count: Types['Integer']['Write'] | null;
|
107
|
+
error_count: Types['Integer']['Write'] | null;
|
108
|
+
is_backing_off: Types['Boolean']['Write'];
|
109
|
+
converged_time: Types['Date Time']['Write'] | null;
|
110
|
+
};
|
111
|
+
}
|
112
|
+
|
113
|
+
export default interface $Model {
|
114
|
+
migration: Migration;
|
115
|
+
migration_lock: MigrationLock;
|
116
|
+
migration_status: MigrationStatus;
|
117
|
+
migration$sbvr__compiler: Migration;
|
118
|
+
migration_lock$sbvr__compiler: MigrationLock;
|
119
|
+
migration_status$sbvr__compiler: MigrationStatus;
|
120
|
+
}
|
package/src/migrator/sync.ts
CHANGED
@@ -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
|
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
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
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
|
};
|
@@ -116,7 +116,7 @@ export const getAndCheckBindValues = async (
|
|
116
116
|
[dataType, value] = odataBinds[bindValue];
|
117
117
|
field = { dataType };
|
118
118
|
} else if (typeof bindValue === 'string') {
|
119
|
-
if (!Object.
|
119
|
+
if (!Object.hasOwn(odataBinds, bindValue)) {
|
120
120
|
console.error(
|
121
121
|
`Invalid binding '${bindValue}' for binds: `,
|
122
122
|
odataBinds,
|
@@ -0,0 +1,44 @@
|
|
1
|
+
import type { Types } from '@balena/abstract-sql-to-typescript';
|
2
|
+
|
3
|
+
export interface Model {
|
4
|
+
Read: {
|
5
|
+
created_at: Types['Date Time']['Read'];
|
6
|
+
modified_at: Types['Date Time']['Read'];
|
7
|
+
id: Types['Serial']['Read'];
|
8
|
+
is_of__vocabulary: Types['Short Text']['Read'];
|
9
|
+
model_type: Types['Short Text']['Read'];
|
10
|
+
model_value: Types['JSON']['Read'];
|
11
|
+
};
|
12
|
+
Write: {
|
13
|
+
created_at: Types['Date Time']['Write'];
|
14
|
+
modified_at: Types['Date Time']['Write'];
|
15
|
+
id: Types['Serial']['Write'];
|
16
|
+
is_of__vocabulary: Types['Short Text']['Write'];
|
17
|
+
model_type: Types['Short Text']['Write'];
|
18
|
+
model_value: Types['JSON']['Write'];
|
19
|
+
};
|
20
|
+
}
|
21
|
+
|
22
|
+
export interface Model {
|
23
|
+
Read: {
|
24
|
+
created_at: Types['Date Time']['Read'];
|
25
|
+
modified_at: Types['Date Time']['Read'];
|
26
|
+
id: Types['Serial']['Read'];
|
27
|
+
is_of__vocabulary: Types['Short Text']['Read'];
|
28
|
+
model_type: Types['Short Text']['Read'];
|
29
|
+
model_value: Types['JSON']['Read'];
|
30
|
+
};
|
31
|
+
Write: {
|
32
|
+
created_at: Types['Date Time']['Write'];
|
33
|
+
modified_at: Types['Date Time']['Write'];
|
34
|
+
id: Types['Serial']['Write'];
|
35
|
+
is_of__vocabulary: Types['Short Text']['Write'];
|
36
|
+
model_type: Types['Short Text']['Write'];
|
37
|
+
model_value: Types['JSON']['Write'];
|
38
|
+
};
|
39
|
+
}
|
40
|
+
|
41
|
+
export default interface $Model {
|
42
|
+
model: Model;
|
43
|
+
model$sbvr__compiler: Model;
|
44
|
+
}
|
package/src/sbvr-api/hooks.ts
CHANGED
@@ -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,23 +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:
|
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?: (
|
44
|
-
|
45
|
-
|
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
|
-
POSTRUN?: (
|
48
|
+
POSTRUN?: (
|
49
|
+
options: HookArgs<Vocab> & { tx: Tx; result: any },
|
50
|
+
) => HookResponse;
|
48
51
|
/** These are run in reverse translation order from newest to oldest */
|
49
52
|
PRERESPOND?: (
|
50
|
-
options: HookArgs & {
|
53
|
+
options: HookArgs<Vocab> & {
|
51
54
|
tx: Tx;
|
52
55
|
result: any;
|
53
56
|
/** This can be mutated to modify the response sent to the client */
|
@@ -56,7 +59,7 @@ export interface Hooks {
|
|
56
59
|
) => HookResponse;
|
57
60
|
/** These are run in reverse translation order from newest to oldest */
|
58
61
|
'POSTRUN-ERROR'?: (
|
59
|
-
options: HookArgs & { tx: Tx; error: TypedError | any },
|
62
|
+
options: HookArgs<Vocab> & { tx: Tx; error: TypedError | any },
|
60
63
|
) => HookResponse;
|
61
64
|
}
|
62
65
|
export type HookBlueprints = {
|
@@ -262,9 +265,9 @@ const apiHooks = {
|
|
262
265
|
// Share hooks between merge and patch since they are the same operation,
|
263
266
|
// just MERGE was the OData intermediary until the HTTP spec added PATCH.
|
264
267
|
apiHooks.MERGE = apiHooks.PATCH;
|
265
|
-
export const addHook = (
|
268
|
+
export const addHook = <Vocab extends string>(
|
266
269
|
method: keyof typeof apiHooks,
|
267
|
-
vocabulary:
|
270
|
+
vocabulary: Vocab,
|
268
271
|
resourceName: string,
|
269
272
|
hooks:
|
270
273
|
| { [key in keyof Hooks]: HookBlueprint<NonNullable<Hooks[key]>> }
|
@@ -343,11 +346,11 @@ export const addHook = (
|
|
343
346
|
getHooks.clear();
|
344
347
|
};
|
345
348
|
|
346
|
-
export const addSideEffectHook = (
|
349
|
+
export const addSideEffectHook = <Vocab extends string>(
|
347
350
|
method: HookMethod,
|
348
|
-
apiRoot:
|
351
|
+
apiRoot: Vocab,
|
349
352
|
resourceName: string,
|
350
|
-
hooks: Hooks
|
353
|
+
hooks: Hooks<NoInfer<Vocab>>,
|
351
354
|
): void => {
|
352
355
|
addHook(method, apiRoot, resourceName, {
|
353
356
|
...hooks,
|
@@ -356,11 +359,11 @@ export const addSideEffectHook = (
|
|
356
359
|
});
|
357
360
|
};
|
358
361
|
|
359
|
-
export const addPureHook = (
|
362
|
+
export const addPureHook = <Vocab extends string>(
|
360
363
|
method: HookMethod,
|
361
|
-
apiRoot:
|
364
|
+
apiRoot: Vocab,
|
362
365
|
resourceName: string,
|
363
|
-
hooks: Hooks
|
366
|
+
hooks: Hooks<NoInfer<Vocab>>,
|
364
367
|
): void => {
|
365
368
|
addHook(method, apiRoot, resourceName, {
|
366
369
|
...hooks,
|
@@ -165,20 +165,19 @@ export const process = async (
|
|
165
165
|
|
166
166
|
const fetchProcessingFields = getFetchProcessingFields(table);
|
167
167
|
const processedFields = fieldNames.filter((fieldName) =>
|
168
|
-
Object.
|
168
|
+
Object.hasOwn(fetchProcessingFields, fieldName),
|
169
169
|
);
|
170
170
|
|
171
171
|
const localFields = getLocalFields(table);
|
172
172
|
// We check that it's not a local field, rather than that it is a foreign key because of the case where the foreign key is on the other resource
|
173
173
|
// and hence not known to this resource
|
174
174
|
const expandableFields = fieldNames.filter(
|
175
|
-
(fieldName) =>
|
176
|
-
!Object.prototype.hasOwnProperty.call(localFields, fieldName),
|
175
|
+
(fieldName) => !Object.hasOwn(localFields, fieldName),
|
177
176
|
);
|
178
177
|
|
179
178
|
const webresourceFields = getWebResourceFields(table);
|
180
179
|
const requiredSigningFields = fieldNames.filter((fieldName) =>
|
181
|
-
Object.
|
180
|
+
Object.hasOwn(webresourceFields, fieldName),
|
182
181
|
);
|
183
182
|
|
184
183
|
const odataIdField = sqlNameToODataName(table.idField);
|
@@ -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');
|
@@ -429,7 +431,7 @@ const convertToLambda = (filter: AnyObject, identifier: string) => {
|
|
429
431
|
}
|
430
432
|
}
|
431
433
|
|
432
|
-
if (Object.
|
434
|
+
if (Object.hasOwn(object, 'name')) {
|
433
435
|
object.property = { ...object };
|
434
436
|
object.name = identifier;
|
435
437
|
delete object.lambda;
|
@@ -725,7 +727,7 @@ const deepFreezeExceptDefinition = (obj: AnyObject) => {
|
|
725
727
|
// We skip the definition because we know it's a property we've defined that will throw an error in some cases
|
726
728
|
if (
|
727
729
|
prop !== 'definition' &&
|
728
|
-
Object.
|
730
|
+
Object.hasOwn(obj, prop) &&
|
729
731
|
obj[prop] !== null &&
|
730
732
|
!['object', 'function'].includes(typeof obj[prop])
|
731
733
|
) {
|
@@ -1586,7 +1588,7 @@ let guestPermissionsInitialized = false;
|
|
1586
1588
|
const getGuestPermissions = memoize(
|
1587
1589
|
async () => {
|
1588
1590
|
// Get guest user
|
1589
|
-
const result =
|
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
|
-
})
|
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,
|