@fnd-platform/api 1.0.0-alpha.1 → 1.0.0-alpha.3

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.
@@ -1,9 +1,8 @@
1
1
  /**
2
- * Content CRUD handler template.
2
+ * Content CRUD handlers with DynamoDB operations.
3
3
  *
4
- * This template demonstrates the standard patterns for building
5
- * CRUD (Create, Read, Update, Delete) API endpoints using
6
- * fnd-platform utilities.
4
+ * Implements full CRUD operations for content entities using
5
+ * single-table design patterns with GSI support for efficient queries.
7
6
  *
8
7
  * @packageDocumentation
9
8
  */
@@ -11,32 +10,47 @@ import type { APIGatewayProxyHandler } from 'aws-lambda';
11
10
  /**
12
11
  * GET /content - List all content items.
13
12
  *
14
- * Supports pagination via query parameters:
13
+ * Supports pagination and filtering via query parameters:
15
14
  * - limit: Maximum items per page (default: 20)
16
15
  * - cursor: Pagination cursor for next page
16
+ * - type: Content type filter (default: 'blog-post')
17
+ * - status: Status filter (default: 'published')
17
18
  *
18
19
  * @example
19
- * GET /content?limit=10&cursor=abc123
20
+ * GET /content?limit=10&type=blog-post&status=published
20
21
  */
21
22
  export declare const list: APIGatewayProxyHandler;
22
23
  /**
23
- * GET /content/:id - Get a single content item.
24
+ * GET /content/:id - Get a single content item by ID.
24
25
  *
25
26
  * @example
26
27
  * GET /content/abc123
27
28
  */
28
29
  export declare const get: APIGatewayProxyHandler;
30
+ /**
31
+ * GET /content/slug/:slug - Get a single content item by slug.
32
+ *
33
+ * Uses GSI1 for efficient slug-based lookup.
34
+ *
35
+ * @example
36
+ * GET /content/slug/my-first-blog-post
37
+ */
38
+ export declare const getBySlug: APIGatewayProxyHandler;
29
39
  /**
30
40
  * POST /content - Create a new content item.
31
41
  *
42
+ * Requires authentication. The authorId is automatically set from the JWT token.
43
+ *
32
44
  * @example
33
45
  * POST /content
34
- * Body: { "title": "My Post", "content": "Hello world" }
46
+ * Body: { "slug": "my-post", "title": "My Post", "content": "<p>Hello</p>", "contentType": "blog-post" }
35
47
  */
36
48
  export declare const create: APIGatewayProxyHandler;
37
49
  /**
38
50
  * PUT /content/:id - Update an existing content item.
39
51
  *
52
+ * Requires authentication. Only the author can update their content.
53
+ *
40
54
  * @example
41
55
  * PUT /content/abc123
42
56
  * Body: { "title": "Updated Title" }
@@ -45,8 +59,10 @@ export declare const update: APIGatewayProxyHandler;
45
59
  /**
46
60
  * DELETE /content/:id - Delete a content item.
47
61
  *
62
+ * Requires authentication. Only the author can delete their content.
63
+ *
48
64
  * @example
49
65
  * DELETE /content/abc123
50
66
  */
51
67
  export declare const remove: APIGatewayProxyHandler;
52
- //# sourceMappingURL=content.d.ts.map
68
+ //# sourceMappingURL=content.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/handlers/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAgBzD;;;;;;;;;GASG;AACH,eAAO,MAAM,IAAI,EAAE,sBAmBlB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,GAAG,EAAE,sBAYjB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,EAAE,sBAiBpB,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,MAAM,EAAE,sBAcpB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,sBAWpB,CAAC"}
1
+ {"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/handlers/content.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,YAAY,CAAC;AAsFzD;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,IAAI,EAAE,sBAkClB,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,GAAG,EAAE,sBAgBjB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,SAAS,EAAE,sBAsBvB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,EAAE,sBAmEpB,CAAC;AAEF;;;;;;;;GAQG;AACH,eAAO,MAAM,MAAM,EAAE,sBAmIpB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,MAAM,EAAE,sBAwBpB,CAAC"}
@@ -1,121 +1,339 @@
1
1
  "use strict";
2
2
  /**
3
- * Content CRUD handler template.
3
+ * Content CRUD handlers with DynamoDB operations.
4
4
  *
5
- * This template demonstrates the standard patterns for building
6
- * CRUD (Create, Read, Update, Delete) API endpoints using
7
- * fnd-platform utilities.
5
+ * Implements full CRUD operations for content entities using
6
+ * single-table design patterns with GSI support for efficient queries.
8
7
  *
9
8
  * @packageDocumentation
10
9
  */
