@pwrdrvr/microapps-router-lib 0.4.0-alpha.9 → 1.0.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.
Files changed (44) hide show
  1. package/dist/get-app-info.d.ts +9 -0
  2. package/dist/get-app-info.d.ts.map +1 -0
  3. package/dist/get-app-info.js +25 -0
  4. package/dist/get-app-info.js.map +1 -0
  5. package/dist/get-route.d.ts +83 -0
  6. package/dist/get-route.d.ts.map +1 -0
  7. package/dist/get-route.js +171 -0
  8. package/dist/get-route.js.map +1 -0
  9. package/dist/index.d.ts +5 -96
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +11 -372
  12. package/dist/index.js.map +1 -1
  13. package/dist/load-app-frame.d.ts +8 -0
  14. package/dist/load-app-frame.d.ts.map +1 -0
  15. package/dist/load-app-frame.js +38 -0
  16. package/dist/load-app-frame.js.map +1 -0
  17. package/dist/normalize-path-prefix.d.ts +8 -0
  18. package/dist/normalize-path-prefix.d.ts.map +1 -0
  19. package/dist/normalize-path-prefix.js +21 -0
  20. package/dist/normalize-path-prefix.js.map +1 -0
  21. package/dist/redirect-default-file.d.ts +18 -0
  22. package/dist/redirect-default-file.d.ts.map +1 -0
  23. package/dist/redirect-default-file.js +54 -0
  24. package/dist/redirect-default-file.js.map +1 -0
  25. package/dist/route-app.d.ts +23 -0
  26. package/dist/route-app.d.ts.map +1 -0
  27. package/dist/route-app.js +169 -0
  28. package/dist/route-app.js.map +1 -0
  29. package/package.json +5 -3
  30. package/src/get-app-info.spec.ts +77 -0
  31. package/src/get-app-info.ts +31 -0
  32. package/src/get-route.spec.ts +585 -0
  33. package/src/get-route.ts +282 -0
  34. package/src/index.ts +5 -537
  35. package/src/load-app-frame.spec.ts +51 -0
  36. package/src/load-app-frame.ts +36 -0
  37. package/src/normalize-path-prefix.spec.ts +27 -0
  38. package/src/normalize-path-prefix.ts +18 -0
  39. package/src/redirect-default-file.spec.ts +98 -0
  40. package/src/redirect-default-file.ts +79 -0
  41. package/src/route-app.spec.ts +128 -0
  42. package/src/route-app.ts +202 -0
  43. package/src/index.spec.ts +0 -322
  44. /package/src/{index.prefix.spec.ts → get-route.prefix.spec.ts} +0 -0
