@markwharton/pwa-core 1.7.0 → 2.0.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 (103) hide show
  1. package/dist/{client/api.d.ts → client.d.ts} +85 -9
  2. package/dist/{client/api.js → client.js} +159 -56
  3. package/dist/index.d.ts +10 -2
  4. package/dist/index.js +14 -6
  5. package/dist/server.d.ts +283 -0
  6. package/dist/server.js +476 -0
  7. package/dist/shared.d.ts +150 -0
  8. package/dist/shared.js +124 -0
  9. package/package.json +11 -12
  10. package/dist/__tests__/auth/apiKey.test.d.ts +0 -1
  11. package/dist/__tests__/auth/apiKey.test.js +0 -80
  12. package/dist/__tests__/auth/token.test.d.ts +0 -1
  13. package/dist/__tests__/auth/token.test.js +0 -212
  14. package/dist/__tests__/auth/types.test.d.ts +0 -1
  15. package/dist/__tests__/auth/types.test.js +0 -77
  16. package/dist/__tests__/client/api.test.d.ts +0 -1
  17. package/dist/__tests__/client/api.test.js +0 -369
  18. package/dist/__tests__/client/apiError.test.d.ts +0 -1
  19. package/dist/__tests__/client/apiError.test.js +0 -91
  20. package/dist/__tests__/http/responses.test.d.ts +0 -1
  21. package/dist/__tests__/http/responses.test.js +0 -112
  22. package/dist/__tests__/http/status.test.d.ts +0 -1
  23. package/dist/__tests__/http/status.test.js +0 -27
  24. package/dist/__tests__/server/auth/apiKey.test.d.ts +0 -1
  25. package/dist/__tests__/server/auth/apiKey.test.js +0 -80
  26. package/dist/__tests__/server/auth/token.test.d.ts +0 -1
  27. package/dist/__tests__/server/auth/token.test.js +0 -299
  28. package/dist/__tests__/server/http/responses.test.d.ts +0 -1
  29. package/dist/__tests__/server/http/responses.test.js +0 -112
  30. package/dist/__tests__/server/storage/client.test.d.ts +0 -1
  31. package/dist/__tests__/server/storage/client.test.js +0 -173
  32. package/dist/__tests__/server/storage/keys.test.d.ts +0 -1
  33. package/dist/__tests__/server/storage/keys.test.js +0 -47
  34. package/dist/__tests__/shared/auth/types.test.d.ts +0 -1
  35. package/dist/__tests__/shared/auth/types.test.js +0 -77
  36. package/dist/__tests__/shared/http/status.test.d.ts +0 -1
  37. package/dist/__tests__/shared/http/status.test.js +0 -29
  38. package/dist/__tests__/storage/client.test.d.ts +0 -1
  39. package/dist/__tests__/storage/client.test.js +0 -173
  40. package/dist/__tests__/storage/keys.test.d.ts +0 -1
  41. package/dist/__tests__/storage/keys.test.js +0 -47
  42. package/dist/__tests__/types.test.d.ts +0 -1
  43. package/dist/__tests__/types.test.js +0 -56
  44. package/dist/auth/apiKey.d.ts +0 -44
  45. package/dist/auth/apiKey.js +0 -59
  46. package/dist/auth/index.d.ts +0 -3
  47. package/dist/auth/index.js +0 -22
  48. package/dist/auth/token.d.ts +0 -56
  49. package/dist/auth/token.js +0 -104
  50. package/dist/auth/types.d.ts +0 -63
  51. package/dist/auth/types.js +0 -41
  52. package/dist/client/apiError.d.ts +0 -48
  53. package/dist/client/apiError.js +0 -65
  54. package/dist/client/index.d.ts +0 -3
  55. package/dist/client/index.js +0 -14
  56. package/dist/client/types.d.ts +0 -12
  57. package/dist/client/types.js +0 -5
  58. package/dist/http/index.d.ts +0 -3
  59. package/dist/http/index.js +0 -14
  60. package/dist/http/responses.d.ts +0 -82
  61. package/dist/http/responses.js +0 -132
  62. package/dist/http/status.d.ts +0 -17
  63. package/dist/http/status.js +0 -19
  64. package/dist/http/types.d.ts +0 -10
  65. package/dist/http/types.js +0 -5
  66. package/dist/server/auth/apiKey.d.ts +0 -44
  67. package/dist/server/auth/apiKey.js +0 -59
  68. package/dist/server/auth/index.d.ts +0 -3
  69. package/dist/server/auth/index.js +0 -19
  70. package/dist/server/auth/token.d.ts +0 -102
  71. package/dist/server/auth/token.js +0 -158
  72. package/dist/server/http/index.d.ts +0 -1
  73. package/dist/server/http/index.js +0 -12
  74. package/dist/server/http/responses.d.ts +0 -82
  75. package/dist/server/http/responses.js +0 -132
  76. package/dist/server/index.d.ts +0 -4
  77. package/dist/server/index.js +0 -37
  78. package/dist/server/storage/client.d.ts +0 -48
  79. package/dist/server/storage/client.js +0 -107
  80. package/dist/server/storage/index.d.ts +0 -2
  81. package/dist/server/storage/index.js +0 -11
  82. package/dist/server/storage/keys.d.ts +0 -8
  83. package/dist/server/storage/keys.js +0 -14
  84. package/dist/shared/auth/index.d.ts +0 -2
  85. package/dist/shared/auth/index.js +0 -7
  86. package/dist/shared/auth/types.d.ts +0 -63
  87. package/dist/shared/auth/types.js +0 -41
  88. package/dist/shared/http/index.d.ts +0 -3
  89. package/dist/shared/http/index.js +0 -5
  90. package/dist/shared/http/status.d.ts +0 -19
  91. package/dist/shared/http/status.js +0 -21
  92. package/dist/shared/http/types.d.ts +0 -10
  93. package/dist/shared/http/types.js +0 -5
  94. package/dist/shared/index.d.ts +0 -5
  95. package/dist/shared/index.js +0 -10
  96. package/dist/storage/client.d.ts +0 -48
  97. package/dist/storage/client.js +0 -107
  98. package/dist/storage/index.d.ts +0 -2
  99. package/dist/storage/index.js +0 -11
  100. package/dist/storage/keys.d.ts +0 -8
  101. package/dist/storage/keys.js +0 -14
  102. package/dist/types.d.ts +0 -48
  103. package/dist/types.js +0 -41