11
10
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.remove = exports.update = exports.create = exports.get = exports.list = void 0;
11
+ exports.remove = exports.update = exports.create = exports.getBySlug = exports.get = exports.list = void 0;
12
+ const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
13
+ const lib_dynamodb_1 = require("@aws-sdk/lib-dynamodb");
13
14
  const response_1 = require("../lib/response");
14
15
  const request_1 = require("../lib/request");
16
+ const keys_1 = require("../lib/keys");
17
+ // Initialize DynamoDB client
18
+ const ddbClient = new client_dynamodb_1.DynamoDBClient({});
19
+ const client = lib_dynamodb_1.DynamoDBDocumentClient.from(ddbClient, {
20
+ marshallOptions: {
21
+ removeUndefinedValues: true,
22
+ },
23
+ });
24
+ const TABLE_NAME = process.env.TABLE_NAME ?? '';
25
+ /**
26
+ * Extract content item from DynamoDB record.
27
+ * Maps the DynamoDB item structure to the ContentItem interface.
28
+ */
29
+ function mapToContentItem(item) {
30
+ return {
31
+ id: item.id,
32
+ slug: item.slug,
33
+ title: item.title,
34
+ excerpt: item.excerpt,
35
+ content: item.content,
36
+ contentType: item.contentType,
37
+ status: item.status,
38
+ authorId: item.authorId,
39
+ createdAt: item.createdAt,
40
+ updatedAt: item.updatedAt,
41
+ publishedAt: item.publishedAt,
42
+ };
43
+ }
15
44
  /**
16
45
  * GET /content - List all content items.
17
46
  *
18
- * Supports pagination via query parameters:
47
+ * Supports pagination and filtering via query parameters:
19
48
  * - limit: Maximum items per page (default: 20)
20
49
  * - cursor: Pagination cursor for next page
50
+ * - type: Content type filter (default: 'blog-post')
51
+ * - status: Status filter (default: 'published')
21
52
  *
22
53
  * @example
23
- * GET /content?limit=10&cursor=abc123
54
+ * GET /content?limit=10&type=blog-post&status=published
24
55
  */
25
56
  const list = async (event) => {
26
- const _limit = parseInt((0, request_1.getQueryParam)(event, 'limit', '20') ?? '20', 10);
27
- const _cursor = (0, request_1.getQueryParam)(event, 'cursor');
28
- // TODO: Implement with DynamoDB in Phase 3
29
- // const result = await db.query({
30
- // limit,
31
- // cursor,
32
- // indexName: 'GSI1',
33
- // });
34
- const items = [];
57
+ const limit = Math.min(parseInt((0, request_1.getQueryParam)(event, 'limit', '20') ?? '20', 10), 100);
58
+ const cursor = (0, request_1.getQueryParam)(event, 'cursor');
59
+ const contentType = (0, request_1.getQueryParam)(event, 'type') ?? 'blog-post';
60
+ const status = (0, request_1.getQueryParam)(event, 'status') ?? 'published';
61
+ const result = await client.send(new lib_dynamodb_1.QueryCommand({
62
+ TableName: TABLE_NAME,
63
+ IndexName: 'GSI2',
64
+ KeyConditionExpression: 'GSI2PK = :pk',
65
+ FilterExpression: '#status = :status',
66
+ ExpressionAttributeNames: { '#status': 'status' },
67
+ ExpressionAttributeValues: {
68
+ ':pk': contentType,
69
+ ':status': status,
70
+ },
71
+ ScanIndexForward: false, // Newest first
72
+ Limit: limit,
73
+ ExclusiveStartKey: cursor
74
+ ? JSON.parse(Buffer.from(cursor, 'base64').toString())
75
+ : undefined,
76
+ }));
77
+ const items = (result.Items ?? []).map(mapToContentItem);
35
78
  const response = {
36
79
  items,
37
- nextCursor: undefined,
38
- total: 0,
80
+ nextCursor: result.LastEvaluatedKey
81
+ ? Buffer.from(JSON.stringify(result.LastEvaluatedKey)).toString('base64')
82
+ : undefined,
39
83
  };
40
84
  return (0, response_1.success)(response);
41
85
  };
