@byline/core 4.16.0 → 4.17.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/dist/@types/admin-types.d.ts +86 -31
  2. package/dist/@types/admin-types.js +12 -0
  3. package/dist/@types/collection-types.d.ts +211 -29
  4. package/dist/@types/collection-types.js +68 -8
  5. package/dist/@types/db-types.d.ts +50 -0
  6. package/dist/@types/form-admin-config.test.node.d.ts +6 -0
  7. package/dist/@types/form-admin-config.test.node.js +26 -0
  8. package/dist/@types/singleton-admin-config.test.node.js +66 -0
  9. package/dist/@types/singleton-definition.test.node.d.ts +8 -0
  10. package/dist/@types/singleton-definition.test.node.js +75 -0
  11. package/dist/@types/site-config.d.ts +9 -8
  12. package/dist/auth/apply-before-read.d.ts +2 -1
  13. package/dist/auth/apply-before-read.js +13 -3
  14. package/dist/auth/apply-before-read.test.node.js +44 -0
  15. package/dist/auth/assert-actor-can-perform.d.ts +4 -3
  16. package/dist/auth/assert-actor-can-perform.js +9 -7
  17. package/dist/auth/assert-actor-can-perform.test.node.js +32 -11
  18. package/dist/auth/filter-readable-collections.d.ts +6 -6
  19. package/dist/auth/filter-readable-collections.js +8 -8
  20. package/dist/auth/filter-readable-collections.test.node.js +26 -1
  21. package/dist/auth/index.d.ts +1 -1
  22. package/dist/auth/index.js +1 -1
  23. package/dist/auth/register-collection-abilities.d.ts +34 -30
  24. package/dist/auth/register-collection-abilities.js +81 -77
  25. package/dist/auth/register-collection-abilities.test.node.js +86 -8
  26. package/dist/codegen/fixtures/all-fields.expected.d.ts +3 -0
  27. package/dist/codegen/index.d.ts +1 -1
  28. package/dist/codegen/index.js +32 -16
  29. package/dist/codegen/index.test.node.js +35 -2
  30. package/dist/config/attach-hooks.d.ts +3 -3
  31. package/dist/config/attach-hooks.js +8 -0
  32. package/dist/config/attach-hooks.test.node.js +59 -0
  33. package/dist/config/config-hooks.test.node.js +34 -1
  34. package/dist/config/config.d.ts +2 -1
  35. package/dist/config/config.js +9 -1
  36. package/dist/config/group-collections.d.ts +10 -9
  37. package/dist/config/group-collections.js +4 -4
  38. package/dist/config/group-collections.test.node.js +14 -0
  39. package/dist/config/validate-admin-configs.d.ts +4 -4
  40. package/dist/config/validate-admin-configs.js +40 -7
  41. package/dist/config/validate-admin-configs.test.node.js +44 -0
  42. package/dist/config/validate-collections.js +43 -0
  43. package/dist/config/validate-collections.test.node.js +75 -0
  44. package/dist/core.d.ts +2 -3
  45. package/dist/core.js +3 -3
  46. package/dist/index.d.ts +2 -2
  47. package/dist/index.js +2 -2
  48. package/dist/lib/errors.d.ts +5 -3
  49. package/dist/lib/errors.js +1 -0
  50. package/dist/services/collection-bootstrap.js +12 -0
  51. package/dist/services/collection-bootstrap.test.node.js +63 -6
  52. package/dist/services/discover-counter-groups.test.node.js +6 -0
  53. package/dist/services/document-lifecycle/copy-to-locale.js +9 -17
  54. package/dist/services/document-lifecycle/create.js +6 -11
  55. package/dist/services/document-lifecycle/delete-locale.js +1 -1
  56. package/dist/services/document-lifecycle/delete.js +1 -1
  57. package/dist/services/document-lifecycle/duplicate.js +7 -18
  58. package/dist/services/document-lifecycle/persistence.d.ts +29 -0
  59. package/dist/services/document-lifecycle/persistence.js +42 -0
  60. package/dist/services/document-lifecycle/restore.js +9 -17
  61. package/dist/services/document-lifecycle/scheduled-publish.js +5 -5
  62. package/dist/services/document-lifecycle/status.js +3 -3
  63. package/dist/services/document-lifecycle/system-fields.js +1 -1
  64. package/dist/services/document-lifecycle/tree.js +2 -2
  65. package/dist/services/document-lifecycle/tree.test.node.js +6 -1
  66. package/dist/services/document-lifecycle/update.js +20 -36
  67. package/dist/services/document-lifecycle.test.node.js +35 -0
  68. package/dist/services/field-upload.d.ts +1 -1
  69. package/dist/services/field-upload.js +20 -6
  70. package/dist/services/field-upload.test.node.js +125 -9
  71. package/dist/services/index.d.ts +1 -0
  72. package/dist/services/index.js +1 -0
  73. package/dist/services/populate.js +1 -1
  74. package/dist/services/populate.test.node.js +9 -0
  75. package/dist/services/richtext-populate.js +1 -1
  76. package/dist/services/singleton-lifecycle/copy-to-locale.d.ts +16 -0
  77. package/dist/services/singleton-lifecycle/copy-to-locale.js +100 -0
  78. package/dist/services/singleton-lifecycle/index.d.ts +14 -0
  79. package/dist/services/singleton-lifecycle/index.js +11 -0
  80. package/dist/services/singleton-lifecycle/internals.d.ts +49 -0
  81. package/dist/services/singleton-lifecycle/internals.js +118 -0
  82. package/dist/services/singleton-lifecycle/restore.d.ts +13 -0
  83. package/dist/services/singleton-lifecycle/restore.js +93 -0
  84. package/dist/services/singleton-lifecycle/update.d.ts +16 -0
  85. package/dist/services/singleton-lifecycle/update.js +107 -0
  86. package/dist/services/singleton-lifecycle.test.node.d.ts +8 -0
  87. package/dist/services/singleton-lifecycle.test.node.js +396 -0
  88. package/dist/storage/collection-fingerprint.js +18 -6
  89. package/dist/storage/collection-fingerprint.test.node.js +15 -0
  90. package/package.json +5 -5
  91. package/dist/config/resolve-item-view-columns.test.node.js +0 -30
  92. /package/dist/{config/resolve-item-view-columns.test.node.d.ts → @types/singleton-admin-config.test.node.d.ts} +0 -0
