firstly 0.0.8 → 0.0.10
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/CHANGELOG.md +17 -0
- package/esm/BaseEnum.d.ts +3 -14
- package/esm/BaseEnum.js +0 -4
- package/esm/FF_Entity.d.ts +1 -1
- package/esm/FF_Entity.js +7 -3
- package/esm/ROUTES.d.ts +2 -2
- package/esm/api/index.d.ts +2 -3
- package/esm/api/index.js +4 -4
- package/esm/auth/RoleHelpers.d.ts +1 -1
- package/esm/auth/RoleHelpers.js +5 -3
- package/esm/auth/client/Auth.js +2 -2
- package/esm/auth/client/Entities.d.ts +2 -2
- package/esm/auth/client/Entities.js +5 -5
- package/esm/auth/client/index.d.ts +1 -1
- package/esm/auth/client/index.js +1 -1
- package/esm/auth/index.d.ts +2 -0
- package/esm/auth/index.js +23 -12
- package/esm/cellsBuildor.d.ts +4 -4
- package/esm/cellsBuildor.js +19 -6
- package/esm/feedback/FeedbackController.d.ts +1 -1
- package/esm/feedback/FeedbackController.js +0 -2
- package/esm/feedback/ui/DialogIssue.svelte +8 -8
- package/esm/handle/index.d.ts +0 -1
- package/esm/helper.d.ts +16 -14
- package/esm/helper.js +58 -2
- package/esm/index.d.ts +7 -3
- package/esm/index.js +1 -1
- package/esm/mail/index.js +15 -10
- package/esm/mail/templates/DefaultMail.svelte.d.ts +3 -3
- package/esm/storeItem.d.ts +1 -2
- package/esm/storeList.d.ts +4 -3
- package/esm/storeList.js +20 -10
- package/esm/ui/Clipboardable.svelte.d.ts +1 -1
- package/esm/ui/Field.svelte +9 -3
- package/esm/ui/Field.svelte.d.ts +3 -2
- package/esm/ui/FieldGroup.svelte +4 -2
- package/esm/ui/FieldGroup.svelte.d.ts +1 -1
- package/esm/ui/Grid.svelte +90 -20
- package/esm/ui/Grid.svelte.d.ts +6 -5
- package/esm/ui/GridLoading.svelte.d.ts +1 -1
- package/esm/ui/GridPaginate.svelte +6 -4
- package/esm/ui/GridPaginate.svelte.d.ts +2 -2
- package/esm/ui/Icon.svelte.d.ts +3 -3
- package/esm/ui/Loading.svelte.d.ts +1 -1
- package/esm/ui/Tooltip.svelte.d.ts +2 -2
- package/esm/ui/dialog/DialogPrimitive.svelte +1 -5
- package/esm/ui/dialog/DialogPrimitive.svelte.d.ts +3 -3
- package/esm/ui/dialog/dialog.d.ts +10 -8
- package/esm/ui/dialog/dialog.js +9 -10
- package/esm/ui/internals/FieldContainer.svelte.d.ts +6 -6
- package/esm/ui/internals/Input.svelte +10 -1
- package/esm/ui/internals/Input.svelte.d.ts +1 -1
- package/esm/ui/internals/Textarea.svelte.d.ts +2 -2
- package/esm/ui/internals/select/MultiSelectMelt.svelte.d.ts +4 -4
- package/esm/ui/internals/select/SelectMelt.svelte.d.ts +7 -7
- package/esm/ui/internals/select/SelectRadio.svelte.d.ts +3 -3
- package/esm/ui/link/Link.svelte +1 -1
- package/esm/ui/link/Link.svelte.d.ts +2 -2
- package/esm/ui/link/LinkPlus.svelte +41 -29
- package/esm/ui/link/LinkPlus.svelte.d.ts +2 -2
- package/esm/utils/transition.d.ts +0 -1
- package/esm/vite/index.js +2 -0
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# firstly
|
|
2
2
|
|
|
3
|
+
## 0.0.10
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#51](https://github.com/jycouet/firstly/pull/51)
|
|
8
|
+
[`803023a`](https://github.com/jycouet/firstly/commit/803023a6257c0bfb9396bc0a7bd454bd1281e26c)
|
|
9
|
+
Thanks [@jycouet](https://github.com/jycouet)! - prepare 0.0.10
|
|
10
|
+
|
|
11
|
+
## 0.0.9
|
|
12
|
+
|
|
13
|
+
### Patch Changes
|
|
14
|
+
|
|
15
|
+
- [#43](https://github.com/jycouet/firstly/pull/43)
|
|
16
|
+
[`46cfc39`](https://github.com/jycouet/firstly/commit/46cfc39090fc448a22c5ca95e45507a31ab8e2e0)
|
|
17
|
+
Thanks [@jycouet](https://github.com/jycouet)! - better enum filter, grid action left/right, bump
|
|
18
|
+
deps, opti session check, action after createOptionWhenNoResult
|
|
19
|
+
|
|
3
20
|
## 0.0.8
|
|
4
21
|
|
|
5
22
|
### Patch Changes
|
package/esm/BaseEnum.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { type IdFilter } from 'remult';
|
|
2
1
|
import type { FindOptionsBase, Repository } from 'remult';
|
|
3
2
|
export type FF_Icon = {
|
|
4
3
|
data?: string | string[];
|
|
@@ -15,30 +14,20 @@ export type BaseItem = BaseEnumOptions & {
|
|
|
15
14
|
sub?: {
|
|
16
15
|
captionPre?: string;
|
|
17
16
|
repo?: Repository<any>;
|
|
18
|
-
|
|
17
|
+
items?: any[];
|
|
19
18
|
};
|
|
20
19
|
};
|
|
21
20
|
export type BaseEnumOptions<Entity = any> = {
|
|
22
21
|
caption?: string;
|
|
23
22
|
icon?: FF_Icon;
|
|
24
|
-
where?:
|
|
23
|
+
where?: FindOptionsBase<Entity>['where'];
|
|
25
24
|
class?: string;
|
|
26
25
|
};
|
|
27
26
|
export declare class BaseEnum<Entity = any> {
|
|
28
27
|
id: string;
|
|
29
28
|
caption?: string;
|
|
30
29
|
icon?: FF_Icon;
|
|
31
|
-
where?:
|
|
30
|
+
where?: FindOptionsBase<Entity>['where'];
|
|
32
31
|
class?: string;
|
|
33
32
|
constructor(_id: string | number, options?: BaseEnumOptions<Entity>);
|
|
34
|
-
getWhere: () => this | Entity[] | {
|
|
35
|
-
$ne?: Entity | Entity[] | undefined;
|
|
36
|
-
'!='?: Entity | Entity[] | undefined;
|
|
37
|
-
$in?: Entity[] | undefined;
|
|
38
|
-
$nin?: Entity[] | undefined;
|
|
39
|
-
} | {
|
|
40
|
-
$id: import("remult").ValueFilter<Entity extends {
|
|
41
|
-
id?: number | undefined;
|
|
42
|
-
} ? number : string>;
|
|
43
|
-
} | import("remult").EntityFilter<Entity> | NonNullable<Entity>;
|
|
44
33
|
}
|
package/esm/BaseEnum.js
CHANGED
package/esm/FF_Entity.d.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { type EntityOptions } from 'remult';
|
|
2
|
-
export declare function FF_Entity<entityType>(key: string, options: EntityOptions<entityType extends new (...args: any) => any ? InstanceType<entityType> : entityType>): (target: any, info?: import("remult/src/remult3/remult3").ClassDecoratorContextStub<entityType extends infer T ? T extends entityType ? T extends new (...args: any) => any ?
|
|
2
|
+
export declare function FF_Entity<entityType>(key: string, options: EntityOptions<entityType extends new (...args: any) => any ? InstanceType<entityType> : entityType>): (target: any, info?: import("remult/src/remult3/remult3").ClassDecoratorContextStub<entityType extends infer T ? T extends entityType ? T extends new (...args: any) => any ? entityType : never : never : never> | undefined) => any;
|
package/esm/FF_Entity.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Entity } from 'remult';
|
|
1
|
+
import { Entity, isBackend } from 'remult';
|
|
2
2
|
import { recordDeleted, recordSaved } from './changeLog';
|
|
3
3
|
const toAllow = (permission) => {
|
|
4
4
|
if (permission) {
|
|
@@ -24,7 +24,9 @@ export function FF_Entity(key, options) {
|
|
|
24
24
|
// Don't log changes
|
|
25
25
|
}
|
|
26
26
|
else {
|
|
27
|
-
|
|
27
|
+
if (isBackend()) {
|
|
28
|
+
await recordSaved(entity, e, options.changeLog);
|
|
29
|
+
}
|
|
28
30
|
}
|
|
29
31
|
},
|
|
30
32
|
deleted: async (entity, e) => {
|
|
@@ -33,7 +35,9 @@ export function FF_Entity(key, options) {
|
|
|
33
35
|
// Don't log changes
|
|
34
36
|
}
|
|
35
37
|
else {
|
|
36
|
-
|
|
38
|
+
if (isBackend()) {
|
|
39
|
+
await recordDeleted(entity, e, options.changeLog);
|
|
40
|
+
}
|
|
37
41
|
}
|
|
38
42
|
},
|
|
39
43
|
});
|
package/esm/ROUTES.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ type ParamValue = string | number | undefined;
|
|
|
7
7
|
/**
|
|
8
8
|
* Append search params to a string
|
|
9
9
|
*/
|
|
10
|
-
export declare const appendSp: (sp?: Record<string, ParamValue | ParamValue[]>, prefix?:
|
|
10
|
+
export declare const appendSp: (sp?: Record<string, ParamValue | ParamValue[]>, prefix?: "?" | "&") => string;
|
|
11
11
|
/**
|
|
12
12
|
* get the current search params
|
|
13
13
|
*
|
|
@@ -41,7 +41,7 @@ declare const AllObjs: {
|
|
|
41
41
|
};
|
|
42
42
|
type AllTypes = typeof AllObjs;
|
|
43
43
|
export type Routes = keyof AllTypes extends `${string}/${infer Route}` ? `/${Route}` : keyof AllTypes;
|
|
44
|
-
export declare const routes:
|
|
44
|
+
export declare const routes: Routes[];
|
|
45
45
|
/**
|
|
46
46
|
* To be used like this:
|
|
47
47
|
* ```ts
|
package/esm/api/index.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { type Handle, type MaybePromise, type RequestEvent } from '@sveltejs/kit';
|
|
1
|
+
import type { Handle, RequestEvent } from '@sveltejs/kit';
|
|
3
2
|
import { type ClassType } from 'remult';
|
|
4
3
|
import type { RemultServerOptions } from 'remult/server';
|
|
5
4
|
import { type MailOptions } from '../mail';
|
|
@@ -15,7 +14,7 @@ export type Module = {
|
|
|
15
14
|
initRequest?: RemultServerOptions<RequestEvent>['initRequest'];
|
|
16
15
|
handlePreRemult?: Handle;
|
|
17
16
|
handlePosRemult?: Handle;
|
|
18
|
-
earlyReturn?: (input: Parameters<Handle>[0]) =>
|
|
17
|
+
earlyReturn?: (input: Parameters<Handle>[0]) => Promise<{
|
|
19
18
|
early: false;
|
|
20
19
|
resolve?: undefined;
|
|
21
20
|
} | {
|
package/esm/api/index.js
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import {} from '@sveltejs/kit';
|
|
2
1
|
import nodemailer from 'nodemailer';
|
|
3
2
|
import { remult } from 'remult';
|
|
4
3
|
import { remultSveltekit } from 'remult/remult-sveltekit';
|
|
@@ -23,9 +22,10 @@ export const firstly = (o) => {
|
|
|
23
22
|
error: o.error
|
|
24
23
|
? o.error
|
|
25
24
|
: async (e) => {
|
|
26
|
-
//
|
|
27
|
-
if
|
|
28
|
-
|
|
25
|
+
// REMULT P2: validation error should probably be 409
|
|
26
|
+
// if 400 we move to 409
|
|
27
|
+
if (e.httpStatusCode == 400) {
|
|
28
|
+
e.sendError(409, e.responseBody);
|
|
29
29
|
}
|
|
30
30
|
},
|
|
31
31
|
// Add user configuration
|
|
@@ -9,4 +9,4 @@ export declare const mergeRoles: (existing: string[], newOnes: string[] | undefi
|
|
|
9
9
|
roles: string[];
|
|
10
10
|
changed: boolean;
|
|
11
11
|
};
|
|
12
|
-
export declare const initRoleFromEnv: (log: Log, userEntity: ClassType<FFAuthUser>,
|
|
12
|
+
export declare const initRoleFromEnv: (log: Log, userEntity: ClassType<FFAuthUser>, envKey: string, role: string) => Promise<void>;
|
package/esm/auth/RoleHelpers.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { repo } from 'remult';
|
|
2
2
|
import { cyan, green, Log, yellow } from '@kitql/helpers';
|
|
3
|
+
import { env } from '$env/dynamic/private';
|
|
3
4
|
import { FFAuthUser } from './client/Entities';
|
|
4
5
|
/**
|
|
5
6
|
* will merge the roles and remove duplicates
|
|
@@ -16,7 +17,8 @@ export const mergeRoles = (existing, newOnes) => {
|
|
|
16
17
|
}
|
|
17
18
|
return { roles: Array.from(result), changed };
|
|
18
19
|
};
|
|
19
|
-
export const initRoleFromEnv = async (log, userEntity,
|
|
20
|
+
export const initRoleFromEnv = async (log, userEntity, envKey, role) => {
|
|
21
|
+
const envValue = envKey ? env[envKey] : '';
|
|
20
22
|
const identifiers = envValue === undefined ? [] : (envValue ?? '').split(',').map((c) => c.trim());
|
|
21
23
|
for (let i = 0; i < identifiers.length; i++) {
|
|
22
24
|
const identifier = identifiers[i].trim();
|
|
@@ -35,9 +37,9 @@ export const initRoleFromEnv = async (log, userEntity, envValue, role) => {
|
|
|
35
37
|
}
|
|
36
38
|
}
|
|
37
39
|
if (identifiers.length > 0) {
|
|
38
|
-
log.info(`${cyan(
|
|
40
|
+
log.info(`${cyan(envKey)}: ${identifiers.map((c) => green(c.trim())).join(', ')} added via ${yellow(`.env`)}.`);
|
|
39
41
|
}
|
|
40
42
|
else {
|
|
41
|
-
log.info(`${cyan(
|
|
43
|
+
log.info(`${cyan(envKey)}: No users added via ${yellow(`.env`)}.`);
|
|
42
44
|
}
|
|
43
45
|
};
|
package/esm/auth/client/Auth.js
CHANGED
|
@@ -4,7 +4,7 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
4
4
|
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
|
-
import { BackendMethod } from 'remult';
|
|
7
|
+
import { Allow, BackendMethod } from 'remult';
|
|
8
8
|
export class Auth {
|
|
9
9
|
// Do not show for firstly users ?
|
|
10
10
|
/** DO NOT USE */
|
|
@@ -104,7 +104,7 @@ __decorate([
|
|
|
104
104
|
BackendMethod({ allowed: true })
|
|
105
105
|
], Auth, "signInDemo", null);
|
|
106
106
|
__decorate([
|
|
107
|
-
BackendMethod({ allowed:
|
|
107
|
+
BackendMethod({ allowed: Allow.authenticated })
|
|
108
108
|
], Auth, "invite", null);
|
|
109
109
|
__decorate([
|
|
110
110
|
BackendMethod({ allowed: true })
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseEnum } from '../..';
|
|
2
2
|
import type { BaseEnumOptions } from '../..';
|
|
3
|
-
export declare const
|
|
4
|
-
readonly Admin: "
|
|
3
|
+
export declare const FF_Role_Auth: {
|
|
4
|
+
readonly Admin: "FF_Role_Auth.Admin";
|
|
5
5
|
};
|
|
6
6
|
export declare class FFAuthUser {
|
|
7
7
|
id: string;
|
|
@@ -7,8 +7,8 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
7
7
|
var FFAuthProvider_1;
|
|
8
8
|
import { Fields, Relations, Validators, ValueListFieldType } from 'remult';
|
|
9
9
|
import { BaseEnum, FF_Entity, FF_Role } from '../..';
|
|
10
|
-
export const
|
|
11
|
-
Admin: '
|
|
10
|
+
export const FF_Role_Auth = {
|
|
11
|
+
Admin: 'FF_Role_Auth.Admin',
|
|
12
12
|
};
|
|
13
13
|
let FFAuthUser = class FFAuthUser {
|
|
14
14
|
id;
|
|
@@ -65,7 +65,7 @@ __decorate([
|
|
|
65
65
|
], FFAuthUser.prototype, "sessions", void 0);
|
|
66
66
|
FFAuthUser = __decorate([
|
|
67
67
|
FF_Entity('ff_auth.users', {
|
|
68
|
-
allowApiCrud: [
|
|
68
|
+
allowApiCrud: [FF_Role_Auth.Admin, FF_Role.Admin],
|
|
69
69
|
caption: 'FF Auth - Users',
|
|
70
70
|
})
|
|
71
71
|
], FFAuthUser);
|
|
@@ -118,7 +118,7 @@ __decorate([
|
|
|
118
118
|
], FFAuthAccount.prototype, "lastVerifiedAt", void 0);
|
|
119
119
|
FFAuthAccount = __decorate([
|
|
120
120
|
FF_Entity('ff_auth.accounts', {
|
|
121
|
-
allowApiCrud: [
|
|
121
|
+
allowApiCrud: [FF_Role_Auth.Admin, FF_Role.Admin],
|
|
122
122
|
caption: 'FF Auth - Accounts',
|
|
123
123
|
// id: { provider: true, userId: true },
|
|
124
124
|
changeLog: {
|
|
@@ -149,7 +149,7 @@ __decorate([
|
|
|
149
149
|
], FFAuthUserSession.prototype, "user", void 0);
|
|
150
150
|
FFAuthUserSession = __decorate([
|
|
151
151
|
FF_Entity('ff_auth.users_sessions', {
|
|
152
|
-
allowApiCrud: [
|
|
152
|
+
allowApiCrud: [FF_Role_Auth.Admin, FF_Role.Admin],
|
|
153
153
|
caption: 'FF Auth - Users sessions',
|
|
154
154
|
changeLog: false,
|
|
155
155
|
})
|
|
@@ -2,6 +2,6 @@ import { Log } from '@kitql/helpers';
|
|
|
2
2
|
import { Auth } from './Auth';
|
|
3
3
|
import { FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession } from './Entities';
|
|
4
4
|
export declare const logAuth: Log;
|
|
5
|
-
export {
|
|
5
|
+
export { FF_Role_Auth } from './Entities';
|
|
6
6
|
export { Auth };
|
|
7
7
|
export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
|
package/esm/auth/client/index.js
CHANGED
|
@@ -2,6 +2,6 @@ import { Log } from '@kitql/helpers';
|
|
|
2
2
|
import { Auth } from './Auth';
|
|
3
3
|
import { FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession } from './Entities';
|
|
4
4
|
export const logAuth = new Log('firstly | auth');
|
|
5
|
-
export {
|
|
5
|
+
export { FF_Role_Auth } from './Entities';
|
|
6
6
|
export { Auth };
|
|
7
7
|
export { FFAuthUser, FFAuthAccount, FFAuthProvider, FFAuthUserSession };
|
package/esm/auth/index.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import type { ClassType, UserInfo } from 'remult';
|
|
|
4
4
|
import type { Module } from '../api';
|
|
5
5
|
import type { RecursivePartial, ResolvedType } from '../utils/types';
|
|
6
6
|
import { FFAuthAccount, FFAuthUser, FFAuthUserSession } from './client/Entities';
|
|
7
|
+
import { initRoleFromEnv } from './RoleHelpers';
|
|
7
8
|
import type { firstlyData, firstlyDataAuth } from './types';
|
|
8
9
|
export type { firstlyData };
|
|
9
10
|
export type AuthorizationURLOptions = Record<string, {
|
|
@@ -129,6 +130,7 @@ export declare const getSafeOptions: () => {
|
|
|
129
130
|
* _Info: index: -777_
|
|
130
131
|
*/
|
|
131
132
|
export declare const auth: (o: AuthOptions) => Module;
|
|
133
|
+
export { initRoleFromEnv };
|
|
132
134
|
export declare let lucia: Lucia<Record<any, any>, UserInfo>;
|
|
133
135
|
declare module 'lucia' {
|
|
134
136
|
interface Register {
|
package/esm/auth/index.js
CHANGED
|
@@ -4,12 +4,11 @@ import { Lucia, TimeSpan } from 'lucia';
|
|
|
4
4
|
import { remult } from 'remult';
|
|
5
5
|
import { red } from '@kitql/helpers';
|
|
6
6
|
import { getRelativePackagePath, read } from '@kitql/internals';
|
|
7
|
-
import { env } from '$env/dynamic/private';
|
|
8
7
|
import { FF_Role } from '../';
|
|
9
8
|
import { RemultLuciaAdapter } from './Adapter';
|
|
10
9
|
import { AuthControllerServer } from './AuthController.server';
|
|
11
10
|
import { Auth, logAuth } from './client';
|
|
12
|
-
import {
|
|
11
|
+
import { FF_Role_Auth, FFAuthAccount, FFAuthProvider, FFAuthUser, FFAuthUserSession, } from './client/Entities';
|
|
13
12
|
import { createOrExtendSession } from './helper';
|
|
14
13
|
import { initRoleFromEnv } from './RoleHelpers';
|
|
15
14
|
export let AUTH_OPTIONS = { ui: {} };
|
|
@@ -24,7 +23,7 @@ const buildUrlOrDefault = (base, userSetting, fallback) => {
|
|
|
24
23
|
};
|
|
25
24
|
export const getSafeOptions = () => {
|
|
26
25
|
const signUp = AUTH_OPTIONS.signUp ?? true;
|
|
27
|
-
const base = AUTH_OPTIONS.ui === false ? 'NO_BASE_PATH' : AUTH_OPTIONS.ui?.paths?.base ?? '/ff/auth';
|
|
26
|
+
const base = AUTH_OPTIONS.ui === false ? 'NO_BASE_PATH' : (AUTH_OPTIONS.ui?.paths?.base ?? '/ff/auth');
|
|
28
27
|
const firstlyData = {
|
|
29
28
|
module: 'auth',
|
|
30
29
|
debug: AUTH_OPTIONS.debug,
|
|
@@ -150,14 +149,25 @@ export const auth = (o) => {
|
|
|
150
149
|
entities: [oSafe.User, oSafe.Session, oSafe.Account],
|
|
151
150
|
controllers: [Auth],
|
|
152
151
|
initRequest: async (event) => {
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
152
|
+
// REMULT: storing user in local should probably be done in remult directly
|
|
153
|
+
if (event?.locals?.user) {
|
|
154
|
+
// console.log('initRequest OK')
|
|
155
|
+
remult.user = event.locals.user;
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
// console.log('initRequest WORK...')
|
|
159
|
+
// std session
|
|
160
|
+
const sessionId = event.cookies.get(lucia.sessionCookieName);
|
|
161
|
+
if (sessionId) {
|
|
162
|
+
const { session, user } = await lucia.validateSession(sessionId);
|
|
163
|
+
if (session && session.fresh) {
|
|
164
|
+
await createOrExtendSession(session.id, session);
|
|
165
|
+
}
|
|
166
|
+
remult.user = user ?? undefined;
|
|
167
|
+
if (event.locals) {
|
|
168
|
+
event.locals.user = user ?? undefined;
|
|
169
|
+
}
|
|
159
170
|
}
|
|
160
|
-
remult.user = user ?? undefined;
|
|
161
171
|
}
|
|
162
172
|
},
|
|
163
173
|
earlyReturn: async ({ event, resolve }) => {
|
|
@@ -296,10 +306,11 @@ export const auth = (o) => {
|
|
|
296
306
|
return { early: false };
|
|
297
307
|
},
|
|
298
308
|
initApi: async () => {
|
|
299
|
-
await initRoleFromEnv(logAuth, oSafe.User,
|
|
300
|
-
await initRoleFromEnv(logAuth, oSafe.User,
|
|
309
|
+
await initRoleFromEnv(logAuth, oSafe.User, 'FF_ROLE_ADMIN', FF_Role.Admin);
|
|
310
|
+
await initRoleFromEnv(logAuth, oSafe.User, 'FF_ROLE_AUTH_ADMIN', FF_Role_Auth.Admin);
|
|
301
311
|
},
|
|
302
312
|
};
|
|
303
313
|
};
|
|
314
|
+
export { initRoleFromEnv };
|
|
304
315
|
// Maybe moving this to /auth/server.ts would be better, people will be able to import from firstly all the time
|
|
305
316
|
export let lucia;
|
package/esm/cellsBuildor.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import type { SvelteComponent } from 'svelte';
|
|
2
|
-
import { type EntityFilter, type FieldMetadata, type Repository } from 'remult';
|
|
2
|
+
import { type ClassType, type EntityFilter, type FieldMetadata, type Repository } from 'remult';
|
|
3
3
|
import type { UnArray } from './utils/types.js';
|
|
4
4
|
export type VisibilityMode = 'view' | 'edit' | 'hide';
|
|
5
5
|
type CellInternal<Entity> = {
|
|
6
6
|
col?: keyof Entity;
|
|
7
|
-
kind?: 'field' | 'field_link' | 'entity_link' | 'slot' | 'header' | 'component';
|
|
7
|
+
kind?: 'field' | 'field_link' | 'entity_link' | 'slot' | 'header' | 'component' | 'baseItem';
|
|
8
8
|
class?: string;
|
|
9
9
|
header?: string;
|
|
10
10
|
headerSlot?: boolean;
|
|
@@ -40,7 +40,7 @@ export declare function cellsBuildor<Entity>(repo: Repository<Entity>, inputBuil
|
|
|
40
40
|
export declare function cellBuildor<Entity>(repo: Repository<Entity>, inputBuildor: UnArray<CellsInput<Entity>>): Cell<Entity>;
|
|
41
41
|
export declare const fieldsOf: <Entity>(b: Cell<Entity>[]) => FieldMetadata<any, Entity>[];
|
|
42
42
|
export declare const getPlaceholder: <Entity>(fields: FieldMetadata<any, Entity>[]) => string;
|
|
43
|
-
export declare const buildSearchWhere: <Entity>(entity: Entity | undefined, fields: FieldMetadata<any, Entity>[], search?: string | null) => EntityFilter<Entity>[];
|
|
43
|
+
export declare const buildSearchWhere: <Entity>(entity: ClassType<Entity> | undefined, fields: FieldMetadata<any, Entity>[], search?: string | null) => EntityFilter<Entity>[];
|
|
44
44
|
export declare const containsWords: <Entity>(fields: FieldMetadata<any, Entity>[], search: string) => EntityFilter<Entity>;
|
|
45
|
-
export declare const buildWhere: <Entity>(entity: Entity | undefined, defaultWhere: EntityFilter<Entity> | undefined, fields_filter: FieldMetadata<any, Entity>[], fields_search: FieldMetadata<any, Entity>[], obj: Record<string, string>) => EntityFilter<Entity>;
|
|
45
|
+
export declare const buildWhere: <Entity>(entity: ClassType<Entity> | undefined, defaultWhere: EntityFilter<Entity> | undefined, fields_filter: FieldMetadata<any, Entity>[], fields_search: FieldMetadata<any, Entity>[], obj: Record<string, string>) => EntityFilter<Entity>;
|
|
46
46
|
export {};
|
package/esm/cellsBuildor.js
CHANGED
|
@@ -77,7 +77,7 @@ export const buildSearchWhere = (entity, fields, search) => {
|
|
|
77
77
|
return f;
|
|
78
78
|
};
|
|
79
79
|
export const containsWords = (fields, search) => {
|
|
80
|
-
const sSplitted = search.split(' ');
|
|
80
|
+
const sSplitted = search.split(' ').filter((s) => s.length > 0);
|
|
81
81
|
if (fields.length === 1) {
|
|
82
82
|
return {
|
|
83
83
|
$and: sSplitted.map((s) => ({ [fields[0].key]: { $contains: s } })),
|
|
@@ -106,12 +106,25 @@ export const buildWhere = (entity, defaultWhere, fields_filter, fields_search, o
|
|
|
106
106
|
and.push({ [field.key]: obj[field.key] });
|
|
107
107
|
}
|
|
108
108
|
else if (field.inputType === 'selectEnum') {
|
|
109
|
+
const fnName = field.key + 'Filter';
|
|
109
110
|
// @ts-ignore
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
if (entity && entity[fnName]) {
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
and.push(entity[fnName](obj[field.key]));
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
// @ts-ignore
|
|
117
|
+
const theEnum = getEnum(field, obj[field.key]);
|
|
118
|
+
// Take the where of the enum if it exists, or it's using this selection as a filter
|
|
119
|
+
if (theEnum?.where) {
|
|
120
|
+
and.push(theEnum.where);
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
const wheretoUse = theEnum?.where ?? new BaseEnum(obj[field.key]);
|
|
124
|
+
// @ts-ignore
|
|
125
|
+
and.push({ [field.key]: wheretoUse });
|
|
126
|
+
}
|
|
127
|
+
}
|
|
115
128
|
}
|
|
116
129
|
else if (rfi?.type === 'toOne') {
|
|
117
130
|
// @ts-ignore (setting the id of the relation)
|
|
@@ -21,13 +21,11 @@ async function getGitHub(query, variables) {
|
|
|
21
21
|
const response = await fetch(GITHUB_GRAPHQL_ENDPOINT, { method: 'POST', headers, body });
|
|
22
22
|
const result = await response.json();
|
|
23
23
|
if (result.errors) {
|
|
24
|
-
/* eslint-disable */
|
|
25
24
|
console.error(`result ERRORS`, body, stry(result));
|
|
26
25
|
}
|
|
27
26
|
return result.data;
|
|
28
27
|
}
|
|
29
28
|
catch (error) {
|
|
30
|
-
/* eslint-disable */
|
|
31
29
|
console.error(`error`, error);
|
|
32
30
|
}
|
|
33
31
|
return null;
|
|
@@ -83,11 +83,11 @@ const disableButton = (issueNumber2, title2, content2) => {
|
|
|
83
83
|
).toLocaleTimeString()}</time
|
|
84
84
|
>
|
|
85
85
|
</div>
|
|
86
|
-
<div class="chat-bubble">{@html item.bodyHTML}</div>
|
|
86
|
+
<div class="chat-bubble prose">{@html item.bodyHTML}</div>
|
|
87
87
|
<!-- <div class="chat-footer opacity-50">Delivered</div> -->
|
|
88
88
|
</div>
|
|
89
89
|
{/each}
|
|
90
|
-
{#if issue?.highlight}
|
|
90
|
+
{#if issue?.highlight && issue.state === 'OPEN'}
|
|
91
91
|
<span class="badge badge-warning">En attente de réponse de TA part 😉, oui 🫵!</span>
|
|
92
92
|
{/if}
|
|
93
93
|
{#if issueNumber}
|
|
@@ -106,15 +106,15 @@ const disableButton = (issueNumber2, title2, content2) => {
|
|
|
106
106
|
></Textarea>
|
|
107
107
|
<div class="flex justify-between">
|
|
108
108
|
{#if issueNumber}
|
|
109
|
-
<Button on:click={close} tabIndex={-1} class="btn-outline btn-error"
|
|
110
|
-
Clore le feedback
|
|
111
|
-
|
|
109
|
+
<Button on:click={close} tabIndex={-1} class="btn-outline btn-error"
|
|
110
|
+
>Clore le feedback</Button
|
|
111
|
+
>
|
|
112
112
|
{:else}
|
|
113
113
|
<div></div>
|
|
114
114
|
{/if}
|
|
115
|
-
<Button on:click={send} disabled={disableButton(issueNumber, title, content)}
|
|
116
|
-
Envoyer
|
|
117
|
-
|
|
115
|
+
<Button on:click={send} disabled={disableButton(issueNumber, title, content)}
|
|
116
|
+
>Envoyer</Button
|
|
117
|
+
>
|
|
118
118
|
</div>
|
|
119
119
|
{/if}
|
|
120
120
|
{/if}
|
package/esm/handle/index.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/// <reference types=".pnpm/@sveltejs+kit@2.5.24_@sveltejs+vite-plugin-svelte@3.1.2_svelte@4.2.18_vite@5.4.1_@types+node@_lnml5jetshdinsnlj53joqxhde/node_modules/@sveltejs/kit" />
|
|
2
1
|
import type { Handle } from '@sveltejs/kit';
|
|
3
2
|
import type { RemultSveltekitServer } from 'remult/remult-sveltekit';
|
|
4
3
|
import type { Module } from '../api';
|
package/esm/helper.d.ts
CHANGED
|
@@ -1,19 +1,9 @@
|
|
|
1
|
-
import type { ClassType, ErrorInfo, FieldMetadata, Repository } from 'remult';
|
|
1
|
+
import type { ClassType, ErrorInfo, FieldMetadata, LifecycleEvent, Repository } from 'remult';
|
|
2
2
|
import type { BaseEnum, BaseItem } from './index.js';
|
|
3
3
|
export declare function isError<T>(object: any): object is ErrorInfo<T>;
|
|
4
4
|
export declare const getFirstInterestingField: <Entity>(repo: Repository<Entity>) => FieldMetadata<any, Entity>;
|
|
5
5
|
export declare const getEntityDisplayValue: <Entity>(repo: Repository<Entity>, row: Entity) => BaseItem;
|
|
6
|
-
export declare const getFieldLinkDisplayValue: (field: FieldMetadata, row: any) =>
|
|
7
|
-
id: string;
|
|
8
|
-
captionSub?: string | (string | undefined)[] | undefined;
|
|
9
|
-
href?: string | undefined;
|
|
10
|
-
repo?: Repository<any> | undefined;
|
|
11
|
-
sub?: {
|
|
12
|
-
captionPre?: string | undefined;
|
|
13
|
-
repo?: Repository<any> | undefined;
|
|
14
|
-
item?: any;
|
|
15
|
-
} | undefined;
|
|
16
|
-
} & {
|
|
6
|
+
export declare const getFieldLinkDisplayValue: (field: FieldMetadata, row: any) => BaseItem & {
|
|
17
7
|
href: string;
|
|
18
8
|
};
|
|
19
9
|
export declare const getEntityDisplayValueFromField: (field: FieldMetadata, row: any) => BaseItem & {
|
|
@@ -43,6 +33,18 @@ type MetaTypeSlot = {
|
|
|
43
33
|
export type FieldMetaType = MetaTypeRelation | MetaTypeEnum | MetaTypePrimitive | MetaTypeSlot;
|
|
44
34
|
export declare const getFieldMetaType: (field?: FieldMetadata) => FieldMetaType;
|
|
45
35
|
export declare const displayWithDefaultAndSuffix: (field: FieldMetadata<any, any> | undefined, value: any) => string;
|
|
46
|
-
export declare const getEnum: <T extends BaseEnum
|
|
47
|
-
export declare const getEnums: <T extends BaseEnum
|
|
36
|
+
export declare const getEnum: <T extends BaseEnum>(baseEnum: ClassType<T>, id: string | undefined | null) => T | undefined;
|
|
37
|
+
export declare const getEnums: <T extends BaseEnum>(baseEnum: ClassType<T>) => T[];
|
|
38
|
+
export declare const upsert: <Entity>(currentRepo: Repository<Entity>, id: Parameters<typeof currentRepo.findId>[0], entity: Partial<Entity>) => Promise<void>;
|
|
39
|
+
/**
|
|
40
|
+
* To be used like:
|
|
41
|
+
* ```ts
|
|
42
|
+
* \@Entity('tasks', {
|
|
43
|
+
* async deleting(item, e) {
|
|
44
|
+
* await onDelete(item, e, 'prevent')
|
|
45
|
+
* },
|
|
46
|
+
* }
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
export declare const onDelete: <T>(item: T, e: LifecycleEvent<T>, mode?: "prevent" | "cascade") => Promise<void>;
|
|
48
50
|
export {};
|
package/esm/helper.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { getEntityRef, getValueList } from 'remult';
|
|
2
2
|
import { getRelationFieldInfo } from 'remult/internals';
|
|
3
|
+
import { stryEq } from '@kitql/helpers';
|
|
3
4
|
import { suffixWithS } from './formats/strings.js';
|
|
4
5
|
export function isError(object) {
|
|
5
6
|
return object;
|
|
@@ -22,7 +23,8 @@ export const getEntityDisplayValue = (repo, row) => {
|
|
|
22
23
|
}
|
|
23
24
|
const field = getFirstInterestingField(repo);
|
|
24
25
|
// REMULT P3 JYC: If it's an enum, it's not working...
|
|
25
|
-
|
|
26
|
+
// @ts-ignore (added for row?.id)
|
|
27
|
+
return { caption: row ? field.displayValue(row) : '-', id: row?.id ? row.id : '' };
|
|
26
28
|
};
|
|
27
29
|
export const getFieldLinkDisplayValue = (field, row) => {
|
|
28
30
|
const caption = field.displayValue(row);
|
|
@@ -89,7 +91,7 @@ export const displayWithDefaultAndSuffix = (field, value) => {
|
|
|
89
91
|
}
|
|
90
92
|
else {
|
|
91
93
|
// toRet.push(value ?? '-')
|
|
92
|
-
toRet.push(field?.displayValue ? field?.displayValue({ [field.key]: value }) : value ?? '-');
|
|
94
|
+
toRet.push(field?.displayValue ? field?.displayValue({ [field.key]: value }) : (value ?? '-'));
|
|
93
95
|
}
|
|
94
96
|
if (value === undefined || value === null) {
|
|
95
97
|
return '';
|
|
@@ -117,3 +119,57 @@ export const getEnum = (baseEnum, id) => {
|
|
|
117
119
|
export const getEnums = (baseEnum) => {
|
|
118
120
|
return getValueList(baseEnum) || [];
|
|
119
121
|
};
|
|
122
|
+
export const upsert = async (currentRepo, id, entity) => {
|
|
123
|
+
const found = await currentRepo.findId(id);
|
|
124
|
+
if (found) {
|
|
125
|
+
// @ts-ignore
|
|
126
|
+
if (!stryEq(found, entity)) {
|
|
127
|
+
// Opti => Sedn only the diff?
|
|
128
|
+
await currentRepo.update(id, entity);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
await currentRepo.insert(entity);
|
|
133
|
+
}
|
|
134
|
+
};
|
|
135
|
+
/**
|
|
136
|
+
* To be used like:
|
|
137
|
+
* ```ts
|
|
138
|
+
* \@Entity('tasks', {
|
|
139
|
+
* async deleting(item, e) {
|
|
140
|
+
* await onDelete(item, e, 'prevent')
|
|
141
|
+
* },
|
|
142
|
+
* }
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
export const onDelete = async (item, e, mode = 'prevent') => {
|
|
146
|
+
const toManies = e.repository.fields
|
|
147
|
+
.toArray()
|
|
148
|
+
.map((f) => {
|
|
149
|
+
return {
|
|
150
|
+
f: f,
|
|
151
|
+
fi: getRelationFieldInfo(f),
|
|
152
|
+
};
|
|
153
|
+
})
|
|
154
|
+
.filter((f) => f.fi?.type === 'toMany');
|
|
155
|
+
const checks = await Promise.all(toManies.map(async (f_fi) => {
|
|
156
|
+
// @ts-ignore
|
|
157
|
+
const count = await e.repository.relations(item)[f_fi.f.key].count();
|
|
158
|
+
return { ...f_fi, count };
|
|
159
|
+
}));
|
|
160
|
+
const nonEmptyRelations = checks.filter((check) => check.count > 0);
|
|
161
|
+
if (nonEmptyRelations.length > 0) {
|
|
162
|
+
if (mode === 'prevent') {
|
|
163
|
+
const relationNames = nonEmptyRelations.map((r) => r.f.caption).join(', ');
|
|
164
|
+
throw Error(`Can't with existing: ${relationNames}`);
|
|
165
|
+
}
|
|
166
|
+
else if (mode === 'cascade') {
|
|
167
|
+
nonEmptyRelations.forEach(async (r) => {
|
|
168
|
+
const where = Object.entries(r.fi?.getFields().fields ?? {}).map(([key, value]) => {
|
|
169
|
+
return { [key]: item[value] };
|
|
170
|
+
});
|
|
171
|
+
await r.fi?.toRepo.deleteMany({ where });
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
};
|