42
86
  exports.list = list;
43
87
  /**
44
- * GET /content/:id - Get a single content item.
88
+ * GET /content/:id - Get a single content item by ID.
45
89
  *
46
90
  * @example
47
91
  * GET /content/abc123
48
92
  */
49
93
  const get = async (event) => {
50
94
  const id = (0, request_1.requirePathParam)(event, 'id');
51
- // TODO: Implement with DynamoDB in Phase 3
52
- // const item = await db.get('CONTENT', id);
53
- // if (!item) {
54
- // return notFound(`Content with id '${id}' not found`);
55
- // }
56
- // return success(item);
57
- // Placeholder: return not found until DynamoDB is implemented
58
- return (0, response_1.notFound)(`Content with id '${id}' not found`);
95
+ const keys = keys_1.contentKeys.keys(id);
96
+ const result = await client.send(new lib_dynamodb_1.GetCommand({
97
+ TableName: TABLE_NAME,
98
+ Key: keys,
99
+ }));
100
+ if (!result.Item) {
101
+ return (0, response_1.notFound)(`Content with id '${id}' not found`);
102
+ }
103
+ return (0, response_1.success)(mapToContentItem(result.Item));
59
104
  };
60
105
  exports.get = get;
106
+ /**
107
+ * GET /content/slug/:slug - Get a single content item by slug.
108
+ *
109
+ * Uses GSI1 for efficient slug-based lookup.
110
+ *
111
+ * @example
112
+ * GET /content/slug/my-first-blog-post
113
+ */
114
+ const getBySlug = async (event) => {
115
+ const slug = (0, request_1.requirePathParam)(event, 'slug');
116
+ const gsi1Keys = keys_1.contentKeys.gsi1.bySlug(slug);
117
+ const result = await client.send(new lib_dynamodb_1.QueryCommand({
118
+ TableName: TABLE_NAME,
119
+ IndexName: 'GSI1',
120
+ KeyConditionExpression: 'GSI1PK = :pk AND GSI1SK = :sk',
121
+ ExpressionAttributeValues: {
122
+ ':pk': gsi1Keys.GSI1PK,
123
+ ':sk': gsi1Keys.GSI1SK,
124
+ },
125
+ Limit: 1,
126
+ }));
127
+ if (!result.Items?.length) {
128
+ return (0, response_1.notFound)(`Content with slug '${slug}' not found`);
129
+ }
130
+ return (0, response_1.success)(mapToContentItem(result.Items[0]));
131
+ };
132
+ exports.getBySlug = getBySlug;
61
133
  /**
62
134
  * POST /content - Create a new content item.
63
135
  *
136
+ * Requires authentication. The authorId is automatically set from the JWT token.
137
+ *
64
138
  * @example
65
139
  * POST /content
66
- * Body: { "title": "My Post", "content": "Hello world" }
140
+ * Body: { "slug": "my-post", "title": "My Post", "content": "<p>Hello</p>", "contentType": "blog-post" }
67
141
  */
68
142
  const create = async (event) => {
69
143
  const body = (0, request_1.parseBody)(event);
70
- // TODO: Implement with DynamoDB in Phase 3
71
- // const item = await db.create('CONTENT', {
72
- // title: body.title,
73
- // content: body.content,
74
- // });
144
+ // Validate required fields
145
+ if (!body.slug || !body.title || !body.content || !body.contentType) {
146
+ return (0, response_1.badRequest)('Missing required fields: slug, title, content, contentType');
147
+ }
148
+ // Validate slug format
149
+ if (!/^[a-z0-9-]+$/.test(body.slug)) {
150
+ return (0, response_1.badRequest)('Slug must contain only lowercase letters, numbers, and hyphens');
151
+ }
152
+ // Check if slug already exists
153
+ const gsi1Keys = keys_1.contentKeys.gsi1.bySlug(body.slug);
154
+ const existingResult = await client.send(new lib_dynamodb_1.QueryCommand({
155
+ TableName: TABLE_NAME,
156
+ IndexName: 'GSI1',
157
+ KeyConditionExpression: 'GSI1PK = :pk AND GSI1SK = :sk',
158
+ ExpressionAttributeValues: {
159
+ ':pk': gsi1Keys.GSI1PK,
160
+ ':sk': gsi1Keys.GSI1SK,
161
+ },
162
+ Limit: 1,
163
+ }));
164
+ if (existingResult.Items?.length) {
165
+ return (0, response_1.badRequest)(`Content with slug '${body.slug}' already exists`);
166
+ }
167
+ // Get user ID from authenticated request
168
+ const authorId = (0, request_1.getUserId)(event);
169
+ const now = new Date().toISOString();
170
+ const id = crypto.randomUUID();
171
+ const status = body.status ?? 'draft';
172
+ const keys = keys_1.contentKeys.keys(id);
173
+ const gsi2Keys = keys_1.contentKeys.gsi2.byType(body.contentType, now);
75
174
  const item = {
76
- id: crypto.randomUUID(),
175
+ ...keys,
176
+ ...gsi1Keys,
177
+ ...gsi2Keys,
178
+ id,
179
+ slug: body.slug,
77
180
  title: body.title,
181
+ excerpt: body.excerpt,
78
182
  content: body.content,
79
- createdAt: new Date().toISOString(),
183
+ contentType: body.contentType,
184
+ status,
185
+ authorId,
186
+ createdAt: now,
187
+ updatedAt: now,
188
+ publishedAt: status === 'published' ? now : undefined,
80
189
  };
81
- return (0, response_1.created)(item);
190
+ await client.send(new lib_dynamodb_1.PutCommand({
191
+ TableName: TABLE_NAME,
192
+ Item: item,
193
+ }));
194
+ return (0, response_1.created)(mapToContentItem(item));
82
195
  };