@@ -0,0 +1,49 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { IDocumentCommands, IDocumentQueries, SingletonDefinition, SingletonSaveOperation } from '../../@types/index.js';
9
+ import type { DocumentLifecycleContext } from '../document-lifecycle/context.js';
10
+ type VersionWriteResult = Awaited<ReturnType<IDocumentCommands['createDocumentVersion']>>;
11
+ type CurrentVersionMetadata = NonNullable<Awaited<ReturnType<IDocumentQueries['getCurrentVersionMetadata']>>>;
12
+ export interface SingletonSaveResult {
13
+ documentId: string;
14
+ documentVersionId: string;
15
+ }
16
+ export interface LockedSingletonSlot {
17
+ documentId: string | null;
18
+ currentVersion: CurrentVersionMetadata | null;
19
+ }
20
+ interface PreparedSingletonSave {
21
+ data: Record<string, any>;
22
+ originalData: Record<string, any> | null;
23
+ locale: string;
24
+ write: () => Promise<VersionWriteResult>;
25
+ }
26
+ /**
27
+ * Assert the kind-aware singleton update ability without touching storage.
28
+ * The runtime kind guard keeps this internal service from becoming an
29
+ * alternate write path for an ordinary collection.
30
+ */
31
+ export declare function authorizeSingletonUpdate(ctx: DocumentLifecycleContext): SingletonDefinition;
32
+ /**
33
+ * Resolve the mapped logical document id without running read authorization
34
+ * or hooks. Client-facing callers must authorize before invoking this resolver.
35
+ */
36
+ export declare function resolveSingletonDocumentId(ctx: DocumentLifecycleContext): Promise<string | null>;
37
+ /**
38
+ * Coordinate one singleton version write under the registered-slot lock.
39
+ * `prepare` runs after the mapping and current version have been read while
40
+ * locked. The before hook and write remain inside the outer transaction; the
41
+ * after hook cannot run until that transaction has committed.
42
+ */
43
+ export declare function commitSingletonSave(params: {
44
+ ctx: DocumentLifecycleContext;
45
+ definition: SingletonDefinition;
46
+ operation: SingletonSaveOperation;
47
+ prepare: (slot: LockedSingletonSlot) => Promise<PreparedSingletonSave>;
48
+ }): Promise<SingletonSaveResult>;
49
+ export {};
@@ -0,0 +1,118 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { resolveHooks } from '../../@types/index.js';
9
+ import { assertActorCanPerform } from '../../auth/assert-actor-can-perform.js';
10
+ import { DbErrorCodes, ERR_CONFLICT, ERR_VALIDATION } from '../../lib/errors.js';
11
+ import { extractDocumentId, extractVersionId } from '../document-lifecycle/internals.js';
12
+ /**
13
+ * Assert the kind-aware singleton update ability without touching storage.
14
+ * The runtime kind guard keeps this internal service from becoming an
15
+ * alternate write path for an ordinary collection.
16
+ */
17
+ export function authorizeSingletonUpdate(ctx) {
18
+ if (ctx.definition.singleton !== true) {
19
+ throw ERR_VALIDATION({
20
+ message: `singleton lifecycle requires a singleton definition; '${ctx.collectionPath}' is a collection`,
21
+ details: { path: ctx.collectionPath, expectedKind: 'singleton' },
22
+ }).log(ctx.logger);
23
+ }
24
+ assertActorCanPerform(ctx.requestContext, ctx.definition, 'update');
25
+ return ctx.definition;
26
+ }
27
+ /**
28
+ * Resolve the mapped logical document id without running read authorization
29
+ * or hooks. Client-facing callers must authorize before invoking this resolver.
30
+ */
31
+ export function resolveSingletonDocumentId(ctx) {
32
+ return ctx.db.queries.singletons.getMappedDocumentId(ctx.collectionId);
33
+ }
34
+ /**
35
+ * Coordinate one singleton version write under the registered-slot lock.
36
+ * `prepare` runs after the mapping and current version have been read while
37
+ * locked. The before hook and write remain inside the outer transaction; the
38
+ * after hook cannot run until that transaction has committed.
39
+ */
40
+ export async function commitSingletonSave(params) {
41
+ const { ctx, definition, operation } = params;
42
+ const hooks = await resolveHooks(definition);
43
+ const requestContext = ctx.requestContext;
44
+ if (requestContext == null) {
45
+ throw new Error('singleton authorization completed without a request context');
46
+ }
47
+ const committed = await ctx.db.withTransaction(async () => {
48
+ await ctx.db.commands.singletons.lockSlot(ctx.collectionId);
49
+ const mappedDocumentId = await resolveSingletonDocumentId(ctx);
50
+ const currentVersion = mappedDocumentId == null
51
+ ? null
52
+ : await ctx.db.queries.documents.getCurrentVersionMetadata({
53
+ collection_id: ctx.collectionId,
54
+ document_id: mappedDocumentId,
55
+ });
56
+ if (mappedDocumentId != null && currentVersion == null) {
57
+ throw ERR_CONFLICT({
58
+ message: `singleton '${ctx.collectionPath}' is mapped to a deleted or unavailable document; ` +
59
+ 'clear the mapping deliberately before rematerialising the slot',
60
+ details: { singletonPath: ctx.collectionPath, documentId: mappedDocumentId },
61
+ }).log(ctx.logger);
62
+ }
63
+ const slot = { documentId: mappedDocumentId, currentVersion };
64
+ const prepared = await params.prepare(slot);
65
+ const isInitialSave = mappedDocumentId == null;
66
+ const beforeSaveContext = {
67
+ data: prepared.data,
68
+ originalData: prepared.originalData,
69
+ singletonPath: ctx.collectionPath,
70
+ locale: prepared.locale,
71
+ requestContext,
72
+ isInitialSave,
73
+ operation,
74
+ documentId: mappedDocumentId,
75
+ };
76
+ await invokeSingletonHook(hooks?.beforeSave, beforeSaveContext);
77
+ const writeResult = await prepared.write();
78
+ const documentId = extractDocumentId(writeResult.document) || mappedDocumentId || '';
79
+ const documentVersionId = extractVersionId(writeResult.document);
80
+ if (documentId === '' || documentVersionId === '') {
81
+ throw new Error('singleton persistence did not return document and version ids');
82
+ }
83
+ if (isInitialSave) {
84
+ try {
85
+ await ctx.db.commands.singletons.setMapping(ctx.collectionId, documentId);
86
+ }
87
+ catch (error) {
88
+ if (ctx.db.classifyError?.(error)?.code === DbErrorCodes.UNIQUE_VIOLATION) {
89
+ throw ERR_CONFLICT({
90
+ message: `singleton '${ctx.collectionPath}' was materialised concurrently`,
91
+ details: { singletonPath: ctx.collectionPath },
92
+ }).log(ctx.logger);
93
+ }
94
+ throw error;
95
+ }
96
+ }
97
+ return {
98
+ documentId,
99
+ documentVersionId,
100
+ afterSaveContext: {
101
+ ...beforeSaveContext,
102
+ documentId,
103
+ documentVersionId,
104
+ },
105
+ };
106
+ });
107
+ await invokeSingletonHook(hooks?.afterSave, committed.afterSaveContext);
108
+ return {
109
+ documentId: committed.documentId,
110
+ documentVersionId: committed.documentVersionId,
111
+ };
112
+ }
113
+ async function invokeSingletonHook(hook, context) {
114
+ const hooks = hook == null ? [] : Array.isArray(hook) ? hook : [hook];
115
+ for (const invoke of hooks) {
116
+ await invoke(context);
117
+ }
118
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { DocumentLifecycleContext } from '../document-lifecycle/context.js';
9
+ import type { SingletonSaveResult } from './internals.js';
10
+ /** Restore one historical singleton version as the new current version. */
11
+ export declare function restoreSingletonVersion(ctx: DocumentLifecycleContext, params: {
12
+ sourceVersionId: string;
13
+ }): Promise<SingletonSaveResult>;
@@ -0,0 +1,93 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { ERR_INVALID_TRANSITION, ERR_NOT_FOUND, ERR_VALIDATION } from '../../lib/errors.js';
9
+ import { withLogContext } from '../../lib/logger.js';
10
+ import { getDefaultStatus } from '../../workflow/workflow.js';
11
+ import { applyRichTextEmbed } from '../document-lifecycle/internals.js';
12
+ import { persistExistingDocumentVersion } from '../document-lifecycle/persistence.js';
13
+ import { authorizeSingletonUpdate, commitSingletonSave } from './internals.js';
14
+ /** Restore one historical singleton version as the new current version. */
15
+ export async function restoreSingletonVersion(ctx, params) {
16
+ return withLogContext({ domain: 'services', module: 'singleton-lifecycle', function: 'restoreSingletonVersion' }, async () => {
17
+ const definition = authorizeSingletonUpdate(ctx);
18
+ return commitSingletonSave({
19
+ ctx,
20
+ definition,
21
+ operation: { type: 'restore', sourceVersionId: params.sourceVersionId },
22
+ prepare: async (slot) => {
23
+ if (slot.documentId == null || slot.currentVersion == null) {
24
+ throw ERR_NOT_FOUND({
25
+ message: `singleton '${ctx.collectionPath}' has not been saved`,
26
+ details: { singletonPath: ctx.collectionPath },
27
+ }).log(ctx.logger);
28
+ }
29
+ const source = await ctx.db.queries.documents.getDocumentByVersion({
30
+ document_version_id: params.sourceVersionId,
31
+ collection_id: ctx.collectionId,
32
+ locale: 'all',
33
+ });
34
+ if (source == null) {
35
+ throw ERR_NOT_FOUND({
36
+ message: 'source version not found',
37
+ details: { sourceVersionId: params.sourceVersionId },
38
+ }).log(ctx.logger);
39
+ }
40
+ const sourceRecord = source;
41
+ if (sourceRecord.document_id !== slot.documentId) {
42
+ throw ERR_VALIDATION({
43
+ message: 'source version does not belong to the singleton document',
44
+ details: {
45
+ singletonPath: ctx.collectionPath,
46
+ sourceVersionId: params.sourceVersionId,
47
+ sourceDocumentId: sourceRecord.document_id,
48
+ },
49
+ }).log(ctx.logger);
50
+ }
51
+ if (slot.currentVersion.document_version_id === params.sourceVersionId) {
52
+ throw ERR_INVALID_TRANSITION({
53
+ message: 'source version is already the current singleton version',
54
+ details: {
55
+ singletonPath: ctx.collectionPath,
56
+ sourceVersionId: params.sourceVersionId,
57
+ },
58
+ }).log(ctx.logger);
59
+ }
60
+ const current = await ctx.db.queries.documents.getDocumentById({
61
+ collection_id: ctx.collectionId,
62
+ document_id: slot.documentId,
63
+ locale: 'all',
64
+ reconstruct: true,
65
+ });
66
+ if (current == null) {
67
+ throw ERR_NOT_FOUND({
68
+ message: 'current singleton version not found',
69
+ details: { singletonPath: ctx.collectionPath, documentId: slot.documentId },
70
+ }).log(ctx.logger);
71
+ }
72
+ const data = sourceRecord.fields ?? {};
73
+ const originalData = current.fields ?? {};
74
+ return {
75
+ data,
76
+ originalData,
77
+ locale: 'all',
78
+ write: async () => {
79
+ await applyRichTextEmbed(ctx, data);
80
+ return persistExistingDocumentVersion(ctx, {
81
+ documentId: slot.documentId,
82
+ action: 'restore',
83
+ documentData: data,
84
+ status: getDefaultStatus(definition),
85
+ locale: 'all',
86
+ previousVersionId: slot.currentVersion?.document_version_id,
87
+ });
88
+ },
89
+ };
90
+ },
91
+ });
92
+ });
93
+ }
@@ -0,0 +1,16 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { DocumentLifecycleContext } from '../document-lifecycle/context.js';
9
+ import type { SingletonSaveResult } from './internals.js';
10
+ export interface UpdateSingletonParams {
11
+ data: Record<string, any>;
12
+ locale?: string;
13
+ expectedVersionId?: string;
14
+ }
15
+ /** Materialise or update a singleton slot as one immutable document version. */
16
+ export declare function updateSingleton(ctx: DocumentLifecycleContext, params: UpdateSingletonParams): Promise<SingletonSaveResult>;
@@ -0,0 +1,107 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import { ERR_CONFLICT, ERR_VALIDATION } from '../../lib/errors.js';
9
+ import { withLogContext } from '../../lib/logger.js';
10
+ import { normaliseDateFields } from '../../utils/normalise-dates.js';
11
+ import { getDefaultStatus } from '../../workflow/workflow.js';
12
+ import { assignCounterValues } from '../assign-counter-values.js';
13
+ import { applyRichTextEmbed } from '../document-lifecycle/internals.js';
14
+ import { persistExistingDocumentVersion, persistInitialDocumentVersion, } from '../document-lifecycle/persistence.js';
15
+ import { normalizeNumericFields } from '../normalize-numeric-fields.js';
16
+ import { authorizeSingletonUpdate, commitSingletonSave } from './internals.js';
17
+ /** Materialise or update a singleton slot as one immutable document version. */
18
+ export async function updateSingleton(ctx, params) {
19
+ return withLogContext({ domain: 'services', module: 'singleton-lifecycle', function: 'updateSingleton' }, async () => {
20
+ const definition = authorizeSingletonUpdate(ctx);
21
+ const locale = params.locale ?? ctx.defaultLocale;
22
+ const data = params.data;
23
+ return commitSingletonSave({
24
+ ctx,
25
+ definition,
26
+ operation: { type: 'save' },
27
+ prepare: async (slot) => {
28
+ if (slot.documentId == null && locale !== ctx.defaultLocale) {
29
+ throw ERR_VALIDATION({
30
+ message: `a singleton's first save must use the default content locale ` +
31
+ `('${ctx.defaultLocale}'); received '${locale}'`,
32
+ details: {
33
+ singletonPath: ctx.collectionPath,
34
+ defaultLocale: ctx.defaultLocale,
35
+ providedLocale: locale,
36
+ },
37
+ }).log(ctx.logger);
38
+ }
39
+ if (params.expectedVersionId != null) {
40
+ const currentVersionId = slot.currentVersion?.document_version_id;
41
+ if (currentVersionId !== params.expectedVersionId) {
42
+ throw ERR_CONFLICT({
43
+ message: 'singleton version conflict',
44
+ details: {
45
+ singletonPath: ctx.collectionPath,
46
+ expectedVersionId: params.expectedVersionId,
47
+ currentVersionId: currentVersionId ?? null,
48
+ },
49
+ }).log(ctx.logger);
50
+ }
51
+ }
52
+ const current = slot.documentId == null
53
+ ? null
54
+ : await ctx.db.queries.documents.getDocumentById({
55
+ collection_id: ctx.collectionId,
56
+ document_id: slot.documentId,
57
+ locale,
58
+ reconstruct: true,
59
+ lenient: true,
60
+ requestContext: ctx.requestContext,
61
+ });
62
+ if (slot.documentId != null && current == null) {
63
+ throw ERR_CONFLICT({
64
+ message: `singleton '${ctx.collectionPath}' could not reconstruct its mapped document`,
65
+ details: { singletonPath: ctx.collectionPath, documentId: slot.documentId },
66
+ }).log(ctx.logger);
67
+ }
68
+ const currentRecord = current;
69
+ const originalData = currentRecord?.fields ?? null;
70
+ normaliseDateFields(data);
71
+ normalizeNumericFields(definition.fields, data);
72
+ return {
73
+ data,
74
+ originalData,
75
+ locale,
76
+ write: async () => {
77
+ normalizeNumericFields(definition.fields, data);
78
+ await assignCounterValues({
79
+ fields: definition.fields,
80
+ data,
81
+ previousData: originalData ?? undefined,
82
+ counters: ctx.db.commands.counters,
83
+ });
84
+ await applyRichTextEmbed(ctx, data);
85
+ if (slot.documentId == null) {
86
+ return persistInitialDocumentVersion(ctx, {
87
+ action: 'create',
88
+ documentData: data,
89
+ path: crypto.randomUUID(),
90
+ status: getDefaultStatus(definition),
91
+ locale,
92
+ });
93
+ }
94
+ return persistExistingDocumentVersion(ctx, {
95
+ documentId: slot.documentId,
96
+ action: 'update',
97
+ documentData: data,
98
+ status: getDefaultStatus(definition),
99
+ locale,
100
+ previousVersionId: slot.currentVersion?.document_version_id,
101
+ });
102
+ },
103
+ };
104
+ },
105
+ });
106
+ });
107
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ export {};