@@ -0,0 +1,169 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RouteApp = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const app_cache_1 = require("./app-cache");
6
+ const log_1 = tslib_1.__importDefault(require("./lib/log"));
7
+ const log = log_1.default.Instance;
8
+ /**
9
+ * Lookup the version of the app to run
10
+ * @param event
11
+ * @param response
12
+ * @param appName
13
+ * @param additionalParts
14
+ * @param log
15
+ * @returns
16
+ */
17
+ async function RouteApp(opts) {
18
+ var _a;
19
+ const { dbManager, event, normalizedPathPrefix = '', appName, possibleSemVerPathNextData, possibleSemVerPathAfterApp, possibleSemVerQuery, additionalParts, appNameOrRootTrailingSlash, } = opts;
20
+ let versionInfoToUse;
21
+ const appVersionCache = app_cache_1.AppVersionCache.GetInstance({ dbManager });
22
+ // Check if the semver placeholder is actually a defined version
23
+ const possibleSemVerPathAfterAppVersionInfo = possibleSemVerPathAfterApp
24
+ ? await appVersionCache.GetVersionInfo({
25
+ key: { AppName: appName, SemVer: possibleSemVerPathAfterApp },
26
+ })
27
+ : undefined;
28
+ const possibleSemVerPathNextDataVersionInfo = possibleSemVerPathNextData
29
+ ? await appVersionCache.GetVersionInfo({
30
+ key: { AppName: appName, SemVer: possibleSemVerPathNextData },
31
+ })
32
+ : undefined;
33
+ const possibleSemVerQueryVersionInfo = possibleSemVerQuery
34
+ ? await appVersionCache.GetVersionInfo({
35
+ key: { AppName: appName, SemVer: possibleSemVerQuery },
36
+ })
37
+ : undefined;
38
+ // If there is a version in the path, use it
39
+ const possibleSemVerPathVersionInfo = possibleSemVerPathAfterAppVersionInfo || possibleSemVerPathNextDataVersionInfo;
40
+ if (possibleSemVerPathVersionInfo) {
41
+ //
42
+ // If this is an iframe app then it's a startup request
43
+ // If this is a direct app then it's a regular request to send to the app
44
+ //
45
+ // This is a version, and it's in the path already, route the request to it
46
+ // without creating iframe
47
+ return {
48
+ statusCode: 200,
49
+ appName,
50
+ semVer: possibleSemVerPathVersionInfo.SemVer,
51
+ isAPIPath: additionalParts.startsWith('api/'),
52
+ ...((possibleSemVerPathVersionInfo === null || possibleSemVerPathVersionInfo === void 0 ? void 0 : possibleSemVerPathVersionInfo.URL) ? { url: possibleSemVerPathVersionInfo === null || possibleSemVerPathVersionInfo === void 0 ? void 0 : possibleSemVerPathVersionInfo.URL } : {}),
53
+ ...((possibleSemVerPathVersionInfo === null || possibleSemVerPathVersionInfo === void 0 ? void 0 : possibleSemVerPathVersionInfo.Type)
54
+ ? {
55
+ type: (possibleSemVerPathVersionInfo === null || possibleSemVerPathVersionInfo === void 0 ? void 0 : possibleSemVerPathVersionInfo.Type) === 'lambda'
56
+ ? 'apigwy'
57
+ : possibleSemVerPathVersionInfo === null || possibleSemVerPathVersionInfo === void 0 ? void 0 : possibleSemVerPathVersionInfo.Type,
58
+ }
59
+ : {}),
60
+ };
61
+ }
62
+ else if (possibleSemVerQueryVersionInfo) {
63
+ // We got a version for the query string, but it's not in the path,
64
+ // so fall back to normal routing (create an iframe or direct route)
65
+ versionInfoToUse = possibleSemVerQueryVersionInfo;
66
+ }
67
+ else if (possibleSemVerQuery) {
68
+ // We got a version in the query string but it does not exist
69
+ // This needs to 404 as this is a very specific request for a specific version
70
+ log.error(`could not find app ${appName}, for path ${event.rawPath} - returning 404`, {
71
+ statusCode: 404,
72
+ });
73
+ return {
74
+ statusCode: 404,
75
+ errorMessage: `Router - Could not find app: ${event.rawPath}, ${appName}`,
76
+ };
77
+ }
78
+ else {
79
+ //
80
+ // TODO: Get the incoming attributes of user
81
+ // For logged in users, these can be: department, product type,
82
+ // employee, office, division, etc.
83
+ // For anonymous users this can be: geo region, language,
84
+ // browser, IP, CIDR, ASIN, etc.
85
+ //
86
+ // The Rules can be either a version or a distribution of versions,
87
+ // including default, for example:
88
+ // 80% to 1.1.0, 20% to default (1.0.3)
89
+ //
90
+ const rules = await appVersionCache.GetRules({ key: { AppName: appName } });
91
+ const defaultVersion = (_a = rules === null || rules === void 0 ? void 0 : rules.RuleSet.default) === null || _a === void 0 ? void 0 : _a.SemVer;
92
+ if (defaultVersion == null) {
93
+ log.error(`could not find app ${appName}, for path ${event.rawPath} - returning 404`, {
94
+ statusCode: 404,
95
+ });
96
+ return {
97
+ statusCode: 404,
98
+ errorMessage: `Router - Could not find app: ${event.rawPath}, ${appName}`,
99
+ };
100
+ }
101
+ const defaultVersionInfo = await appVersionCache.GetVersionInfo({
102
+ key: { AppName: appName, SemVer: defaultVersion },
103
+ });
104
+ versionInfoToUse = defaultVersionInfo;
105
+ }
106
+ if (!versionInfoToUse) {
107
+ log.error(`could not find version info for app ${appName}, for path ${event.rawPath} - returning 404`, {
108
+ statusCode: 404,
109
+ });
110
+ return {
111
+ statusCode: 404,
112
+ errorMessage: `Router - Could not find version info for app: ${event.rawPath}, ${appName}`,
113
+ };
114
+ }
115
+ if ((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.StartupType) === 'iframe' || !(versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.StartupType)) {
116
+ // Prepare the iframe contents
117
+ let appVersionPath;
118
+ if (
119
+ // versionInfoToUse?.Type !== 'static' &&
120
+ (versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.DefaultFile) === undefined ||
121
+ (versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.DefaultFile) === '' ||
122
+ additionalParts !== '') {
123
+ // KLUDGE: We're going to take a missing default file to mean that the
124
+ // app type is Next.js (or similar) and that it wants no trailing slash after the version
125
+ // TODO: Move this to an attribute of the version
126
+ appVersionPath = `${normalizedPathPrefix}/${appNameOrRootTrailingSlash}${versionInfoToUse.SemVer}`;
127
+ if (additionalParts !== '') {
128
+ appVersionPath += `/${additionalParts}`;
129
+ }
130
+ }
131
+ else {
132
+ // Linking to the file directly means this will be peeled off by the S3 route
133
+ // That means we won't have to proxy this from S3
134
+ appVersionPath = `${normalizedPathPrefix}/${appNameOrRootTrailingSlash}${versionInfoToUse.SemVer}/${versionInfoToUse.DefaultFile}`;
135
+ }
136
+ return {
137
+ statusCode: 200,
138
+ appName,
139
+ semVer: versionInfoToUse.SemVer,
140
+ startupType: 'iframe',
141
+ isAPIPath: additionalParts.startsWith('api/'),
142
+ ...((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.URL) ? { url: versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.URL } : {}),
143
+ ...((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type)
144
+ ? { type: (versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type) === 'lambda' ? 'apigwy' : versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type }
145
+ : {}),
146
+ iFrameAppVersionPath: appVersionPath,
147
+ };
148
+ }
149
+ else {
150
+ // This is a direct app version, no iframe needed
151
+ if ((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type) === 'lambda') {
152
+ throw new Error('Invalid type for direct app version');
153
+ }
154
+ if (['apigwy', 'static'].includes((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type) || '')) {
155
+ throw new Error('Invalid type for direct app version');
156
+ }
157
+ return {
158
+ statusCode: 200,
159
+ appName,
160
+ semVer: versionInfoToUse.SemVer,
161
+ startupType: 'direct',
162
+ isAPIPath: additionalParts.startsWith('api/'),
163
+ ...((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.URL) ? { url: versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.URL } : {}),
164
+ ...((versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type) ? { type: versionInfoToUse === null || versionInfoToUse === void 0 ? void 0 : versionInfoToUse.Type } : {}),
165
+ };
166
+ }
167
+ }
168
+ exports.RouteApp = RouteApp;
169
+ //# sourceMappingURL=route-app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"route-app.js","sourceRoot":"","sources":["../src/route-app.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pwrdrvr/microapps-router-lib",
3
- "version": "0.4.0-alpha.9",
3
+ "version": "1.0.2",
4
4
  "description": "Router library for the microapps framework",