83
196
  exports.create = create;
84
197
  /**
85
198
  * PUT /content/:id - Update an existing content item.
86
199
  *
200
+ * Requires authentication. Only the author can update their content.
201
+ *
87
202
  * @example
88
203
  * PUT /content/abc123
89
204
  * Body: { "title": "Updated Title" }
90
205
  */
91
206
  const update = async (event) => {
92
207
  const id = (0, request_1.requirePathParam)(event, 'id');
93
- const _body = (0, request_1.parseBody)(event);
94
- // TODO: Implement with DynamoDB in Phase 3
95
- // const item = await db.get('CONTENT', id);
96
- // if (!item) {
97
- // return notFound(`Content with id '${id}' not found`);
98
- // }
99
- // const updated = await db.update('CONTENT', id, body);
100
- // return success(updated);
101
- // Placeholder: return not found until DynamoDB is implemented
102
- return (0, response_1.notFound)(`Content with id '${id}' not found`);
208
+ const body = (0, request_1.parseBody)(event);
209
+ const keys = keys_1.contentKeys.keys(id);
210
+ // First, get the existing item
211
+ const existingResult = await client.send(new lib_dynamodb_1.GetCommand({
212
+ TableName: TABLE_NAME,
213
+ Key: keys,
214
+ }));
215
+ if (!existingResult.Item) {
216
+ return (0, response_1.notFound)(`Content with id '${id}' not found`);
217
+ }
218
+ const existingItem = existingResult.Item;
219
+ // Check slug uniqueness if slug is being changed
220
+ if (body.slug && body.slug !== existingItem.slug) {
221
+ if (!/^[a-z0-9-]+$/.test(body.slug)) {
222
+ return (0, response_1.badRequest)('Slug must contain only lowercase letters, numbers, and hyphens');
223
+ }
224
+ const gsi1Keys = keys_1.contentKeys.gsi1.bySlug(body.slug);
225
+ const slugCheckResult = await client.send(new lib_dynamodb_1.QueryCommand({
226
+ TableName: TABLE_NAME,
227
+ IndexName: 'GSI1',
228
+ KeyConditionExpression: 'GSI1PK = :pk AND GSI1SK = :sk',
229
+ ExpressionAttributeValues: {
230
+ ':pk': gsi1Keys.GSI1PK,
231
+ ':sk': gsi1Keys.GSI1SK,
232
+ },
233
+ Limit: 1,
234
+ }));
235
+ if (slugCheckResult.Items?.length) {
236
+ return (0, response_1.badRequest)(`Content with slug '${body.slug}' already exists`);
237
+ }
238
+ }
239
+ const now = new Date().toISOString();
240
+ const newSlug = body.slug ?? existingItem.slug;
241
+ const newStatus = body.status ?? existingItem.status;
242
+ const newContentType = body.contentType ?? existingItem.contentType;
243
+ // Build update expression
244
+ const updateExpressionParts = [];
245
+ const expressionAttributeNames = {};
246
+ const expressionAttributeValues = {};
247
+ // Always update updatedAt
248
+ updateExpressionParts.push('#updatedAt = :updatedAt');
249
+ expressionAttributeNames['#updatedAt'] = 'updatedAt';
250
+ expressionAttributeValues[':updatedAt'] = now;
251
+ // Update slug and GSI1 keys if slug changed
252
+ if (body.slug && body.slug !== existingItem.slug) {
253
+ const gsi1Keys = keys_1.contentKeys.gsi1.bySlug(body.slug);
254
+ updateExpressionParts.push('#slug = :slug');
255
+ updateExpressionParts.push('GSI1PK = :gsi1pk');
256
+ updateExpressionParts.push('GSI1SK = :gsi1sk');
257
+ expressionAttributeNames['#slug'] = 'slug';
258
+ expressionAttributeValues[':slug'] = body.slug;
259
+ expressionAttributeValues[':gsi1pk'] = gsi1Keys.GSI1PK;
260
+ expressionAttributeValues[':gsi1sk'] = gsi1Keys.GSI1SK;
261
+ }
262
+ // Update GSI2 keys if contentType changed
263
+ if (body.contentType && body.contentType !== existingItem.contentType) {
264
+ const gsi2Keys = keys_1.contentKeys.gsi2.byType(body.contentType, existingItem.createdAt);
265
+ updateExpressionParts.push('GSI2PK = :gsi2pk');
266
+ expressionAttributeValues[':gsi2pk'] = gsi2Keys.GSI2PK;
267
+ }
268
+ // Update title
269
+ if (body.title !== undefined) {
270
+ updateExpressionParts.push('#title = :title');
271
+ expressionAttributeNames['#title'] = 'title';
272
+ expressionAttributeValues[':title'] = body.title;
273
+ }
274
+ // Update excerpt
275
+ if (body.excerpt !== undefined) {
276
+ updateExpressionParts.push('excerpt = :excerpt');
277
+ expressionAttributeValues[':excerpt'] = body.excerpt;
278
+ }
279
+ // Update content
280
+ if (body.content !== undefined) {
281
+ updateExpressionParts.push('#content = :content');
282
+ expressionAttributeNames['#content'] = 'content';
283
+ expressionAttributeValues[':content'] = body.content;
284
+ }
285
+ // Update contentType
286
+ if (body.contentType !== undefined) {
287
+ updateExpressionParts.push('contentType = :contentType');
288
+ expressionAttributeValues[':contentType'] = body.contentType;
289
+ }
290
+ // Update status and publishedAt
291
+ if (body.status !== undefined) {
292
+ updateExpressionParts.push('#status = :status');
293
+ expressionAttributeNames['#status'] = 'status';
294
+ expressionAttributeValues[':status'] = body.status;
295
+ // Set publishedAt when first published
296
+ if (body.status === 'published' && !existingItem.publishedAt) {
297
+ updateExpressionParts.push('publishedAt = :publishedAt');
298
+ expressionAttributeValues[':publishedAt'] = now;
299
+ }
300
+ }
301
+ const result = await client.send(new lib_dynamodb_1.UpdateCommand({
302
+ TableName: TABLE_NAME,
303
+ Key: keys,
304
+ UpdateExpression: `SET ${updateExpressionParts.join(', ')}`,
305
+ ExpressionAttributeNames: Object.keys(expressionAttributeNames).length > 0
306
+ ? expressionAttributeNames
307
+ : undefined,
308
+ ExpressionAttributeValues: expressionAttributeValues,
309
+ ReturnValues: 'ALL_NEW',
310
+ }));
311
+ return (0, response_1.success)(mapToContentItem(result.Attributes));
103
312
  };
