@venizia/ignis 0.4.7-0 → 0.4.7-2
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/LICENSE.md +1 -4
- package/README.md +2 -2
- package/dist/esm/base/applications/base.d.ts.map +1 -1
- package/dist/esm/base/applications/base.js +25 -18
- package/dist/esm/base/applications/base.js.map +1 -1
- package/dist/esm/base/applications/common/index.d.ts +1 -0
- package/dist/esm/base/applications/common/index.d.ts.map +1 -1
- package/dist/esm/base/applications/common/index.js +1 -0
- package/dist/esm/base/applications/common/index.js.map +1 -1
- package/dist/esm/base/applications/common/logger-startup.d.ts +11 -0
- package/dist/esm/base/applications/common/logger-startup.d.ts.map +1 -0
- package/dist/esm/base/applications/common/logger-startup.js +29 -0
- package/dist/esm/base/applications/common/logger-startup.js.map +1 -0
- package/dist/esm/base/applications/server.d.ts +14 -9
- package/dist/esm/base/applications/server.d.ts.map +1 -1
- package/dist/esm/base/applications/server.js +36 -29
- package/dist/esm/base/applications/server.js.map +1 -1
- package/dist/esm/common/constants.d.ts.map +1 -1
- package/dist/esm/common/constants.js +2 -2
- package/dist/esm/common/constants.js.map +1 -1
- package/dist/esm/components/auth/authenticate/component.js +2 -2
- package/dist/esm/components/auth/authenticate/component.js.map +1 -1
- package/dist/esm/components/auth/authenticate/controllers/factory.d.ts +139 -136
- package/dist/esm/components/auth/authenticate/controllers/factory.d.ts.map +1 -1
- package/dist/esm/components/auth/authenticate/controllers/factory.js +175 -172
- package/dist/esm/components/auth/authenticate/controllers/factory.js.map +1 -1
- package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js +2 -2
- package/dist/esm/components/auth/authenticate/controllers/jwks/definitions.js.map +1 -1
- package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js +2 -2
- package/dist/esm/components/auth/authenticate/controllers/service-certs/definitions.js.map +1 -1
- package/dist/esm/components/auth/authorize/adapters/base-filtered.js +2 -2
- package/dist/esm/components/auth/authorize/adapters/base-filtered.js.map +1 -1
- package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.d.ts.map +1 -1
- package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js +2 -2
- package/dist/esm/components/auth/authorize/adapters/custom-grant-expander.js.map +1 -1
- package/dist/esm/components/auth/models/entities/columns.d.ts +99 -0
- package/dist/esm/components/auth/models/entities/columns.d.ts.map +1 -0
- package/dist/esm/components/auth/models/entities/columns.js +133 -0
- package/dist/esm/components/auth/models/entities/columns.js.map +1 -0
- package/dist/esm/components/auth/models/entities/index.d.ts +1 -2
- package/dist/esm/components/auth/models/entities/index.d.ts.map +1 -1
- package/dist/esm/components/auth/models/entities/index.js +1 -2
- package/dist/esm/components/auth/models/entities/index.js.map +1 -1
- package/dist/esm/components/auth/models/entities/permission.model.d.ts +1 -12
- package/dist/esm/components/auth/models/entities/permission.model.d.ts.map +1 -1
- package/dist/esm/components/auth/models/entities/permission.model.js +1 -36
- package/dist/esm/components/auth/models/entities/permission.model.js.map +1 -1
- package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts +1 -49
- package/dist/esm/components/auth/models/entities/policy-definition.model.d.ts.map +1 -1
- package/dist/esm/components/auth/models/entities/policy-definition.model.js +1 -69
- package/dist/esm/components/auth/models/entities/policy-definition.model.js.map +1 -1
- package/dist/esm/components/controller/grpc/grpc.component.js +2 -2
- package/dist/esm/components/controller/grpc/grpc.component.js.map +1 -1
- package/dist/esm/components/health-check/controller.js +5 -5
- package/dist/esm/components/health-check/controller.js.map +1 -1
- package/dist/esm/components/index.d.ts +0 -1
- package/dist/esm/components/index.d.ts.map +1 -1
- package/dist/esm/components/index.js +0 -1
- package/dist/esm/components/index.js.map +1 -1
- package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.d.ts.map +1 -1
- package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js +13 -9
- package/dist/esm/components/mail/helpers/transporters/amazon-ses-transporter.helper.js.map +1 -1
- package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.d.ts.map +1 -1
- package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js +5 -3
- package/dist/esm/components/mail/helpers/transporters/mailgun-transporter.helper.js.map +1 -1
- package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.d.ts.map +1 -1
- package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js +5 -5
- package/dist/esm/components/mail/helpers/transporters/nodemail-transporter.helper.js.map +1 -1
- package/dist/esm/components/mail/services/generators/verification-data.d.ts.map +1 -1
- package/dist/esm/components/mail/services/generators/verification-data.js +7 -3
- package/dist/esm/components/mail/services/generators/verification-data.js.map +1 -1
- package/dist/esm/components/mail/services/mail.service.js +7 -7
- package/dist/esm/components/mail/services/mail.service.js.map +1 -1
- package/dist/esm/components/mail/utilities/address.utility.d.ts +12 -8
- package/dist/esm/components/mail/utilities/address.utility.d.ts.map +1 -1
- package/dist/esm/components/mail/utilities/address.utility.js +30 -27
- package/dist/esm/components/mail/utilities/address.utility.js.map +1 -1
- package/dist/esm/components/mail/utilities/attachment.utility.d.ts +31 -29
- package/dist/esm/components/mail/utilities/attachment.utility.d.ts.map +1 -1
- package/dist/esm/components/mail/utilities/attachment.utility.js +97 -86
- package/dist/esm/components/mail/utilities/attachment.utility.js.map +1 -1
- package/dist/esm/components/mail/utilities/body.utility.d.ts +6 -4
- package/dist/esm/components/mail/utilities/body.utility.d.ts.map +1 -1
- package/dist/esm/components/mail/utilities/body.utility.js +14 -12
- package/dist/esm/components/mail/utilities/body.utility.js.map +1 -1
- package/dist/esm/components/mail/utilities/mime.utility.d.ts +23 -17
- package/dist/esm/components/mail/utilities/mime.utility.d.ts.map +1 -1
- package/dist/esm/components/mail/utilities/mime.utility.js +109 -102
- package/dist/esm/components/mail/utilities/mime.utility.js.map +1 -1
- package/dist/esm/components/mail/utilities/verification.utility.d.ts +8 -2
- package/dist/esm/components/mail/utilities/verification.utility.d.ts.map +1 -1
- package/dist/esm/components/mail/utilities/verification.utility.js +7 -5
- package/dist/esm/components/mail/utilities/verification.utility.js.map +1 -1
- package/dist/esm/components/socket-io/component.js +3 -3
- package/dist/esm/components/socket-io/component.js.map +1 -1
- package/dist/esm/components/socket-io/handlers/bun.handler.d.ts +13 -11
- package/dist/esm/components/socket-io/handlers/bun.handler.d.ts.map +1 -1
- package/dist/esm/components/socket-io/handlers/bun.handler.js +32 -30
- package/dist/esm/components/socket-io/handlers/bun.handler.js.map +1 -1
- package/dist/esm/components/static-asset/common/commit-token.d.ts +21 -16
- package/dist/esm/components/static-asset/common/commit-token.d.ts.map +1 -1
- package/dist/esm/components/static-asset/common/commit-token.js +35 -28
- package/dist/esm/components/static-asset/common/commit-token.js.map +1 -1
- package/dist/esm/components/static-asset/common/constants.d.ts +0 -2
- package/dist/esm/components/static-asset/common/constants.d.ts.map +1 -1
- package/dist/esm/components/static-asset/common/constants.js +1 -3
- package/dist/esm/components/static-asset/common/constants.js.map +1 -1
- package/dist/esm/components/static-asset/common/types.d.ts +0 -4
- package/dist/esm/components/static-asset/common/types.d.ts.map +1 -1
- package/dist/esm/components/static-asset/common/types.js.map +1 -1
- package/dist/esm/components/static-asset/component.js +2 -2
- package/dist/esm/components/static-asset/component.js.map +1 -1
- package/dist/esm/components/static-asset/controller/base.definition.d.ts +6 -6
- package/dist/esm/components/static-asset/controller/base.definition.d.ts.map +1 -1
- package/dist/esm/components/static-asset/controller/base.definition.js +224 -224
- package/dist/esm/components/static-asset/controller/base.definition.js.map +1 -1
- package/dist/esm/components/static-asset/controller/factory.d.ts +23 -23
- package/dist/esm/components/static-asset/controller/factory.d.ts.map +1 -1
- package/dist/esm/components/static-asset/controller/factory.js +105 -76
- package/dist/esm/components/static-asset/controller/factory.js.map +1 -1
- package/dist/esm/components/static-asset/controller/key-scope.d.ts +28 -26
- package/dist/esm/components/static-asset/controller/key-scope.d.ts.map +1 -1
- package/dist/esm/components/static-asset/controller/key-scope.js +34 -30
- package/dist/esm/components/static-asset/controller/key-scope.js.map +1 -1
- package/dist/esm/components/static-asset/controller/meta-link.d.ts +37 -33
- package/dist/esm/components/static-asset/controller/meta-link.d.ts.map +1 -1
- package/dist/esm/components/static-asset/controller/meta-link.js +86 -84
- package/dist/esm/components/static-asset/controller/meta-link.js.map +1 -1
- package/dist/esm/components/static-asset/controller/route-options.d.ts +18 -16
- package/dist/esm/components/static-asset/controller/route-options.d.ts.map +1 -1
- package/dist/esm/components/static-asset/controller/route-options.js +28 -26
- package/dist/esm/components/static-asset/controller/route-options.js.map +1 -1
- package/dist/esm/components/static-asset/models/base.model.js +3 -3
- package/dist/esm/components/static-asset/models/base.model.js.map +1 -1
- package/dist/esm/components/websocket/component.js +2 -2
- package/dist/esm/components/websocket/component.js.map +1 -1
- package/dist/esm/components/websocket/handlers/bun.handler.d.ts +6 -4
- package/dist/esm/components/websocket/handlers/bun.handler.d.ts.map +1 -1
- package/dist/esm/components/websocket/handlers/bun.handler.js +21 -19
- package/dist/esm/components/websocket/handlers/bun.handler.js.map +1 -1
- package/dist/esm/testing/assert-application-boots.d.ts +6 -1
- package/dist/esm/testing/assert-application-boots.d.ts.map +1 -1
- package/dist/esm/testing/assert-application-boots.js +139 -136
- package/dist/esm/testing/assert-application-boots.js.map +1 -1
- package/dist/esm/utilities/drizzle-result.utility.d.ts +6 -8
- package/dist/esm/utilities/drizzle-result.utility.d.ts.map +1 -1
- package/dist/esm/utilities/drizzle-result.utility.js +23 -49
- package/dist/esm/utilities/drizzle-result.utility.js.map +1 -1
- package/dist/esm/utilities/network.utility.d.ts.map +1 -1
- package/dist/esm/utilities/network.utility.js +2 -2
- package/dist/esm/utilities/network.utility.js.map +1 -1
- package/dist/presets/app/files/src/boot.test.ts +2 -2
- package/dist/presets/app/files/src/controllers/hello.controller.ts +2 -2
- package/dist/presets/app/preset.json +4 -4
- package/dist/presets/lib/preset.json +4 -4
- package/dist/presets/shared/files/.configs/formatters/.ignore +4 -0
- package/dist/presets/shared/files/.configs/lints/.ignore +4 -0
- package/dist/presets/shared/files/.configs/lints/eslint.config.mjs +4 -0
- package/dist/presets/shared/files/.configs/lints/oxlint.config.mts +4 -0
- package/dist/presets/shared/files/README.md +15 -0
- package/dist/presets/shared/files/src/index.test.ts +8 -0
- package/dist/presets/shared/files/src/index.ts +8 -0
- package/dist/presets/shared/files/tsconfig.json +20 -0
- package/dist/presets/shared/preset.json +35 -0
- package/package.json +11 -11
- package/dist/esm/components/auth/models/entities/role.model.d.ts +0 -10
- package/dist/esm/components/auth/models/entities/role.model.d.ts.map +0 -1
- package/dist/esm/components/auth/models/entities/role.model.js +0 -15
- package/dist/esm/components/auth/models/entities/role.model.js.map +0 -1
- package/dist/esm/components/auth/models/entities/user.model.d.ts +0 -28
- package/dist/esm/components/auth/models/entities/user.model.d.ts.map +0 -1
- package/dist/esm/components/auth/models/entities/user.model.js +0 -17
- package/dist/esm/components/auth/models/entities/user.model.js.map +0 -1
- package/dist/esm/components/controller/index.d.ts +0 -2
- package/dist/esm/components/controller/index.d.ts.map +0 -1
- package/dist/esm/components/controller/index.js +0 -7
- package/dist/esm/components/controller/index.js.map +0 -1
|
@@ -1,37 +1,41 @@
|
|
|
1
1
|
import type { IBucketRef, IFileStat, IObjectRef, IStorageHelper, IUploadResult } from '@venizia/ignis-helpers';
|
|
2
2
|
import type { AnyType } from '@venizia/ignis-helpers/common';
|
|
3
3
|
import type { TMetaLinkConfig, TStaticAssetStorageType, TUploadQuery } from '../common/index.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
}
|
|
4
|
+
export declare class AssetMetaLink {
|
|
5
|
+
/** What a stat says about one stored object: the columns a refresh rewrites and a new row starts from. */
|
|
6
|
+
private static buildStoredObjectFacts;
|
|
7
|
+
/** The upload result of an object already in storage, so a commit or a recreate writes its row the way an upload does. */
|
|
8
|
+
static buildStoredUploadResult(opts: {
|
|
9
|
+
helper: IStorageHelper;
|
|
10
|
+
bucket: IBucketRef;
|
|
11
|
+
object: IObjectRef;
|
|
12
|
+
link: string;
|
|
13
|
+
fileStat: IFileStat;
|
|
14
|
+
}): IUploadResult;
|
|
15
|
+
/** The MetaLink row for one stored object. Every path that creates a row goes through here, so each lands exactly the row an ordinary upload does. */
|
|
16
|
+
static createRow(opts: {
|
|
17
|
+
metaLink: TMetaLinkConfig<AnyType>;
|
|
18
|
+
helper: IStorageHelper;
|
|
19
|
+
storage: TStaticAssetStorageType;
|
|
20
|
+
uploadResult: IUploadResult;
|
|
21
|
+
fileStat: IFileStat;
|
|
22
|
+
query: TUploadQuery;
|
|
23
|
+
}): Promise<AnyType>;
|
|
24
|
+
/**
|
|
25
|
+
* Rewrites the stored-object facts on every row of the pair. Rows per pair are deliberately not
|
|
26
|
+
* unique, and each keeps its own labels and storage type. A `createMetaLink` hook owns `link` and
|
|
27
|
+
* `metadata`, so with one only the stat columns change; without one, `metadata` is merged per row.
|
|
28
|
+
*/
|
|
29
|
+
static refreshRows(opts: {
|
|
30
|
+
metaLink: TMetaLinkConfig<AnyType>;
|
|
31
|
+
helper: IStorageHelper;
|
|
32
|
+
bucket: IBucketRef;
|
|
33
|
+
object: IObjectRef;
|
|
34
|
+
link: string;
|
|
35
|
+
fileStat: IFileStat;
|
|
36
|
+
}): Promise<{
|
|
37
|
+
count: number;
|
|
38
|
+
data: AnyType[];
|
|
39
|
+
}>;
|
|
40
|
+
}
|
|
37
41
|
//# sourceMappingURL=meta-link.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta-link.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/meta-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,aAAa,EACd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"meta-link.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/meta-link.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,UAAU,EACV,SAAS,EACT,UAAU,EACV,cAAc,EACd,aAAa,EACd,MAAM,wBAAwB,CAAC;AAEhC,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,EAAE,eAAe,EAAE,uBAAuB,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AAExF,qBAAa,aAAa;IACxB,0GAA0G;IAC1G,OAAO,CAAC,MAAM,CAAC,sBAAsB;IAmBrC,0HAA0H;IAC1H,MAAM,CAAC,uBAAuB,CAAC,IAAI,EAAE;QACnC,MAAM,EAAE,cAAc,CAAC;QACvB,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,UAAU,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,SAAS,CAAC;KACrB,GAAG,aAAa;IAcjB,sJAAsJ;WACzI,SAAS,CAAC,IAAI,EAAE;QAC3B,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,EAAE,cAAc,CAAC;QACvB,OAAO,EAAE,uBAAuB,CAAC;QACjC,YAAY,EAAE,aAAa,CAAC;QAC5B,QAAQ,EAAE,SAAS,CAAC;QACpB,KAAK,EAAE,YAAY,CAAC;KACrB,GAAG,OAAO,CAAC,OAAO,CAAC;IAiCpB;;;;OAIG;WACU,WAAW,CAAC,IAAI,EAAE;QAC7B,QAAQ,EAAE,eAAe,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,EAAE,cAAc,CAAC;QACvB,MAAM,EAAE,UAAU,CAAC;QACnB,MAAM,EAAE,UAAU,CAAC;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,SAAS,CAAC;KACrB,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,EAAE,CAAA;KAAE,CAAC;CAmChD"}
|
|
@@ -1,89 +1,91 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
etag: fileStat.etag,
|
|
11
|
-
metadata: fileStat.metadata,
|
|
12
|
-
isSynced: true,
|
|
13
|
-
};
|
|
14
|
-
};
|
|
15
|
-
/** The upload result of an object already in storage, so a commit or a recreate writes its row the way an upload does. */
|
|
16
|
-
export const buildStoredUploadResult = (opts) => {
|
|
17
|
-
const { helper, bucket, object, link, fileStat } = opts;
|
|
18
|
-
return {
|
|
19
|
-
bucket,
|
|
20
|
-
object: {
|
|
21
|
-
key: object.key,
|
|
1
|
+
import { ResolverUtility } from '@venizia/ignis-helpers/common';
|
|
2
|
+
export class AssetMetaLink {
|
|
3
|
+
/** What a stat says about one stored object: the columns a refresh rewrites and a new row starts from. */
|
|
4
|
+
static buildStoredObjectFacts(opts) {
|
|
5
|
+
const { helper, object, link, fileStat } = opts;
|
|
6
|
+
return {
|
|
7
|
+
link,
|
|
8
|
+
// The column is NOT NULL and a backend may report nothing.
|
|
9
|
+
mimetype: fileStat.metadata?.mimetype ?? helper.getMimeType({ filename: object.key }),
|
|
22
10
|
size: fileStat.size,
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
}
|
|
28
|
-
/** The
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
11
|
+
etag: fileStat.etag,
|
|
12
|
+
metadata: fileStat.metadata,
|
|
13
|
+
isSynced: true,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
/** The upload result of an object already in storage, so a commit or a recreate writes its row the way an upload does. */
|
|
17
|
+
static buildStoredUploadResult(opts) {
|
|
18
|
+
const { helper, bucket, object, link, fileStat } = opts;
|
|
19
|
+
return {
|
|
20
|
+
bucket,
|
|
21
|
+
object: {
|
|
22
|
+
key: object.key,
|
|
23
|
+
size: fileStat.size,
|
|
24
|
+
contentType: fileStat.metadata?.mimetype ?? helper.getMimeType({ filename: object.key }),
|
|
25
|
+
},
|
|
26
|
+
link,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** The MetaLink row for one stored object. Every path that creates a row goes through here, so each lands exactly the row an ordinary upload does. */
|
|
30
|
+
static async createRow(opts) {
|
|
31
|
+
const { metaLink, helper, storage, uploadResult, fileStat, query } = opts;
|
|
32
|
+
if (metaLink.createMetaLink) {
|
|
33
|
+
const created = await metaLink.createMetaLink({ uploadResult, fileStat, query });
|
|
34
|
+
return created.data;
|
|
35
|
+
}
|
|
36
|
+
// Resolved per call so an application that swaps the repository is not pinned to the first one.
|
|
37
|
+
const repository = await ResolverUtility.resolveValueAsync({ value: metaLink.repository });
|
|
38
|
+
const created = await repository.create({
|
|
39
|
+
data: {
|
|
40
|
+
bucketName: uploadResult.bucket.name,
|
|
41
|
+
objectName: uploadResult.object.key,
|
|
42
|
+
...AssetMetaLink.buildStoredObjectFacts({
|
|
43
|
+
helper,
|
|
44
|
+
object: uploadResult.object,
|
|
45
|
+
link: uploadResult.link,
|
|
46
|
+
fileStat,
|
|
47
|
+
}),
|
|
48
|
+
storageType: storage,
|
|
49
|
+
principalId: query.principalId ? String(query.principalId) : undefined,
|
|
50
|
+
principalType: query.principalType ? String(query.principalType) : undefined,
|
|
51
|
+
variant: query.variant ? String(query.variant) : undefined,
|
|
52
|
+
// Absent leaves the column default rather than writing 0, so a row the caller never
|
|
53
|
+
// ordered is indistinguishable from a legacy one.
|
|
54
|
+
sequence: query.sequence === undefined ? undefined : Number(query.sequence),
|
|
55
|
+
},
|
|
56
|
+
});
|
|
33
57
|
return created.data;
|
|
34
58
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const repository = await resolveValueAsync({ value: metaLink.repository });
|
|
66
|
-
const { mimetype, size, etag, isSynced } = buildStoredObjectFacts({
|
|
67
|
-
helper,
|
|
68
|
-
object,
|
|
69
|
-
link,
|
|
70
|
-
fileStat,
|
|
71
|
-
});
|
|
72
|
-
const statColumns = { mimetype, size, etag, isSynced };
|
|
73
|
-
const updated = await repository.updateAll({
|
|
74
|
-
data: metaLink.createMetaLink ? statColumns : { ...statColumns, link },
|
|
75
|
-
where: { bucketName: bucket.name, objectName: object.key },
|
|
76
|
-
});
|
|
77
|
-
const rows = updated.data ?? [];
|
|
78
|
-
if (metaLink.createMetaLink || !fileStat.metadata) {
|
|
79
|
-
return { count: updated.count, data: rows };
|
|
59
|
+
/**
|
|
60
|
+
* Rewrites the stored-object facts on every row of the pair. Rows per pair are deliberately not
|
|
61
|
+
* unique, and each keeps its own labels and storage type. A `createMetaLink` hook owns `link` and
|
|
62
|
+
* `metadata`, so with one only the stat columns change; without one, `metadata` is merged per row.
|
|
63
|
+
*/
|
|
64
|
+
static async refreshRows(opts) {
|
|
65
|
+
const { metaLink, helper, bucket, object, link, fileStat } = opts;
|
|
66
|
+
const repository = await ResolverUtility.resolveValueAsync({ value: metaLink.repository });
|
|
67
|
+
const { mimetype, size, etag, isSynced } = AssetMetaLink.buildStoredObjectFacts({
|
|
68
|
+
helper,
|
|
69
|
+
object,
|
|
70
|
+
link,
|
|
71
|
+
fileStat,
|
|
72
|
+
});
|
|
73
|
+
const statColumns = { mimetype, size, etag, isSynced };
|
|
74
|
+
const updated = await repository.updateAll({
|
|
75
|
+
data: metaLink.createMetaLink ? statColumns : { ...statColumns, link },
|
|
76
|
+
where: { bucketName: bucket.name, objectName: object.key },
|
|
77
|
+
});
|
|
78
|
+
const rows = updated.data ?? [];
|
|
79
|
+
if (metaLink.createMetaLink || !fileStat.metadata) {
|
|
80
|
+
return { count: updated.count, data: rows };
|
|
81
|
+
}
|
|
82
|
+
// One UPDATE per row: each merge starts from that row's own keys, which the statement above
|
|
83
|
+
// returned untouched and which no single engine-neutral statement over the pair can express.
|
|
84
|
+
const merged = await Promise.all(rows.map((row) => repository.updateById({
|
|
85
|
+
id: row.id,
|
|
86
|
+
data: { metadata: { ...row.metadata, ...fileStat.metadata } },
|
|
87
|
+
})));
|
|
88
|
+
return { count: updated.count, data: merged.map((result) => result.data) };
|
|
80
89
|
}
|
|
81
|
-
|
|
82
|
-
// returned untouched and which no single engine-neutral statement over the pair can express.
|
|
83
|
-
const merged = await Promise.all(rows.map((row) => repository.updateById({
|
|
84
|
-
id: row.id,
|
|
85
|
-
data: { metadata: { ...row.metadata, ...fileStat.metadata } },
|
|
86
|
-
})));
|
|
87
|
-
return { count: updated.count, data: merged.map((result) => result.data) };
|
|
88
|
-
};
|
|
90
|
+
}
|
|
89
91
|
//# sourceMappingURL=meta-link.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"meta-link.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/meta-link.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"meta-link.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/meta-link.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n IBucketRef,\n IFileStat,\n IObjectRef,\n IStorageHelper,\n IUploadResult,\n} from '@venizia/ignis-helpers';\nimport { ResolverUtility } from '@venizia/ignis-helpers/common';\nimport type { AnyType } from '@venizia/ignis-helpers/common';\nimport type { TMetaLinkConfig, TStaticAssetStorageType, TUploadQuery } from '../common';\n\nexport class AssetMetaLink {\n /** What a stat says about one stored object: the columns a refresh rewrites and a new row starts from. */\n private static buildStoredObjectFacts(opts: {\n helper: IStorageHelper;\n object: IObjectRef;\n link: string;\n fileStat: IFileStat;\n }) {\n const { helper, object, link, fileStat } = opts;\n\n return {\n link,\n // The column is NOT NULL and a backend may report nothing.\n mimetype: fileStat.metadata?.mimetype ?? helper.getMimeType({ filename: object.key }),\n size: fileStat.size,\n etag: fileStat.etag,\n metadata: fileStat.metadata,\n isSynced: true,\n };\n }\n\n /** The upload result of an object already in storage, so a commit or a recreate writes its row the way an upload does. */\n static buildStoredUploadResult(opts: {\n helper: IStorageHelper;\n bucket: IBucketRef;\n object: IObjectRef;\n link: string;\n fileStat: IFileStat;\n }): IUploadResult {\n const { helper, bucket, object, link, fileStat } = opts;\n\n return {\n bucket,\n object: {\n key: object.key,\n size: fileStat.size,\n contentType: fileStat.metadata?.mimetype ?? helper.getMimeType({ filename: object.key }),\n },\n link,\n };\n }\n\n /** The MetaLink row for one stored object. Every path that creates a row goes through here, so each lands exactly the row an ordinary upload does. */\n static async createRow(opts: {\n metaLink: TMetaLinkConfig<AnyType>;\n helper: IStorageHelper;\n storage: TStaticAssetStorageType;\n uploadResult: IUploadResult;\n fileStat: IFileStat;\n query: TUploadQuery;\n }): Promise<AnyType> {\n const { metaLink, helper, storage, uploadResult, fileStat, query } = opts;\n\n if (metaLink.createMetaLink) {\n const created = await metaLink.createMetaLink({ uploadResult, fileStat, query });\n return created.data;\n }\n\n // Resolved per call so an application that swaps the repository is not pinned to the first one.\n const repository = await ResolverUtility.resolveValueAsync({ value: metaLink.repository });\n const created = await repository.create({\n data: {\n bucketName: uploadResult.bucket.name,\n objectName: uploadResult.object.key,\n ...AssetMetaLink.buildStoredObjectFacts({\n helper,\n object: uploadResult.object,\n link: uploadResult.link,\n fileStat,\n }),\n storageType: storage,\n principalId: query.principalId ? String(query.principalId) : undefined,\n principalType: query.principalType ? String(query.principalType) : undefined,\n variant: query.variant ? String(query.variant) : undefined,\n // Absent leaves the column default rather than writing 0, so a row the caller never\n // ordered is indistinguishable from a legacy one.\n sequence: query.sequence === undefined ? undefined : Number(query.sequence),\n },\n });\n\n return created.data;\n }\n\n /**\n * Rewrites the stored-object facts on every row of the pair. Rows per pair are deliberately not\n * unique, and each keeps its own labels and storage type. A `createMetaLink` hook owns `link` and\n * `metadata`, so with one only the stat columns change; without one, `metadata` is merged per row.\n */\n static async refreshRows(opts: {\n metaLink: TMetaLinkConfig<AnyType>;\n helper: IStorageHelper;\n bucket: IBucketRef;\n object: IObjectRef;\n link: string;\n fileStat: IFileStat;\n }): Promise<{ count: number; data: AnyType[] }> {\n const { metaLink, helper, bucket, object, link, fileStat } = opts;\n\n const repository = await ResolverUtility.resolveValueAsync({ value: metaLink.repository });\n const { mimetype, size, etag, isSynced } = AssetMetaLink.buildStoredObjectFacts({\n helper,\n object,\n link,\n fileStat,\n });\n const statColumns = { mimetype, size, etag, isSynced };\n\n const updated = await repository.updateAll({\n data: metaLink.createMetaLink ? statColumns : { ...statColumns, link },\n where: { bucketName: bucket.name, objectName: object.key },\n });\n const rows = updated.data ?? [];\n\n if (metaLink.createMetaLink || !fileStat.metadata) {\n return { count: updated.count, data: rows };\n }\n\n // One UPDATE per row: each merge starts from that row's own keys, which the statement above\n // returned untouched and which no single engine-neutral statement over the pair can express.\n const merged = await Promise.all(\n rows.map((row) =>\n repository.updateById({\n id: row.id,\n data: { metadata: { ...row.metadata, ...fileStat.metadata } },\n }),\n ),\n );\n\n return { count: updated.count, data: merged.map((result) => result.data) };\n }\n}\n"]}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
1
|
import { type TStaticAssetRouteConfig } from '../common/index.js';
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
2
|
+
export declare class AssetRouteOptions {
|
|
3
|
+
/** Splits the `enabled` switch off the route config: it is this component's field, never a Hono one. */
|
|
4
|
+
static readOverride(opts: {
|
|
5
|
+
route?: TStaticAssetRouteConfig;
|
|
6
|
+
}): {
|
|
7
|
+
isEnabled: boolean;
|
|
8
|
+
override: Omit<TStaticAssetRouteConfig, 'enabled'>;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* The route's body validator reads the whole multipart body, so a declared length checked in the
|
|
12
|
+
* handler arrives too late to save any memory. Appended after the application's own middleware, so
|
|
13
|
+
* a check of its own still answers first.
|
|
14
|
+
*/
|
|
15
|
+
static appendLengthGuard(opts: {
|
|
16
|
+
middleware: TStaticAssetRouteConfig['middleware'];
|
|
17
|
+
maxBytes: number;
|
|
18
|
+
}): NonNullable<TStaticAssetRouteConfig['middleware']>;
|
|
19
|
+
}
|
|
18
20
|
//# sourceMappingURL=route-options.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-options.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/route-options.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAE5E,wGAAwG;
|
|
1
|
+
{"version":3,"file":"route-options.d.ts","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/route-options.ts"],"names":[],"mappings":"AAGA,OAAO,EAAqB,KAAK,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAE5E,qBAAa,iBAAiB;IAC5B,wGAAwG;IACxG,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE;QAAE,KAAK,CAAC,EAAE,uBAAuB,CAAA;KAAE,GAAG;QAC9D,SAAS,EAAE,OAAO,CAAC;QACnB,QAAQ,EAAE,IAAI,CAAC,uBAAuB,EAAE,SAAS,CAAC,CAAC;KACpD;IAKD;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAAI,EAAE;QAC7B,UAAU,EAAE,uBAAuB,CAAC,YAAY,CAAC,CAAC;QAClD,QAAQ,EAAE,MAAM,CAAC;KAClB,GAAG,WAAW,CAAC,uBAAuB,CAAC,YAAY,CAAC,CAAC;CAuBvD"}
|
|
@@ -1,32 +1,34 @@
|
|
|
1
1
|
import { HTTP } from '@venizia/ignis-helpers/common';
|
|
2
2
|
import { getError } from '@venizia/ignis-helpers/core';
|
|
3
3
|
import { StaticAssetErrors } from '../common/index.js';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
4
|
+
export class AssetRouteOptions {
|
|
5
|
+
/** Splits the `enabled` switch off the route config: it is this component's field, never a Hono one. */
|
|
6
|
+
static readOverride(opts) {
|
|
7
|
+
const { enabled, ...override } = opts.route ?? {};
|
|
8
|
+
return { isEnabled: enabled !== false, override };
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* The route's body validator reads the whole multipart body, so a declared length checked in the
|
|
12
|
+
* handler arrives too late to save any memory. Appended after the application's own middleware, so
|
|
13
|
+
* a check of its own still answers first.
|
|
14
|
+
*/
|
|
15
|
+
static appendLengthGuard(opts) {
|
|
16
|
+
const { middleware, maxBytes } = opts;
|
|
17
|
+
const guard = async (context, next) => {
|
|
18
|
+
const declaredLength = Number(context.req.header(HTTP.Headers.CONTENT_LENGTH));
|
|
19
|
+
// Not authoritative: a multipart envelope is larger than its files, so the per-file check in the handler decides.
|
|
20
|
+
if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {
|
|
21
|
+
throw getError({
|
|
22
|
+
error: StaticAssetErrors.UPLOAD_TOO_LARGE,
|
|
23
|
+
message: `Request body of ${declaredLength} bytes exceeds the maximum of ${maxBytes}`,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
await next();
|
|
27
|
+
};
|
|
28
|
+
if (!middleware) {
|
|
29
|
+
return [guard];
|
|
24
30
|
}
|
|
25
|
-
|
|
26
|
-
};
|
|
27
|
-
if (!middleware) {
|
|
28
|
-
return [guard];
|
|
31
|
+
return Array.isArray(middleware) ? [...middleware, guard] : [middleware, guard];
|
|
29
32
|
}
|
|
30
|
-
|
|
31
|
-
};
|
|
33
|
+
}
|
|
32
34
|
//# sourceMappingURL=route-options.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"route-options.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/route-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAgC,MAAM,WAAW,CAAC;AAE5E,wGAAwG;
|
|
1
|
+
{"version":3,"file":"route-options.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/controller/route-options.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,+BAA+B,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAEvD,OAAO,EAAE,iBAAiB,EAAgC,MAAM,WAAW,CAAC;AAE5E,MAAM,OAAO,iBAAiB;IAC5B,wGAAwG;IACxG,MAAM,CAAC,YAAY,CAAC,IAAyC;QAI3D,MAAM,EAAE,OAAO,EAAE,GAAG,QAAQ,EAAE,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAClD,OAAO,EAAE,SAAS,EAAE,OAAO,KAAK,KAAK,EAAE,QAAQ,EAAE,CAAC;IACpD,CAAC;IAED;;;;OAIG;IACH,MAAM,CAAC,iBAAiB,CAAC,IAGxB;QACC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;QAEtC,MAAM,KAAK,GAAsB,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE;YACvD,MAAM,cAAc,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC;YAE/E,kHAAkH;YAClH,IAAI,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,QAAQ,EAAE,CAAC;gBACjE,MAAM,QAAQ,CAAC;oBACb,KAAK,EAAE,iBAAiB,CAAC,gBAAgB;oBACzC,OAAO,EAAE,mBAAmB,cAAc,iCAAiC,QAAQ,EAAE;iBACtF,CAAC,CAAC;YACL,CAAC;YAED,MAAM,IAAI,EAAE,CAAC;QACf,CAAC,CAAC;QAEF,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,CAAC,KAAK,CAAC,CAAC;QACjB,CAAC;QAED,OAAO,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC;IAClF,CAAC;CACF","sourcesContent":["import { HTTP } from '@venizia/ignis-helpers/common';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport type { MiddlewareHandler } from 'hono';\nimport { StaticAssetErrors, type TStaticAssetRouteConfig } from '../common';\n\nexport class AssetRouteOptions {\n /** Splits the `enabled` switch off the route config: it is this component's field, never a Hono one. */\n static readOverride(opts: { route?: TStaticAssetRouteConfig }): {\n isEnabled: boolean;\n override: Omit<TStaticAssetRouteConfig, 'enabled'>;\n } {\n const { enabled, ...override } = opts.route ?? {};\n return { isEnabled: enabled !== false, override };\n }\n\n /**\n * The route's body validator reads the whole multipart body, so a declared length checked in the\n * handler arrives too late to save any memory. Appended after the application's own middleware, so\n * a check of its own still answers first.\n */\n static appendLengthGuard(opts: {\n middleware: TStaticAssetRouteConfig['middleware'];\n maxBytes: number;\n }): NonNullable<TStaticAssetRouteConfig['middleware']> {\n const { middleware, maxBytes } = opts;\n\n const guard: MiddlewareHandler = async (context, next) => {\n const declaredLength = Number(context.req.header(HTTP.Headers.CONTENT_LENGTH));\n\n // Not authoritative: a multipart envelope is larger than its files, so the per-file check in the handler decides.\n if (Number.isFinite(declaredLength) && declaredLength > maxBytes) {\n throw getError({\n error: StaticAssetErrors.UPLOAD_TOO_LARGE,\n message: `Request body of ${declaredLength} bytes exceeds the maximum of ${maxBytes}`,\n });\n }\n\n await next();\n };\n\n if (!middleware) {\n return [guard];\n }\n\n return Array.isArray(middleware) ? [...middleware, guard] : [middleware, guard];\n }\n}\n"]}
|
|
@@ -5,13 +5,13 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
|
|
|
5
5
|
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
6
|
};
|
|
7
7
|
import { model } from '../../../base/metadata/index.js';
|
|
8
|
-
import { BaseRelationalEntity,
|
|
8
|
+
import { BaseRelationalEntity, PostgresIdEnricher, PostgresTzEnricher, } from '@venizia/ignis-connectors/postgres';
|
|
9
9
|
import { boolean, index, integer, jsonb, pgTable, text } from 'drizzle-orm/pg-core';
|
|
10
10
|
/** One row per (object, owner) pairing, NOT per object: one product image attached to the product and to each variant is the common case, so `(bucketName, objectName)` is indexed and deliberately NOT unique. */
|
|
11
11
|
let BaseMetaLinkModel = class BaseMetaLinkModel extends BaseRelationalEntity {
|
|
12
12
|
static { this.schema = pgTable('MetaLink', {
|
|
13
|
-
...
|
|
14
|
-
...
|
|
13
|
+
...PostgresIdEnricher.generateColumnDefs({ id: { dataType: 'string' } }),
|
|
14
|
+
...PostgresTzEnricher.generateColumnDefs(),
|
|
15
15
|
bucketName: text('bucket_name').notNull(),
|
|
16
16
|
objectName: text('object_name').notNull(),
|
|
17
17
|
link: text().notNull(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.model.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/models/base.model.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,
|
|
1
|
+
{"version":3,"file":"base.model.js","sourceRoot":"","sources":["../../../../../src/components/static-asset/models/base.model.ts"],"names":[],"mappings":";;;;;;AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EACL,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,GAGnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,qBAAqB,CAAC;AAEpF,mNAAmN;AAE5M,IAAM,iBAAiB,GAAvB,MAAM,iBAAkB,SAAQ,oBAAqD;aAC1E,WAAM,GAAG,OAAO,CAC9B,UAAU,EACV;QACE,GAAG,kBAAkB,CAAC,kBAAkB,CAAC,EAAE,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,CAAC;QACxE,GAAG,kBAAkB,CAAC,kBAAkB,EAAE;QAC1C,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE;QACzC,UAAU,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,OAAO,EAAE;QACzC,IAAI,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE;QACtB,QAAQ,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE;QAC1B,IAAI,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE;QACzB,IAAI,EAAE,IAAI,EAAE;QACZ,QAAQ,EAAE,KAAK,EAAE,CAAC,KAAK,EAAuB;QAC9C,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC,OAAO,EAAE;QAC3C,QAAQ,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;QAEvD,+IAA+I;QAC/I,OAAO,EAAE,IAAI,EAAE;QAEf,qJAAqJ;QACrJ,QAAQ,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;QAExC,uKAAuK;QACvK,aAAa,EAAE,IAAI,CAAC,gBAAgB,CAAC;QACrC,WAAW,EAAE,IAAI,CAAC,cAAc,CAAC;KAClC,EACD,CAAC,GAAG,EAAE,EAAE,CAAC;QACP,KAAK,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,KAAK,CAAC,yBAAyB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC;QACnD,KAAK,CAAC,0BAA0B,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,CAAC;QACrD,KAAK,CAAC,uBAAuB,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC;QAC/C,8FAA8F;QAC9F,KAAK,CAAC,iCAAiC,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,aAAa,EAAE,GAAG,CAAC,WAAW,EAAE,GAAG,CAAC,QAAQ,CAAC;KAC9F,CACF,AAjCqB,CAiCpB;aAEc,cAAS,GAAG,GAAG,EAAE,CAAC,EAAE,AAAX,CAAY;;AApC1B,iBAAiB;IAD7B,KAAK,CAAC,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,CAAC;GACxB,iBAAiB,CAqC7B","sourcesContent":["import { model } from '@/base/metadata';\nimport {\n BaseRelationalEntity,\n PostgresIdEnricher,\n PostgresTzEnricher,\n type TTableObject,\n type TTableSchemaWithId,\n} from '@venizia/ignis-connectors/postgres';\nimport { boolean, index, integer, jsonb, pgTable, text } from 'drizzle-orm/pg-core';\n\n/** One row per (object, owner) pairing, NOT per object: one product image attached to the product and to each variant is the common case, so `(bucketName, objectName)` is indexed and deliberately NOT unique. */\n@model({ migration: { use: false } })\nexport class BaseMetaLinkModel extends BaseRelationalEntity<typeof BaseMetaLinkModel.schema> {\n static override schema = pgTable(\n 'MetaLink',\n {\n ...PostgresIdEnricher.generateColumnDefs({ id: { dataType: 'string' } }),\n ...PostgresTzEnricher.generateColumnDefs(),\n bucketName: text('bucket_name').notNull(),\n objectName: text('object_name').notNull(),\n link: text().notNull(),\n mimetype: text().notNull(),\n size: integer().notNull(),\n etag: text(),\n metadata: jsonb().$type<Record<string, any>>(),\n storageType: text('storage_type').notNull(),\n isSynced: boolean('is_synced').notNull().default(false),\n\n /** An opaque label the caller chooses - a size, a role, a rendition name. The component stores and returns it and reads no meaning into it. */\n variant: text(),\n\n /** Display order within ONE principal. Defaults to 0 so legacy rows tie and `ORDER BY sequence, createdAt` reproduces the order they already had. */\n sequence: integer().notNull().default(0),\n\n /** A polymorphic owner: the type names the table, the id the row. Both nullable - an object may belong to nothing yet, which is how `recreate-metalink` writes one. */\n principalType: text('principal_type'),\n principalId: text('principal_id'),\n },\n (def) => [\n index(`IDX_MetaLink_bucketName`).on(def.bucketName),\n index(`IDX_MetaLink_objectName`).on(def.objectName),\n index(`IDX_MetaLink_storageType`).on(def.storageType),\n index(`IDX_MetaLink_isSynced`).on(def.isSynced),\n // Ordering runs inside a principal filter, so filter columns lead and the sort column trails.\n index(`IDX_MetaLink_principal_sequence`).on(def.principalType, def.principalId, def.sequence),\n ],\n );\n\n static override relations = () => [];\n}\n\nexport type TMetaLinkSchema = typeof BaseMetaLinkModel.schema;\nexport type TMetaLink = TTableObject<TMetaLinkSchema>;\n\n/** Any table whose row carries the MetaLink fields. The component reads and writes the ROW, so the table is free to carry another name or to live in another Postgres schema. */\nexport type TMetaLinkCompatibleSchema = TTableSchemaWithId & { $inferSelect: TMetaLink };\n"]}
|
|
@@ -19,7 +19,7 @@ import { getError } from '@venizia/ignis-helpers/core';
|
|
|
19
19
|
import { HTTP } from '@venizia/ignis-helpers/common';
|
|
20
20
|
import { isRedisHelper, WebSocketDefaults, WebSocketServerHelper, } from '@venizia/ignis-helpers';
|
|
21
21
|
import { WebSocketBindingKeys, DEFAULT_SERVER_OPTIONS, } from './common/index.js';
|
|
22
|
-
import {
|
|
22
|
+
import { WebSocketBunHandler } from './handlers/index.js';
|
|
23
23
|
let WebSocketComponent = WebSocketComponent_1 = class WebSocketComponent extends BaseComponent {
|
|
24
24
|
constructor(application) {
|
|
25
25
|
super({
|
|
@@ -144,7 +144,7 @@ let WebSocketComponent = WebSocketComponent_1 = class WebSocketComponent extends
|
|
|
144
144
|
this.application.bind({ key: WebSocketBindingKeys.WEBSOCKET_INSTANCE }).toValue(wsHelper);
|
|
145
145
|
const wsPath = serverOptions.path ?? WebSocketDefaults.PATH;
|
|
146
146
|
serverInstance.reload({
|
|
147
|
-
fetch:
|
|
147
|
+
fetch: WebSocketBunHandler.createFetchHandler({ wsPath, honoServer }),
|
|
148
148
|
websocket: wsHelper.getBunWebSocketHandler(),
|
|
149
149
|
});
|
|
150
150
|
logger.info('WebSocket initialized for Bun runtime');
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/components/websocket/component.ts"],"names":[],"mappings":"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","sourcesContent":["import { type BaseApplication, type TBunServerInstance } from '@/base/applications';\nimport { BaseComponent } from '@venizia/ignis-kernel';\nimport { inject } from '@/base/metadata';\nimport { CoreBindings } from '@venizia/ignis-kernel';\nimport { Binding } from '@venizia/ignis-kernel';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { HTTP, type ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport {\n type AbstractRedisHelper,\n isRedisHelper,\n type TWebSocketAuthenticateFn,\n type TWebSocketClientConnectedFn,\n type TWebSocketClientDisconnectedFn,\n type TWebSocketMessageHandler,\n type TWebSocketHandshakeFn,\n type TWebSocketOutboundTransformer,\n type TWebSocketValidateRoomFn,\n WebSocketDefaults,\n WebSocketServerHelper,\n} from '@venizia/ignis-helpers';\nimport {\n WebSocketBindingKeys,\n DEFAULT_SERVER_OPTIONS,\n type IResolvedBindings,\n type IServerOptions,\n} from './common';\nimport { createBunFetchHandler } from './handlers';\n\nexport class WebSocketComponent extends BaseComponent {\n protected serverOptions: IServerOptions;\n\n constructor(\n @inject({ key: CoreBindings.APPLICATION_INSTANCE }) private application: BaseApplication,\n ) {\n super({\n scope: WebSocketComponent.name,\n initDefault: { enable: true, container: application },\n bindings: {\n [WebSocketBindingKeys.SERVER_OPTIONS]: Binding.bind<Partial<IServerOptions>>({\n key: WebSocketBindingKeys.SERVER_OPTIONS,\n }).toValue(DEFAULT_SERVER_OPTIONS),\n\n [WebSocketBindingKeys.REDIS_CONNECTION]: Binding.bind<AbstractRedisHelper | null>({\n key: WebSocketBindingKeys.REDIS_CONNECTION,\n }).toValue(null),\n\n [WebSocketBindingKeys.AUTHENTICATE_HANDLER]: Binding.bind<TWebSocketAuthenticateFn | null>({\n key: WebSocketBindingKeys.AUTHENTICATE_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.VALIDATE_ROOM_HANDLER]: Binding.bind<TWebSocketValidateRoomFn | null>(\n {\n key: WebSocketBindingKeys.VALIDATE_ROOM_HANDLER,\n },\n ).toValue(null),\n\n [WebSocketBindingKeys.CLIENT_CONNECTED_HANDLER]:\n Binding.bind<TWebSocketClientConnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_CONNECTED_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.CLIENT_DISCONNECTED_HANDLER]:\n Binding.bind<TWebSocketClientDisconnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_DISCONNECTED_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.MESSAGE_HANDLER]: Binding.bind<TWebSocketMessageHandler | null>({\n key: WebSocketBindingKeys.MESSAGE_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.OUTBOUND_TRANSFORMER]:\n Binding.bind<TWebSocketOutboundTransformer | null>({\n key: WebSocketBindingKeys.OUTBOUND_TRANSFORMER,\n }).toValue(null),\n\n [WebSocketBindingKeys.HANDSHAKE_HANDLER]: Binding.bind<TWebSocketHandshakeFn | null>({\n key: WebSocketBindingKeys.HANDSHAKE_HANDLER,\n }).toValue(null),\n },\n });\n }\n\n private resolveBindings(): IResolvedBindings {\n const extraServerOptions =\n this.application.get<Partial<IServerOptions>>({\n key: WebSocketBindingKeys.SERVER_OPTIONS,\n isOptional: true,\n }) ?? {};\n this.serverOptions = Object.assign({}, DEFAULT_SERVER_OPTIONS, extraServerOptions);\n\n const redisConnection = this.application.get<AbstractRedisHelper>({\n key: WebSocketBindingKeys.REDIS_CONNECTION,\n });\n if (!isRedisHelper(redisConnection)) {\n throw getError({\n message:\n '[WebSocketComponent][resolveBindings] Invalid instance of redisConnection | Please init connection with RedisSingleHelper (single), RedisClusterHelper (cluster), or RedisSentinelHelper (sentinel)!',\n });\n }\n\n const authenticateFn = this.application.get<TWebSocketAuthenticateFn>({\n key: WebSocketBindingKeys.AUTHENTICATE_HANDLER,\n });\n if (!authenticateFn) {\n throw getError({\n message: '[WebSocketComponent] Invalid authenticateFn to setup WebSocket server!',\n });\n }\n\n const validateRoomFn =\n this.application.get<TWebSocketValidateRoomFn | null>({\n key: WebSocketBindingKeys.VALIDATE_ROOM_HANDLER,\n }) ?? undefined;\n const clientConnectedFn =\n this.application.get<TWebSocketClientConnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_CONNECTED_HANDLER,\n }) ?? undefined;\n const clientDisconnectedFn =\n this.application.get<TWebSocketClientDisconnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_DISCONNECTED_HANDLER,\n }) ?? undefined;\n const messageHandler =\n this.application.get<TWebSocketMessageHandler | null>({\n key: WebSocketBindingKeys.MESSAGE_HANDLER,\n }) ?? undefined;\n const outboundTransformer =\n this.application.get<TWebSocketOutboundTransformer | null>({\n key: WebSocketBindingKeys.OUTBOUND_TRANSFORMER,\n }) ?? undefined;\n const handshakeFn =\n this.application.get<TWebSocketHandshakeFn | null>({\n key: WebSocketBindingKeys.HANDSHAKE_HANDLER,\n }) ?? undefined;\n\n return {\n redisConnection,\n authenticateFn,\n validateRoomFn,\n clientConnectedFn,\n clientDisconnectedFn,\n messageHandler,\n outboundTransformer,\n handshakeFn,\n };\n }\n\n private registerBunHook(opts: IResolvedBindings) {\n const {\n redisConnection,\n authenticateFn,\n validateRoomFn,\n clientConnectedFn,\n clientDisconnectedFn,\n messageHandler,\n outboundTransformer,\n handshakeFn,\n } = opts;\n const serverOptions = this.serverOptions;\n\n const logger = this.logger.for(this.registerBunHook.name);\n\n this.application.registerPostStartHook({\n identifier: 'websocket-initialize',\n hook: async () => {\n const serverInstance = this.application.getServerInstance<TBunServerInstance>();\n const honoServer = this.application.getServer();\n\n if (!serverInstance) {\n throw getError({\n message: '[WebSocketComponent] Bun server instance not available!',\n });\n }\n\n const wsHelper = new WebSocketServerHelper({\n identifier: serverOptions.identifier,\n path: serverOptions.path,\n defaultRooms: serverOptions.defaultRooms,\n serverOptions: serverOptions.serverOptions,\n heartbeatInterval: serverOptions.heartbeatInterval,\n heartbeatTimeout: serverOptions.heartbeatTimeout,\n server: serverInstance,\n redisConnection,\n authenticateFn,\n validateRoomFn,\n clientConnectedFn,\n clientDisconnectedFn,\n messageHandler,\n outboundTransformer,\n handshakeFn,\n requireEncryption: serverOptions.requireEncryption,\n });\n await wsHelper.configure();\n\n this.application.bind({ key: WebSocketBindingKeys.WEBSOCKET_INSTANCE }).toValue(wsHelper);\n\n const wsPath = serverOptions.path ?? WebSocketDefaults.PATH;\n\n serverInstance.reload({\n fetch: createBunFetchHandler({ wsPath, honoServer }),\n websocket: wsHelper.getBunWebSocketHandler(),\n });\n\n logger.info('WebSocket initialized for Bun runtime');\n },\n });\n }\n\n override binding(): ValueOrPromise<void> {\n const logger = this.logger.for(this.binding.name);\n\n if (!this.application) {\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: '[binding] Invalid application to bind WebSocketComponent',\n });\n }\n\n logger.info('Binding WebSocket for application...');\n\n const resolved = this.resolveBindings();\n logger.debug('WebSocket Server Options: %j', this.serverOptions);\n\n this.registerBunHook(resolved);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"component.js","sourceRoot":"","sources":["../../../../src/components/websocket/component.ts"],"names":[],"mappings":"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","sourcesContent":["import { type BaseApplication, type TBunServerInstance } from '@/base/applications';\nimport { BaseComponent } from '@venizia/ignis-kernel';\nimport { inject } from '@/base/metadata';\nimport { CoreBindings } from '@venizia/ignis-kernel';\nimport { Binding } from '@venizia/ignis-kernel';\nimport { getError } from '@venizia/ignis-helpers/core';\nimport { HTTP, type ValueOrPromise } from '@venizia/ignis-helpers/common';\nimport {\n type AbstractRedisHelper,\n isRedisHelper,\n type TWebSocketAuthenticateFn,\n type TWebSocketClientConnectedFn,\n type TWebSocketClientDisconnectedFn,\n type TWebSocketMessageHandler,\n type TWebSocketHandshakeFn,\n type TWebSocketOutboundTransformer,\n type TWebSocketValidateRoomFn,\n WebSocketDefaults,\n WebSocketServerHelper,\n} from '@venizia/ignis-helpers';\nimport {\n WebSocketBindingKeys,\n DEFAULT_SERVER_OPTIONS,\n type IResolvedBindings,\n type IServerOptions,\n} from './common';\nimport { WebSocketBunHandler } from './handlers';\n\nexport class WebSocketComponent extends BaseComponent {\n protected serverOptions: IServerOptions;\n\n constructor(\n @inject({ key: CoreBindings.APPLICATION_INSTANCE }) private application: BaseApplication,\n ) {\n super({\n scope: WebSocketComponent.name,\n initDefault: { enable: true, container: application },\n bindings: {\n [WebSocketBindingKeys.SERVER_OPTIONS]: Binding.bind<Partial<IServerOptions>>({\n key: WebSocketBindingKeys.SERVER_OPTIONS,\n }).toValue(DEFAULT_SERVER_OPTIONS),\n\n [WebSocketBindingKeys.REDIS_CONNECTION]: Binding.bind<AbstractRedisHelper | null>({\n key: WebSocketBindingKeys.REDIS_CONNECTION,\n }).toValue(null),\n\n [WebSocketBindingKeys.AUTHENTICATE_HANDLER]: Binding.bind<TWebSocketAuthenticateFn | null>({\n key: WebSocketBindingKeys.AUTHENTICATE_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.VALIDATE_ROOM_HANDLER]: Binding.bind<TWebSocketValidateRoomFn | null>(\n {\n key: WebSocketBindingKeys.VALIDATE_ROOM_HANDLER,\n },\n ).toValue(null),\n\n [WebSocketBindingKeys.CLIENT_CONNECTED_HANDLER]:\n Binding.bind<TWebSocketClientConnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_CONNECTED_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.CLIENT_DISCONNECTED_HANDLER]:\n Binding.bind<TWebSocketClientDisconnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_DISCONNECTED_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.MESSAGE_HANDLER]: Binding.bind<TWebSocketMessageHandler | null>({\n key: WebSocketBindingKeys.MESSAGE_HANDLER,\n }).toValue(null),\n\n [WebSocketBindingKeys.OUTBOUND_TRANSFORMER]:\n Binding.bind<TWebSocketOutboundTransformer | null>({\n key: WebSocketBindingKeys.OUTBOUND_TRANSFORMER,\n }).toValue(null),\n\n [WebSocketBindingKeys.HANDSHAKE_HANDLER]: Binding.bind<TWebSocketHandshakeFn | null>({\n key: WebSocketBindingKeys.HANDSHAKE_HANDLER,\n }).toValue(null),\n },\n });\n }\n\n private resolveBindings(): IResolvedBindings {\n const extraServerOptions =\n this.application.get<Partial<IServerOptions>>({\n key: WebSocketBindingKeys.SERVER_OPTIONS,\n isOptional: true,\n }) ?? {};\n this.serverOptions = Object.assign({}, DEFAULT_SERVER_OPTIONS, extraServerOptions);\n\n const redisConnection = this.application.get<AbstractRedisHelper>({\n key: WebSocketBindingKeys.REDIS_CONNECTION,\n });\n if (!isRedisHelper(redisConnection)) {\n throw getError({\n message:\n '[WebSocketComponent][resolveBindings] Invalid instance of redisConnection | Please init connection with RedisSingleHelper (single), RedisClusterHelper (cluster), or RedisSentinelHelper (sentinel)!',\n });\n }\n\n const authenticateFn = this.application.get<TWebSocketAuthenticateFn>({\n key: WebSocketBindingKeys.AUTHENTICATE_HANDLER,\n });\n if (!authenticateFn) {\n throw getError({\n message: '[WebSocketComponent] Invalid authenticateFn to setup WebSocket server!',\n });\n }\n\n const validateRoomFn =\n this.application.get<TWebSocketValidateRoomFn | null>({\n key: WebSocketBindingKeys.VALIDATE_ROOM_HANDLER,\n }) ?? undefined;\n const clientConnectedFn =\n this.application.get<TWebSocketClientConnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_CONNECTED_HANDLER,\n }) ?? undefined;\n const clientDisconnectedFn =\n this.application.get<TWebSocketClientDisconnectedFn | null>({\n key: WebSocketBindingKeys.CLIENT_DISCONNECTED_HANDLER,\n }) ?? undefined;\n const messageHandler =\n this.application.get<TWebSocketMessageHandler | null>({\n key: WebSocketBindingKeys.MESSAGE_HANDLER,\n }) ?? undefined;\n const outboundTransformer =\n this.application.get<TWebSocketOutboundTransformer | null>({\n key: WebSocketBindingKeys.OUTBOUND_TRANSFORMER,\n }) ?? undefined;\n const handshakeFn =\n this.application.get<TWebSocketHandshakeFn | null>({\n key: WebSocketBindingKeys.HANDSHAKE_HANDLER,\n }) ?? undefined;\n\n return {\n redisConnection,\n authenticateFn,\n validateRoomFn,\n clientConnectedFn,\n clientDisconnectedFn,\n messageHandler,\n outboundTransformer,\n handshakeFn,\n };\n }\n\n private registerBunHook(opts: IResolvedBindings) {\n const {\n redisConnection,\n authenticateFn,\n validateRoomFn,\n clientConnectedFn,\n clientDisconnectedFn,\n messageHandler,\n outboundTransformer,\n handshakeFn,\n } = opts;\n const serverOptions = this.serverOptions;\n\n const logger = this.logger.for(this.registerBunHook.name);\n\n this.application.registerPostStartHook({\n identifier: 'websocket-initialize',\n hook: async () => {\n const serverInstance = this.application.getServerInstance<TBunServerInstance>();\n const honoServer = this.application.getServer();\n\n if (!serverInstance) {\n throw getError({\n message: '[WebSocketComponent] Bun server instance not available!',\n });\n }\n\n const wsHelper = new WebSocketServerHelper({\n identifier: serverOptions.identifier,\n path: serverOptions.path,\n defaultRooms: serverOptions.defaultRooms,\n serverOptions: serverOptions.serverOptions,\n heartbeatInterval: serverOptions.heartbeatInterval,\n heartbeatTimeout: serverOptions.heartbeatTimeout,\n server: serverInstance,\n redisConnection,\n authenticateFn,\n validateRoomFn,\n clientConnectedFn,\n clientDisconnectedFn,\n messageHandler,\n outboundTransformer,\n handshakeFn,\n requireEncryption: serverOptions.requireEncryption,\n });\n await wsHelper.configure();\n\n this.application.bind({ key: WebSocketBindingKeys.WEBSOCKET_INSTANCE }).toValue(wsHelper);\n\n const wsPath = serverOptions.path ?? WebSocketDefaults.PATH;\n\n serverInstance.reload({\n fetch: WebSocketBunHandler.createFetchHandler({ wsPath, honoServer }),\n websocket: wsHelper.getBunWebSocketHandler(),\n });\n\n logger.info('WebSocket initialized for Bun runtime');\n },\n });\n }\n\n override binding(): ValueOrPromise<void> {\n const logger = this.logger.for(this.binding.name);\n\n if (!this.application) {\n throw getError({\n statusCode: HTTP.ResultCodes.RS_5.InternalServerError,\n message: '[binding] Invalid application to bind WebSocketComponent',\n });\n }\n\n logger.info('Binding WebSocket for application...');\n\n const resolved = this.resolveBindings();\n logger.debug('WebSocket Server Options: %j', this.serverOptions);\n\n this.registerBunHook(resolved);\n }\n}\n"]}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { TBunServerInstance } from '../../../base/applications/index.js';
|
|
2
2
|
import type { OpenAPIHono } from '@hono/zod-openapi';
|
|
3
|
-
export declare
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export declare class WebSocketBunHandler {
|
|
4
|
+
static createFetchHandler(opts: {
|
|
5
|
+
wsPath: string;
|
|
6
|
+
honoServer: OpenAPIHono;
|
|
7
|
+
}): (req: Request, server: TBunServerInstance) => Promise<Response | undefined>;
|
|
8
|
+
}
|
|
7
9
|
//# sourceMappingURL=bun.handler.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bun.handler.d.ts","sourceRoot":"","sources":["../../../../../src/components/websocket/handlers/bun.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,
|
|
1
|
+
{"version":3,"file":"bun.handler.d.ts","sourceRoot":"","sources":["../../../../../src/components/websocket/handlers/bun.handler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAE9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,qBAAa,mBAAmB;IAC9B,MAAM,CAAC,kBAAkB,CAAC,IAAI,EAAE;QAC9B,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,WAAW,CAAC;KACzB,GAAG,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,QAAQ,GAAG,SAAS,CAAC;CA0BhF"}
|