@@ -1,173 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- const vitest_1 = require("vitest");
37
- // Create mock functions
38
- const mockCreateTable = vitest_1.vi.fn();
39
- const mockFromConnectionString = vitest_1.vi.fn();
40
- // Mock @azure/data-tables
41
- vitest_1.vi.mock('@azure/data-tables', () => {
42
- class MockTableClient {
43
- constructor() {
44
- this.createTable = mockCreateTable;
45
- }
46
- }
47
- MockTableClient.fromConnectionString = mockFromConnectionString;
48
- return {
49
- TableClient: MockTableClient,
50
- TableServiceClient: class MockTableServiceClient {
51
- }
52
- };
53
- });
54
- // Mock @azure/identity
55
- vitest_1.vi.mock('@azure/identity', () => ({
56
- DefaultAzureCredential: class MockDefaultAzureCredential {
57
- }
58
- }));
59
- (0, vitest_1.describe)('Storage client', () => {
60
- (0, vitest_1.beforeEach)(() => {
61
- vitest_1.vi.resetModules();
62
- vitest_1.vi.clearAllMocks();
63
- mockCreateTable.mockResolvedValue(undefined);
64
- mockFromConnectionString.mockReturnValue({
65
- createTable: vitest_1.vi.fn().mockResolvedValue(undefined)
66
- });
67
- // Reset environment
68
- delete process.env.STORAGE_ACCOUNT_NAME;
69
- delete process.env.AzureWebJobsStorage;
70
- });
71
- (0, vitest_1.describe)('initStorage', () => {
72
- (0, vitest_1.it)('accepts configuration object', async () => {
73
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
74
- initStorage({ accountName: 'myaccount' });
75
- (0, vitest_1.expect)(useManagedIdentity()).toBe(true);
76
- });
77
- (0, vitest_1.it)('accepts connection string', async () => {
78
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
79
- initStorage({ connectionString: 'DefaultEndpointsProtocol=https;AccountName=test' });
80
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
81
- });
82
- });
83
- (0, vitest_1.describe)('initStorageFromEnv', () => {
84
- (0, vitest_1.it)('reads STORAGE_ACCOUNT_NAME', async () => {
85
- process.env.STORAGE_ACCOUNT_NAME = 'testaccount';
86
- const { initStorageFromEnv, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
87
- initStorageFromEnv();
88
- (0, vitest_1.expect)(useManagedIdentity()).toBe(true);
89
- });
90
- (0, vitest_1.it)('reads AzureWebJobsStorage', async () => {
91
- process.env.AzureWebJobsStorage = 'UseDevelopmentStorage=true';
92
- const { initStorageFromEnv, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
93
- initStorageFromEnv();
94
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
95
- });
96
- });
97
- (0, vitest_1.describe)('useManagedIdentity', () => {
98
- (0, vitest_1.it)('returns true when accountName is set without development storage', async () => {
99
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
100
- initStorage({ accountName: 'prodaccount' });
101
- (0, vitest_1.expect)(useManagedIdentity()).toBe(true);
102
- });
103
- (0, vitest_1.it)('returns false when using development storage', async () => {
104
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
105
- initStorage({
106
- accountName: 'devaccount',
107
- connectionString: 'UseDevelopmentStorage=true'
108
- });
109
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
110
- });
111
- (0, vitest_1.it)('returns false when only connection string is set', async () => {
112
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
113
- initStorage({ connectionString: 'DefaultEndpointsProtocol=https' });
114
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
115
- });
116
- });
117
- (0, vitest_1.describe)('getTableClient', () => {
118
- (0, vitest_1.it)('throws if storage not configured', async () => {
119
- const { getTableClient } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
120
- await (0, vitest_1.expect)(getTableClient('test')).rejects.toThrow('Storage not configured. Set STORAGE_ACCOUNT_NAME or AzureWebJobsStorage.');
121
- });
122
- (0, vitest_1.it)('creates table client with managed identity', async () => {
123
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
124
- initStorage({ accountName: 'testaccount' });
125
- clearTableClientCache();
126
- const client = await getTableClient('mytable');
127
- (0, vitest_1.expect)(client).toBeDefined();
128
- });
129
- (0, vitest_1.it)('creates table client with connection string', async () => {
130
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
131
- initStorage({ connectionString: 'DefaultEndpointsProtocol=https;AccountName=test' });
132
- clearTableClientCache();
133
- await getTableClient('mytable');
134
- (0, vitest_1.expect)(mockFromConnectionString).toHaveBeenCalledWith('DefaultEndpointsProtocol=https;AccountName=test', 'mytable');
135
- });
136
- (0, vitest_1.it)('caches table client', async () => {
137
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
138
- initStorage({ accountName: 'testaccount' });
139
- clearTableClientCache();
140
- const client1 = await getTableClient('mytable');
141
- const client2 = await getTableClient('mytable');
142
- (0, vitest_1.expect)(client1).toBe(client2);
143
- });
144
- (0, vitest_1.it)('handles 409 conflict (table exists)', async () => {
145
- mockCreateTable.mockRejectedValue({ statusCode: 409 });
146
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
147
- initStorage({ accountName: 'testaccount' });
148
- clearTableClientCache();
149
- // Should not throw
150
- const client = await getTableClient('existingtable');
151
- (0, vitest_1.expect)(client).toBeDefined();
152
- });
153
- (0, vitest_1.it)('throws on other errors', async () => {
154
- mockCreateTable.mockRejectedValue({ statusCode: 500, message: 'Server error' });
155
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
156
- initStorage({ accountName: 'testaccount' });
157
- clearTableClientCache();
158
- await (0, vitest_1.expect)(getTableClient('mytable')).rejects.toMatchObject({ statusCode: 500 });
159
- });
160
- });
161
- (0, vitest_1.describe)('clearTableClientCache', () => {
162
- (0, vitest_1.it)('clears cached clients', async () => {
163
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../../server/storage/client')));
164
- initStorage({ accountName: 'testaccount' });
165
- clearTableClientCache();
166
- await getTableClient('mytable');
167
- clearTableClientCache();
168
- // After clearing, a new call should create a new client
169
- const client2 = await getTableClient('mytable');
170
- (0, vitest_1.expect)(client2).toBeDefined();
171
- });
172
- });
173
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const keys_1 = require("../../../server/storage/keys");
5
- (0, vitest_1.describe)('generateRowKey', () => {
6
- (0, vitest_1.it)('returns 32-character hex string', () => {
7
- const key = (0, keys_1.generateRowKey)('test-identifier');
8
- (0, vitest_1.expect)(key).toHaveLength(32);
9
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
10
- });
11
- (0, vitest_1.it)('produces consistent hash for same input', () => {
12
- const key1 = (0, keys_1.generateRowKey)('same-input');
13
- const key2 = (0, keys_1.generateRowKey)('same-input');
14
- (0, vitest_1.expect)(key1).toBe(key2);
15
- });
16
- (0, vitest_1.it)('produces different hashes for different inputs', () => {
17
- const key1 = (0, keys_1.generateRowKey)('input-1');
18
- const key2 = (0, keys_1.generateRowKey)('input-2');
19
- (0, vitest_1.expect)(key1).not.toBe(key2);
20
- });
21
- (0, vitest_1.it)('handles empty string', () => {
22
- const key = (0, keys_1.generateRowKey)('');
23
- (0, vitest_1.expect)(key).toHaveLength(32);
24
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
25
- });
26
- (0, vitest_1.it)('handles special characters', () => {
27
- const key = (0, keys_1.generateRowKey)('https://example.com/path?query=value&foo=bar');
28
- (0, vitest_1.expect)(key).toHaveLength(32);
29
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
30
- });
31
- (0, vitest_1.it)('handles unicode characters', () => {
32
- const key = (0, keys_1.generateRowKey)('日本語テスト');
33
- (0, vitest_1.expect)(key).toHaveLength(32);
34
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
35
- });
36
- (0, vitest_1.it)('handles long strings', () => {
37
- const longString = 'x'.repeat(10000);
38
- const key = (0, keys_1.generateRowKey)(longString);
39
- (0, vitest_1.expect)(key).toHaveLength(32);
40
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
41
- });
42
- (0, vitest_1.it)('produces URL-safe keys', () => {
43
- const key = (0, keys_1.generateRowKey)('some-identifier');
44
- // Row keys should not contain these characters
45
- (0, vitest_1.expect)(key).not.toMatch(/[\/\\#?\s]/);
46
- });
47
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,77 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const types_1 = require("../../../shared/auth/types");
5
- (0, vitest_1.describe)('Auth type guards', () => {
6
- const basePayload = {
7
- iat: 1234567890,
8
- exp: 1234567890 + 3600
9
- };
10
- (0, vitest_1.describe)('hasUsername', () => {
11
- (0, vitest_1.it)('returns true for payload with username', () => {
12
- const payload = { ...basePayload, username: 'testuser' };
13
- (0, vitest_1.expect)((0, types_1.hasUsername)(payload)).toBe(true);
14
- });
15
- (0, vitest_1.it)('returns false for payload without username', () => {
16
- (0, vitest_1.expect)((0, types_1.hasUsername)(basePayload)).toBe(false);
17
- });
18
- (0, vitest_1.it)('returns false for payload with non-string username', () => {
19
- const payload = { ...basePayload, username: 123 };
20
- (0, vitest_1.expect)((0, types_1.hasUsername)(payload)).toBe(false);
21
- });
22
- (0, vitest_1.it)('returns false for payload with empty string username', () => {
23
- const payload = { ...basePayload, username: '' };
24
- (0, vitest_1.expect)((0, types_1.hasUsername)(payload)).toBe(true); // Empty string is still a string
25
- });
26
- });
27
- (0, vitest_1.describe)('hasRole', () => {
28
- (0, vitest_1.it)('returns true for payload with role', () => {
29
- const payload = {
30
- ...basePayload,
31
- authenticated: true,
32
- tokenType: 'user',
33
- role: 'admin'
34
- };
35
- (0, vitest_1.expect)((0, types_1.hasRole)(payload)).toBe(true);
36
- });
37
- (0, vitest_1.it)('returns false for payload without role', () => {
38
- (0, vitest_1.expect)((0, types_1.hasRole)(basePayload)).toBe(false);
39
- });
40
- (0, vitest_1.it)('returns true for viewer role', () => {
41
- const payload = {
42
- ...basePayload,
43
- authenticated: true,
44
- tokenType: 'user',
45
- role: 'viewer'
46
- };
47
- (0, vitest_1.expect)((0, types_1.hasRole)(payload)).toBe(true);
48
- });
49
- });
50
- (0, vitest_1.describe)('isAdmin', () => {
51
- (0, vitest_1.it)('returns true for admin role', () => {
52
- const payload = {
53
- ...basePayload,
54
- authenticated: true,
55
- tokenType: 'user',
56
- role: 'admin'
57
- };
58
- (0, vitest_1.expect)((0, types_1.isAdmin)(payload)).toBe(true);
59
- });
60
- (0, vitest_1.it)('returns false for viewer role', () => {
61
- const payload = {
62
- ...basePayload,
63
- authenticated: true,
64
- tokenType: 'user',
65
- role: 'viewer'
66
- };
67
- (0, vitest_1.expect)((0, types_1.isAdmin)(payload)).toBe(false);
68
- });
69
- (0, vitest_1.it)('returns false for payload without role', () => {
70
- (0, vitest_1.expect)((0, types_1.isAdmin)(basePayload)).toBe(false);
71
- });
72
- (0, vitest_1.it)('returns false for payload with username but no role', () => {
73
- const payload = { ...basePayload, username: 'testuser' };
74
- (0, vitest_1.expect)((0, types_1.isAdmin)(payload)).toBe(false);
75
- });
76
- });
77
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,29 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const status_1 = require("../../../shared/http/status");
5
- (0, vitest_1.describe)('HTTP_STATUS', () => {
6
- (0, vitest_1.it)('has correct status codes', () => {
7
- (0, vitest_1.expect)(status_1.HTTP_STATUS.OK).toBe(200);
8
- (0, vitest_1.expect)(status_1.HTTP_STATUS.CREATED).toBe(201);
9
- (0, vitest_1.expect)(status_1.HTTP_STATUS.NO_CONTENT).toBe(204);
10
- (0, vitest_1.expect)(status_1.HTTP_STATUS.BAD_REQUEST).toBe(400);
11
- (0, vitest_1.expect)(status_1.HTTP_STATUS.UNAUTHORIZED).toBe(401);
12
- (0, vitest_1.expect)(status_1.HTTP_STATUS.FORBIDDEN).toBe(403);
13
- (0, vitest_1.expect)(status_1.HTTP_STATUS.NOT_FOUND).toBe(404);
14
- (0, vitest_1.expect)(status_1.HTTP_STATUS.CONFLICT).toBe(409);
15
- (0, vitest_1.expect)(status_1.HTTP_STATUS.GONE).toBe(410);
16
- (0, vitest_1.expect)(status_1.HTTP_STATUS.UNPROCESSABLE_ENTITY).toBe(422);
17
- (0, vitest_1.expect)(status_1.HTTP_STATUS.TOO_MANY_REQUESTS).toBe(429);
18
- (0, vitest_1.expect)(status_1.HTTP_STATUS.INTERNAL_ERROR).toBe(500);
19
- (0, vitest_1.expect)(status_1.HTTP_STATUS.SERVICE_UNAVAILABLE).toBe(503);
20
- });
21
- (0, vitest_1.it)('is immutable (const assertion)', () => {
22
- // TypeScript const assertion makes the object readonly
23
- // This test verifies the values haven't been accidentally modified
24
- const statusCodes = Object.values(status_1.HTTP_STATUS);
25
- (0, vitest_1.expect)(statusCodes).toContain(200);
26
- (0, vitest_1.expect)(statusCodes).toContain(404);
27
- (0, vitest_1.expect)(statusCodes).toContain(500);
28
- });
29
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,173 +0,0 @@
1
- "use strict";
2
- var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
- if (k2 === undefined) k2 = k;
4
- var desc = Object.getOwnPropertyDescriptor(m, k);
5
- if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
- desc = { enumerable: true, get: function() { return m[k]; } };
7
- }
8
- Object.defineProperty(o, k2, desc);
9
- }) : (function(o, m, k, k2) {
10
- if (k2 === undefined) k2 = k;
11
- o[k2] = m[k];
12
- }));
13
- var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
- Object.defineProperty(o, "default", { enumerable: true, value: v });
15
- }) : function(o, v) {
16
- o["default"] = v;
17
- });
18
- var __importStar = (this && this.__importStar) || (function () {
19
- var ownKeys = function(o) {
20
- ownKeys = Object.getOwnPropertyNames || function (o) {
21
- var ar = [];
22
- for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
- return ar;
24
- };
25
- return ownKeys(o);
26
- };
27
- return function (mod) {
28
- if (mod && mod.__esModule) return mod;
29
- var result = {};
30
- if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
- __setModuleDefault(result, mod);
32
- return result;
33
- };
34
- })();
35
- Object.defineProperty(exports, "__esModule", { value: true });
36
- const vitest_1 = require("vitest");
37
- // Create mock functions
38
- const mockCreateTable = vitest_1.vi.fn();
39
- const mockFromConnectionString = vitest_1.vi.fn();
40
- // Mock @azure/data-tables
41
- vitest_1.vi.mock('@azure/data-tables', () => {
42
- class MockTableClient {
43
- constructor() {
44
- this.createTable = mockCreateTable;
45
- }
46
- }
47
- MockTableClient.fromConnectionString = mockFromConnectionString;
48
- return {
49
- TableClient: MockTableClient,
50
- TableServiceClient: class MockTableServiceClient {
51
- }
52
- };
53
- });
54
- // Mock @azure/identity
55
- vitest_1.vi.mock('@azure/identity', () => ({
56
- DefaultAzureCredential: class MockDefaultAzureCredential {
57
- }
58
- }));
59
- (0, vitest_1.describe)('Storage client', () => {
60
- (0, vitest_1.beforeEach)(() => {
61
- vitest_1.vi.resetModules();
62
- vitest_1.vi.clearAllMocks();
63
- mockCreateTable.mockResolvedValue(undefined);
64
- mockFromConnectionString.mockReturnValue({
65
- createTable: vitest_1.vi.fn().mockResolvedValue(undefined)
66
- });
67
- // Reset environment
68
- delete process.env.STORAGE_ACCOUNT_NAME;
69
- delete process.env.AzureWebJobsStorage;
70
- });
71
- (0, vitest_1.describe)('initStorage', () => {
72
- (0, vitest_1.it)('accepts configuration object', async () => {
73
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
74
- initStorage({ accountName: 'myaccount' });
75
- (0, vitest_1.expect)(useManagedIdentity()).toBe(true);
76
- });
77
- (0, vitest_1.it)('accepts connection string', async () => {
78
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
79
- initStorage({ connectionString: 'DefaultEndpointsProtocol=https;AccountName=test' });
80
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
81
- });
82
- });
83
- (0, vitest_1.describe)('initStorageFromEnv', () => {
84
- (0, vitest_1.it)('reads STORAGE_ACCOUNT_NAME', async () => {
85
- process.env.STORAGE_ACCOUNT_NAME = 'testaccount';
86
- const { initStorageFromEnv, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
87
- initStorageFromEnv();
88
- (0, vitest_1.expect)(useManagedIdentity()).toBe(true);
89
- });
90
- (0, vitest_1.it)('reads AzureWebJobsStorage', async () => {
91
- process.env.AzureWebJobsStorage = 'UseDevelopmentStorage=true';
92
- const { initStorageFromEnv, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
93
- initStorageFromEnv();
94
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
95
- });
96
- });
97
- (0, vitest_1.describe)('useManagedIdentity', () => {
98
- (0, vitest_1.it)('returns true when accountName is set without development storage', async () => {
99
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
100
- initStorage({ accountName: 'prodaccount' });
101
- (0, vitest_1.expect)(useManagedIdentity()).toBe(true);
102
- });
103
- (0, vitest_1.it)('returns false when using development storage', async () => {
104
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
105
- initStorage({
106
- accountName: 'devaccount',
107
- connectionString: 'UseDevelopmentStorage=true'
108
- });
109
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
110
- });
111
- (0, vitest_1.it)('returns false when only connection string is set', async () => {
112
- const { initStorage, useManagedIdentity } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
113
- initStorage({ connectionString: 'DefaultEndpointsProtocol=https' });
114
- (0, vitest_1.expect)(useManagedIdentity()).toBe(false);
115
- });
116
- });
117
- (0, vitest_1.describe)('getTableClient', () => {
118
- (0, vitest_1.it)('throws if storage not configured', async () => {
119
- const { getTableClient } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
120
- await (0, vitest_1.expect)(getTableClient('test')).rejects.toThrow('Storage not configured. Set STORAGE_ACCOUNT_NAME or AzureWebJobsStorage.');
121
- });
122
- (0, vitest_1.it)('creates table client with managed identity', async () => {
123
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
124
- initStorage({ accountName: 'testaccount' });
125
- clearTableClientCache();
126
- const client = await getTableClient('mytable');
127
- (0, vitest_1.expect)(client).toBeDefined();
128
- });
129
- (0, vitest_1.it)('creates table client with connection string', async () => {
130
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
131
- initStorage({ connectionString: 'DefaultEndpointsProtocol=https;AccountName=test' });
132
- clearTableClientCache();
133
- await getTableClient('mytable');
134
- (0, vitest_1.expect)(mockFromConnectionString).toHaveBeenCalledWith('DefaultEndpointsProtocol=https;AccountName=test', 'mytable');
135
- });
136
- (0, vitest_1.it)('caches table client', async () => {
137
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
138
- initStorage({ accountName: 'testaccount' });
139
- clearTableClientCache();
140
- const client1 = await getTableClient('mytable');
141
- const client2 = await getTableClient('mytable');
142
- (0, vitest_1.expect)(client1).toBe(client2);
143
- });
144
- (0, vitest_1.it)('handles 409 conflict (table exists)', async () => {
145
- mockCreateTable.mockRejectedValue({ statusCode: 409 });
146
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
147
- initStorage({ accountName: 'testaccount' });
148
- clearTableClientCache();
149
- // Should not throw
150
- const client = await getTableClient('existingtable');
151
- (0, vitest_1.expect)(client).toBeDefined();
152
- });
153
- (0, vitest_1.it)('throws on other errors', async () => {
154
- mockCreateTable.mockRejectedValue({ statusCode: 500, message: 'Server error' });
155
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
156
- initStorage({ accountName: 'testaccount' });
157
- clearTableClientCache();
158
- await (0, vitest_1.expect)(getTableClient('mytable')).rejects.toMatchObject({ statusCode: 500 });
159
- });
160
- });
161
- (0, vitest_1.describe)('clearTableClientCache', () => {
162
- (0, vitest_1.it)('clears cached clients', async () => {
163
- const { initStorage, getTableClient, clearTableClientCache } = await Promise.resolve().then(() => __importStar(require('../../storage/client')));
164
- initStorage({ accountName: 'testaccount' });
165
- clearTableClientCache();
166
- await getTableClient('mytable');
167
- clearTableClientCache();
168
- // After clearing, a new call should create a new client
169
- const client2 = await getTableClient('mytable');
170
- (0, vitest_1.expect)(client2).toBeDefined();
171
- });
172
- });
173
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const keys_1 = require("../../storage/keys");
5
- (0, vitest_1.describe)('generateRowKey', () => {
6
- (0, vitest_1.it)('returns 32-character hex string', () => {
7
- const key = (0, keys_1.generateRowKey)('test-identifier');
8
- (0, vitest_1.expect)(key).toHaveLength(32);
9
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
10
- });
11
- (0, vitest_1.it)('produces consistent hash for same input', () => {
12
- const key1 = (0, keys_1.generateRowKey)('same-input');
13
- const key2 = (0, keys_1.generateRowKey)('same-input');
14
- (0, vitest_1.expect)(key1).toBe(key2);
15
- });
16
- (0, vitest_1.it)('produces different hashes for different inputs', () => {
17
- const key1 = (0, keys_1.generateRowKey)('input-1');
18
- const key2 = (0, keys_1.generateRowKey)('input-2');
19
- (0, vitest_1.expect)(key1).not.toBe(key2);
20
- });
21
- (0, vitest_1.it)('handles empty string', () => {
22
- const key = (0, keys_1.generateRowKey)('');
23
- (0, vitest_1.expect)(key).toHaveLength(32);
24
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
25
- });
26
- (0, vitest_1.it)('handles special characters', () => {
27
- const key = (0, keys_1.generateRowKey)('https://example.com/path?query=value&foo=bar');
28
- (0, vitest_1.expect)(key).toHaveLength(32);
29
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
30
- });
31
- (0, vitest_1.it)('handles unicode characters', () => {
32
- const key = (0, keys_1.generateRowKey)('日本語テスト');
33
- (0, vitest_1.expect)(key).toHaveLength(32);
34
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
35
- });
36
- (0, vitest_1.it)('handles long strings', () => {
37
- const longString = 'x'.repeat(10000);
38
- const key = (0, keys_1.generateRowKey)(longString);
39
- (0, vitest_1.expect)(key).toHaveLength(32);
40
- (0, vitest_1.expect)(key).toMatch(/^[a-f0-9]+$/);
41
- });
42
- (0, vitest_1.it)('produces URL-safe keys', () => {
43
- const key = (0, keys_1.generateRowKey)('some-identifier');
44
- // Row keys should not contain these characters
45
- (0, vitest_1.expect)(key).not.toMatch(/[\/\\#?\s]/);
46
- });
47
- });
@@ -1 +0,0 @@
1
- export {};
@@ -1,56 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- const vitest_1 = require("vitest");
4
- const types_1 = require("../types");
5
- (0, vitest_1.describe)('Result helpers', () => {
6
- (0, vitest_1.describe)('ok', () => {
7
- (0, vitest_1.it)('creates success result with data', () => {
8
- const result = (0, types_1.ok)({ name: 'test' });
9
- (0, vitest_1.expect)(result.ok).toBe(true);
10
- (0, vitest_1.expect)(result.data).toEqual({ name: 'test' });
11
- (0, vitest_1.expect)(result.error).toBeUndefined();
12
- });
13
- (0, vitest_1.it)('works with primitive values', () => {
14
- (0, vitest_1.expect)((0, types_1.ok)(42).data).toBe(42);
15
- (0, vitest_1.expect)((0, types_1.ok)('hello').data).toBe('hello');
16
- (0, vitest_1.expect)((0, types_1.ok)(true).data).toBe(true);
17
- });
18
- (0, vitest_1.it)('works with null', () => {
19
- const result = (0, types_1.ok)(null);
20
- (0, vitest_1.expect)(result.ok).toBe(true);
21
- (0, vitest_1.expect)(result.data).toBeNull();
22
- });
23
- });
24
- (0, vitest_1.describe)('okVoid', () => {
25
- (0, vitest_1.it)('creates success result without data', () => {
26
- const result = (0, types_1.okVoid)();
27
- (0, vitest_1.expect)(result.ok).toBe(true);
28
- (0, vitest_1.expect)(result.data).toBeUndefined();
29
- (0, vitest_1.expect)(result.error).toBeUndefined();
30
- });
31
- });
32
- (0, vitest_1.describe)('err', () => {
33
- (0, vitest_1.it)('creates failure result with error message', () => {
34
- const result = (0, types_1.err)('Something went wrong');
35
- (0, vitest_1.expect)(result.ok).toBe(false);
36
- (0, vitest_1.expect)(result.error).toBe('Something went wrong');
37
- (0, vitest_1.expect)(result.data).toBeUndefined();
38
- (0, vitest_1.expect)(result.statusCode).toBeUndefined();
39
- });
40
- (0, vitest_1.it)('creates failure result with status code', () => {
41
- const result = (0, types_1.err)('Not found', 404);
42
- (0, vitest_1.expect)(result.ok).toBe(false);
43
- (0, vitest_1.expect)(result.error).toBe('Not found');
44
- (0, vitest_1.expect)(result.statusCode).toBe(404);
45
- });
46
- (0, vitest_1.it)('excludes statusCode when not provided', () => {
47
- const result = (0, types_1.err)('Error');
48
- (0, vitest_1.expect)('statusCode' in result).toBe(false);
49
- });
50
- (0, vitest_1.it)('includes statusCode when provided', () => {
51
- const result = (0, types_1.err)('Error', 500);
52
- (0, vitest_1.expect)('statusCode' in result).toBe(true);
53
- (0, vitest_1.expect)(result.statusCode).toBe(500);
54
- });
55
- });
56
- });