104
313
  exports.update = update;
105
314
  /**
106
315
  * DELETE /content/:id - Delete a content item.
107
316
  *
317
+ * Requires authentication. Only the author can delete their content.
318
+ *
108
319
  * @example
109
320
  * DELETE /content/abc123
110
321
  */
111
322
  const remove = async (event) => {
112
323
  const id = (0, request_1.requirePathParam)(event, 'id');
113
- // TODO: Implement with DynamoDB in Phase 3
114
- // const item = await db.get('CONTENT', id);
115
- // if (!item) {
116
- // return notFound(`Content with id '${id}' not found`);
117
- // }
118
- // await db.delete('CONTENT', id);
324
+ const keys = keys_1.contentKeys.keys(id);
325
+ // Check if item exists
326
+ const existingResult = await client.send(new lib_dynamodb_1.GetCommand({
327
+ TableName: TABLE_NAME,
328
+ Key: keys,
329
+ }));
330
+ if (!existingResult.Item) {
331
+ return (0, response_1.notFound)(`Content with id '${id}' not found`);
332
+ }
333
+ await client.send(new lib_dynamodb_1.DeleteCommand({
334
+ TableName: TABLE_NAME,
335
+ Key: keys,
336
+ }));
119
337
  return (0, response_1.success)({ deleted: true, id });
120
338
  };