5
5
  "types": "dist/index.d.ts",
6
6
  "main": "dist/index.js",
@@ -23,16 +23,18 @@
23
23
  "fs-extra": "^9.0.0",
24
24
  "lambda-log": "^3.0.0",
25
25
  "source-map-support": "^0.5.0",
26
- "tslib": "^2.0.0"
26
+ "tslib": "^2.1.0"
27
27
  },
28
28
  "devDependencies": {
29
29
  "@aws-sdk/client-dynamodb": "3.78.0",
30
30
  "@types/aws-lambda": "8.10.110",
31
31
  "@types/lambda-log": "^2.2.0",
32
- "@types/node": "16.9.2",
32
+ "@types/mock-fs": "4.13.1",
33
+ "@types/node": "^18.0.0",
33
34
  "@types/source-map-support": "0.5.6",
34
35
  "fs-extra": "^9.1.0",
35
36
  "lambda-log": "^3.1.0",
37
+ "mock-fs": "5.2.0",
36
38
  "source-map-support": "0.5.21",
37
39
  "tslib": "^2.1.0"
38
40
  },
@@ -0,0 +1,77 @@
1
+ import { DBManager, Rules } from '@pwrdrvr/microapps-datalib';
2
+ import { AppVersionCache } from './app-cache';
3
+ import { GetAppInfo } from './get-app-info';
4
+
5
+ jest.mock('@pwrdrvr/microapps-datalib');
6
+
7
+ describe('GetAppInfo', () => {
8
+ const dbManager = {} as DBManager;
9
+ const getAppVersionCacheSpy = jest.spyOn(AppVersionCache, 'GetInstance');
10
+
11
+ beforeEach(() => {
12
+ jest.clearAllMocks();
13
+ });
14
+
15
+ afterEach(() => {
16
+ getAppVersionCacheSpy.mockReset();
17
+ });
18
+
19
+ const testCases = [
20
+ {
21
+ caseName: 'returns the correct app name when it exists',
22
+ appName: 'testApp',
23
+ mockRules: {
24
+ AppName: 'testapp',
25
+ Version: 1,
26
+ RuleSet: {
27
+ default: {
28
+ AttributeName: 'default',
29
+ AttributeValue: '',
30
+ SemVer: '1.0.0',
31
+ },
32
+ },
33
+ } as unknown as Rules,
34
+ expected: 'testApp',
35
+ },
36
+ {
37
+ caseName:
38
+ 'returns undefined when the app name does not exist and there is no [root] catch-all app',
39
+ appName: 'nonexistent',
40
+ mockRules: undefined,
41
+ expected: undefined,
42
+ },
43
+ {
44
+ caseName:
45
+ 'returns [root] when the app name does not exist but there is a [root] catch-all app',
46
+ appName: 'nonexistent',
47
+ mockRules: {
48
+ AppName: '[root]',
49
+ RuleSet: {
50
+ default: {
51
+ AttributeName: 'default',
52
+ AttributeValue: '',
53
+ SemVer: '9.0.0',
54
+ },
55
+ } as unknown as Rules,
56
+ },
57
+ expected: '[root]',
58
+ },
59
+ ];
60
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
61
+ it.each(testCases)('$caseName', async ({ caseName, appName, mockRules, expected }) => {
62
+ getAppVersionCacheSpy.mockImplementation(() => {
63
+ return {
64
+ // eslint-disable-next-line @typescript-eslint/require-await
65
+ GetRules: async ({ key }: { key: { AppName: string } }) => {
66
+ if (key.AppName === appName || key.AppName === '[root]') {
67
+ return mockRules;
68
+ }
69
+ return undefined;
70
+ },
71
+ } as unknown as AppVersionCache;
72
+ });
73
+
74
+ const result = await GetAppInfo({ dbManager, appName });
75
+ expect(result).toEqual(expected);
76
+ });
77
+ });
@@ -0,0 +1,31 @@
1
+ import { DBManager, Rules } from '@pwrdrvr/microapps-datalib';
2
+ import { AppVersionCache } from './app-cache';
3
+
4
+ /**
5
+ * Determine if we have an appname or a catch all app
6
+ */
7
+
8
+ export async function GetAppInfo(opts: {
9
+ dbManager: DBManager;
10
+ appName: string;
11
+ }): Promise<string | undefined> {
12
+ const { dbManager, appName } = opts;
13
+
14
+ let rules: Rules | undefined;
15
+
16
+ const appVersionCache = AppVersionCache.GetInstance({ dbManager });
17
+
18
+ // Check if we got a matching app name
19
+ rules = await appVersionCache.GetRules({ key: { AppName: appName } });
20
+ if (rules && rules.AppName === appName.toLowerCase()) {
21
+ return appName;
22
+ }
23
+
24
+ // Check if we have a `[root]` app that is a catch all
25
+ rules = await appVersionCache.GetRules({ key: { AppName: '[root]' } });
26
+ if (rules && rules.AppName === '[root]') {
27
+ return '[root]';
28
+ }
29
+
30
+ return undefined;
31
+ }