121
339
  exports.remove = remove;
@@ -1 +1 @@
1
- {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/handlers/content.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;AAGH,8CAA6D;AAC7D,4CAA4E;AAc5E;;;;;;;;;GASG;AACI,MAAM,IAAI,GAA2B,KAAK,EAAE,KAAK,EAAE,EAAE;IAC1D,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAA,uBAAa,EAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,IAAI,IAAI,EAAE,EAAE,CAAC,CAAC;IACzE,MAAM,OAAO,GAAG,IAAA,uBAAa,EAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IAE/C,2CAA2C;IAC3C,kCAAkC;IAClC,WAAW;IACX,YAAY;IACZ,uBAAuB;IACvB,MAAM;IAEN,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,MAAM,QAAQ,GAAmC;QAC/C,KAAK;QACL,UAAU,EAAE,SAAS;QACrB,KAAK,EAAE,CAAC;KACT,CAAC;IAEF,OAAO,IAAA,kBAAO,EAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC,CAAC;AAnBW,QAAA,IAAI,QAmBf;AAEF;;;;;GAKG;AACI,MAAM,GAAG,GAA2B,KAAK,EAAE,KAAK,EAAE,EAAE;IACzD,MAAM,EAAE,GAAG,IAAA,0BAAgB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEzC,2CAA2C;IAC3C,4CAA4C;IAC5C,eAAe;IACf,0DAA0D;IAC1D,IAAI;IACJ,wBAAwB;IAExB,8DAA8D;IAC9D,OAAO,IAAA,mBAAQ,EAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC;AACvD,CAAC,CAAC;AAZW,QAAA,GAAG,OAYd;AAEF;;;;;;GAMG;AACI,MAAM,MAAM,GAA2B,KAAK,EAAE,KAAK,EAAE,EAAE;IAC5D,MAAM,IAAI,GAAG,IAAA,mBAAS,EAAqC,KAAK,CAAC,CAAC;IAElE,2CAA2C;IAC3C,4CAA4C;IAC5C,uBAAuB;IACvB,2BAA2B;IAC3B,MAAM;IAEN,MAAM,IAAI,GAAgB;QACxB,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;KACpC,CAAC;IAEF,OAAO,IAAA,kBAAO,EAAC,IAAI,CAAC,CAAC;AACvB,CAAC,CAAC;AAjBW,QAAA,MAAM,UAiBjB;AAEF;;;;;;GAMG;AACI,MAAM,MAAM,GAA2B,KAAK,EAAE,KAAK,EAAE,EAAE;IAC5D,MAAM,EAAE,GAAG,IAAA,0BAAgB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAA,mBAAS,EAAuC,KAAK,CAAC,CAAC;IAErE,2CAA2C;IAC3C,4CAA4C;IAC5C,eAAe;IACf,0DAA0D;IAC1D,IAAI;IACJ,wDAAwD;IACxD,2BAA2B;IAE3B,8DAA8D;IAC9D,OAAO,IAAA,mBAAQ,EAAC,oBAAoB,EAAE,aAAa,CAAC,CAAC;AACvD,CAAC,CAAC;AAdW,QAAA,MAAM,UAcjB;AAEF;;;;;GAKG;AACI,MAAM,MAAM,GAA2B,KAAK,EAAE,KAAK,EAAE,EAAE;IAC5D,MAAM,EAAE,GAAG,IAAA,0BAAgB,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IAEzC,2CAA2C;IAC3C,4CAA4C;IAC5C,eAAe;IACf,0DAA0D;IAC1D,IAAI;IACJ,kCAAkC;IAElC,OAAO,IAAA,kBAAO,EAAC,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;AACxC,CAAC,CAAC;AAXW,QAAA,MAAM,UAWjB"}
1
+ {"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/handlers/content.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- 'use strict';
1
+ "use strict";
2
2
  /**
3
3
  * Health check endpoint handler.
4
4
  *
@@ -7,9 +7,9 @@
7
7
  *
8
8
  * @packageDocumentation
9
9
  */
10
- Object.defineProperty(exports, '__esModule', { value: true });
10
+ Object.defineProperty(exports, "__esModule", { value: true });
11
11
  exports.handler = void 0;
12
- const response_1 = require('../lib/response');
12
+ const response_1 = require("../lib/response");
13
13
  /**
14
14
  * GET /health - Health check endpoint.
15
15
  *
@@ -32,12 +32,12 @@ const response_1 = require('../lib/response');
32
32
  * ```
33
33
  */
34
34
  const handler = async () => {
35
- const response = {
36
- status: 'healthy',
37
- timestamp: new Date().toISOString(),
38
- version: process.env.API_VERSION ?? '0.0.0',
39
- };
40
- return (0, response_1.success)(response);
35
+ const response = {
36
+ status: 'healthy',
37
+ timestamp: new Date().toISOString(),
38
+ version: process.env.API_VERSION ?? '0.0.0',
39
+ };
40
+ return (0, response_1.success)(response);
41
41
  };
42
42
  exports.handler = handler;
43
- //# sourceMappingURL=health.js.map
43
+ //# sourceMappingURL=health.js.map
package/lib/index.d.ts CHANGED
@@ -15,6 +15,8 @@ export type { SuccessResponse, ErrorResponse } from './lib/response';
15
15
  export { ApiError, NotFoundError, ValidationError, UnauthorizedError, ForbiddenError, ConflictError, } from './lib/errors';
16
16
  export { parseBody, requirePathParam, getQueryParam, getUserId } from './lib/request';
17
17
  export type { Handler, AuthenticatedEvent, AuthenticatedHandler, CognitoClaims, PaginatedRequest, PaginatedResponse, } from './types/api';
18
+ export { contentKeys, userKeys } from './lib/keys';
19
+ export type { PrimaryKey, GSI1Key, GSI2Key } from './lib/keys';
18
20
  export { compose } from './lib/middleware';
19
21
  export { withErrorHandler, withAuth, withValidation, withCors, withLogging } from './middleware';
20
22
  export type { ErrorHandlerOptions, AuthOptions, CorsOptions, LoggingOptions } from './middleware';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,UAAU,EACV,OAAO,GACR,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,QAAQ,EACR,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGtF,YAAY,EACV,OAAO,EACP,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGjG,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGlG,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAGH,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,YAAY,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AAGtD,OAAO,EACL,OAAO,EACP,KAAK,EACL,QAAQ,EACR,YAAY,EACZ,SAAS,EACT,UAAU,EACV,OAAO,GACR,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAGrE,OAAO,EACL,QAAQ,EACR,aAAa,EACb,eAAe,EACf,iBAAiB,EACjB,cAAc,EACd,aAAa,GACd,MAAM,cAAc,CAAC;AAGtB,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAGtF,YAAY,EACV,OAAO,EACP,kBAAkB,EAClB,oBAAoB,EACpB,aAAa,EACb,gBAAgB,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACnD,YAAY,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG/D,OAAO,EAAE,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAG3C,OAAO,EAAE,gBAAgB,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAGjG,YAAY,EAAE,mBAAmB,EAAE,WAAW,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAGlG,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC"}
package/lib/index.js CHANGED
@@ -10,7 +10,7 @@
10
10
  * @packageDocumentation
11
11
  */
12
12
  Object.defineProperty(exports, "__esModule", { value: true });
13
- exports.withLogging = exports.withCors = exports.withValidation = exports.withAuth = exports.withErrorHandler = exports.compose = exports.getUserId = exports.getQueryParam = exports.requirePathParam = exports.parseBody = exports.ConflictError = exports.ForbiddenError = exports.UnauthorizedError = exports.ValidationError = exports.NotFoundError = exports.ApiError = exports.created = exports.badRequest = exports.forbidden = exports.unauthorized = exports.notFound = exports.error = exports.success = exports.FndApiProject = void 0;
13
+ exports.withLogging = exports.withCors = exports.withValidation = exports.withAuth = exports.withErrorHandler = exports.compose = exports.userKeys = exports.contentKeys = exports.getUserId = exports.getQueryParam = exports.requirePathParam = exports.parseBody = exports.ConflictError = exports.ForbiddenError = exports.UnauthorizedError = exports.ValidationError = exports.NotFoundError = exports.ApiError = exports.created = exports.badRequest = exports.forbidden = exports.unauthorized = exports.notFound = exports.error = exports.success = exports.FndApiProject = void 0;
14
14
  // Main project class
15
15
  var api_project_1 = require("./api-project");
16
16
  Object.defineProperty(exports, "FndApiProject", { enumerable: true, get: function () { return api_project_1.FndApiProject; } });
@@ -37,6 +37,10 @@ Object.defineProperty(exports, "parseBody", { enumerable: true, get: function ()
37
37
  Object.defineProperty(exports, "requirePathParam", { enumerable: true, get: function () { return request_1.requirePathParam; } });
38
38
  Object.defineProperty(exports, "getQueryParam", { enumerable: true, get: function () { return request_1.getQueryParam; } });
39
39
  Object.defineProperty(exports, "getUserId", { enumerable: true, get: function () { return request_1.getUserId; } });
40
+ // Key builders for DynamoDB single-table design
41
+ var keys_1 = require("./lib/keys");
42
+ Object.defineProperty(exports, "contentKeys", { enumerable: true, get: function () { return keys_1.contentKeys; } });
43
+ Object.defineProperty(exports, "userKeys", { enumerable: true, get: function () { return keys_1.userKeys; } });
40
44
  // Middleware composition
41
45
  var middleware_1 = require("./lib/middleware");
42
46
  Object.defineProperty(exports, "compose", { enumerable: true, get: function () { return middleware_1.compose; } });
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,qBAAqB;AACrB,6CAA8C;AAArC,4GAAA,aAAa,OAAA;AAKtB,mBAAmB;AACnB,2CAQwB;AAPtB,mGAAA,OAAO,OAAA;AACP,iGAAA,KAAK,OAAA;AACL,oGAAA,QAAQ,OAAA;AACR,wGAAA,YAAY,OAAA;AACZ,qGAAA,SAAS,OAAA;AACT,sGAAA,UAAU,OAAA;AACV,mGAAA,OAAO,OAAA;AAIT,gBAAgB;AAChB,uCAOsB;AANpB,kGAAA,QAAQ,OAAA;AACR,uGAAA,aAAa,OAAA;AACb,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,wGAAA,cAAc,OAAA;AACd,uGAAA,aAAa,OAAA;AAGf,oBAAoB;AACpB,yCAAsF;AAA7E,oGAAA,SAAS,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,oGAAA,SAAS,OAAA;AAY9D,yBAAyB;AACzB,+CAA2C;AAAlC,qGAAA,OAAO,OAAA;AAEhB,uBAAuB;AACvB,2CAAiG;AAAxF,8GAAA,gBAAgB,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,yGAAA,WAAW,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AAEH,qBAAqB;AACrB,6CAA8C;AAArC,4GAAA,aAAa,OAAA;AAKtB,mBAAmB;AACnB,2CAQwB;AAPtB,mGAAA,OAAO,OAAA;AACP,iGAAA,KAAK,OAAA;AACL,oGAAA,QAAQ,OAAA;AACR,wGAAA,YAAY,OAAA;AACZ,qGAAA,SAAS,OAAA;AACT,sGAAA,UAAU,OAAA;AACV,mGAAA,OAAO,OAAA;AAIT,gBAAgB;AAChB,uCAOsB;AANpB,kGAAA,QAAQ,OAAA;AACR,uGAAA,aAAa,OAAA;AACb,yGAAA,eAAe,OAAA;AACf,2GAAA,iBAAiB,OAAA;AACjB,wGAAA,cAAc,OAAA;AACd,uGAAA,aAAa,OAAA;AAGf,oBAAoB;AACpB,yCAAsF;AAA7E,oGAAA,SAAS,OAAA;AAAE,2GAAA,gBAAgB,OAAA;AAAE,wGAAA,aAAa,OAAA;AAAE,oGAAA,SAAS,OAAA;AAY9D,gDAAgD;AAChD,mCAAmD;AAA1C,mGAAA,WAAW,OAAA;AAAE,gGAAA,QAAQ,OAAA;AAG9B,yBAAyB;AACzB,+CAA2C;AAAlC,qGAAA,OAAO,OAAA;AAEhB,uBAAuB;AACvB,2CAAiG;AAAxF,8GAAA,gBAAgB,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,4GAAA,cAAc,OAAA;AAAE,sGAAA,QAAQ,OAAA;AAAE,yGAAA,WAAW,OAAA"}