wao 0.1.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 (60) hide show
  1. package/cjs/accounts.js +96 -0
  2. package/cjs/ao.js +1543 -0
  3. package/cjs/aoconnect.js +758 -0
  4. package/cjs/ar.js +794 -0
  5. package/cjs/dirname.js +7 -0
  6. package/cjs/helpers.js +381 -0
  7. package/cjs/index.js +20 -0
  8. package/cjs/utils.js +438 -0
  9. package/esm/.cache/opt.json +1 -0
  10. package/esm/accounts.js +91 -0
  11. package/esm/ao.js +737 -0
  12. package/esm/aoconnect.js +318 -0
  13. package/esm/ar.js +243 -0
  14. package/esm/dirname.js +1 -0
  15. package/esm/helpers.js +161 -0
  16. package/esm/index.js +4 -0
  17. package/esm/lua/aos-sqlite.wasm +0 -0
  18. package/esm/lua/aos.wasm +0 -0
  19. package/esm/lua/aos2.lua +33 -0
  20. package/esm/lua/aos2_0_1.wasm +0 -0
  21. package/esm/lua/atomic-asset.lua +238 -0
  22. package/esm/lua/atomic-note-library.lua +2274 -0
  23. package/esm/lua/atomic-note.lua +11 -0
  24. package/esm/lua/collection-registry.lua +202 -0
  25. package/esm/lua/collection.lua +173 -0
  26. package/esm/lua/notebook.lua +173 -0
  27. package/esm/lua/profile.lua +858 -0
  28. package/esm/lua/profile000.lua +666 -0
  29. package/esm/lua/proxy.lua +24 -0
  30. package/esm/lua/registry.lua +858 -0
  31. package/esm/lua/registry000.lua +636 -0
  32. package/esm/test.js +94 -0
  33. package/esm/utils.js +342 -0
  34. package/package.json +21 -0
  35. package/test/.cache/opt.json +1 -0
  36. package/test/accounts.js +91 -0
  37. package/test/ao.js +737 -0
  38. package/test/aoconnect.js +318 -0
  39. package/test/ar.js +243 -0
  40. package/test/dirname.js +1 -0
  41. package/test/helpers.js +161 -0
  42. package/test/index.js +4 -0
  43. package/test/lua/aos-sqlite.wasm +0 -0
  44. package/test/lua/aos.wasm +0 -0
  45. package/test/lua/aos2.lua +33 -0
  46. package/test/lua/aos2_0_1.wasm +0 -0
  47. package/test/lua/atomic-asset.lua +238 -0
  48. package/test/lua/atomic-note-library.lua +2274 -0
  49. package/test/lua/atomic-note.lua +11 -0
  50. package/test/lua/collection-registry.lua +202 -0
  51. package/test/lua/collection.lua +173 -0
  52. package/test/lua/notebook.lua +173 -0
  53. package/test/lua/profile.lua +858 -0
  54. package/test/lua/profile000.lua +666 -0
  55. package/test/lua/proxy.lua +24 -0
  56. package/test/lua/registry.lua +858 -0
  57. package/test/lua/registry000.lua +636 -0
  58. package/test/package.json +21 -0
  59. package/test/test.js +94 -0
  60. package/test/utils.js +342 -0
@@ -0,0 +1,636 @@
1
+ local json = require('json')
2
+ local sqlite3 = require('lsqlite3')
3
+
4
+ Db = Db or sqlite3.open_memory()
5
+
6
+ local function decode_message_data(data)
7
+ local status, decoded_data = pcall(json.decode, data)
8
+ if not status or type(decoded_data) ~= 'table' then
9
+ return false, nil
10
+ end
11
+ return true, decoded_data
12
+ end
13
+
14
+ local function is_authorized(profile_id, address)
15
+ if not profile_id then return true end
16
+ local query = [[
17
+ SELECT role
18
+ FROM ao_profile_authorization
19
+ WHERE profile_id = ? AND delegate_address = ?
20
+ LIMIT 1
21
+ ]]
22
+ local stmt = Db:prepare(query)
23
+ stmt:bind_values(profile_id, address)
24
+ local authorized = false
25
+ for row in stmt:nrows() do
26
+ authorized = true
27
+ break
28
+ end
29
+ stmt:finalize()
30
+ return authorized
31
+ end
32
+
33
+ local function process_profile_action(msg, profile_id_to_check_for_update)
34
+ if profile_id_to_check_for_update and not is_authorized(profile_id_to_check_for_update, msg.From) then
35
+ ao.send({
36
+ Target = msg.From,
37
+ Action = 'Authorization-Error',
38
+ Tags = {
39
+ Status = 'Error',
40
+ Message = 'Unauthorized to access this handler'
41
+ }
42
+ })
43
+ return
44
+ end
45
+ local decode_check, data = decode_message_data(msg.Data)
46
+ if not decode_check then
47
+ ao.send({
48
+ Target = msg.From,
49
+ Action = 'DB_CODE',
50
+ Tags = {
51
+ Status = 'DECODE_FAILED',
52
+ Message = "Failed to decode data"
53
+ },
54
+ Data = { Code = "DECODE_FAILED" }
55
+ })
56
+ return
57
+ end
58
+
59
+ local tags = msg.Tags or {}
60
+
61
+ --local insert_languages = [[ INSERT INTO ]]
62
+ local upsert_metadata_stmt = [[
63
+ INSERT INTO ao_profile_metadata (id, username, profile_image, cover_image, description, display_name, date_updated, date_created)
64
+ VALUES (:id, :username, :profile_image, :cover_image, :description, :display_name, :date_updated, :date_created)
65
+ ON CONFLICT(id) DO UPDATE SET
66
+ username = COALESCE(excluded.username, ao_profile_metadata.username),
67
+ profile_image = CASE
68
+ WHEN excluded.profile_image IS NULL THEN NULL
69
+ WHEN excluded.profile_image = 'NULL' THEN NULL
70
+ ELSE COALESCE(excluded.profile_image, ao_profile_metadata.profile_image, NULL)
71
+ END,
72
+ cover_image = CASE
73
+ WHEN excluded.cover_image IS NULL THEN NULL
74
+ WHEN excluded.cover_image = 'NULL' THEN NULL
75
+ ELSE COALESCE(excluded.cover_image, ao_profile_metadata.cover_image, NULL)
76
+ END,
77
+ description = CASE
78
+ WHEN excluded.description IS NULL THEN NULL
79
+ WHEN excluded.description = 'NULL' THEN NULL
80
+ ELSE COALESCE(excluded.description, ao_profile_metadata.description, NULL)
81
+ END,
82
+ display_name = CASE
83
+ WHEN excluded.display_name IS NULL THEN NULL
84
+ WHEN excluded.display_name = 'NULL' THEN NULL
85
+ ELSE COALESCE(excluded.display_name, ao_profile_metadata.display_name, NULL)
86
+ END,
87
+ date_updated = CASE
88
+ WHEN excluded.date_updated IS NULL THEN excluded.date_created
89
+ WHEN excluded.date_updated = "NULL" THEN excluded.date_created
90
+ ELSE excluded.date_updated
91
+ END,
92
+ date_created = CASE
93
+ WHEN excluded.date_created IS NULL THEN ao_profile_metadata.date_created
94
+ WHEN excluded.date_created = "NULL" THEN ao_profile_metadata.date_created
95
+ ELSE excluded.date_created
96
+ END
97
+ ]]
98
+ local upsert_meta = Db:prepare(upsert_metadata_stmt)
99
+
100
+ local names_bound = {
101
+ id = profile_id_to_check_for_update or msg.From,
102
+ username = tags.UserName or data.UserName,
103
+ profile_image = tags.ProfileImage or data.ProfileImage,
104
+ cover_image = tags.CoverImage or data.CoverImage,
105
+ description = tags.Description or data.Description,
106
+ display_name = tags.DisplayName or data.DisplayName,
107
+ date_updated = tags.DateUpdated or tags.DateCreated or data.DateUpdated or data.DateCreated,
108
+ date_created = tags.DateCreated or data.DateCreated or "NULL"
109
+ }
110
+
111
+ if upsert_meta then
112
+ upsert_meta:bind_names(names_bound)
113
+ else
114
+ ao.send({
115
+ Target = msg.From,
116
+ Action = 'DB_CODE',
117
+ Tags = {
118
+ Status = 'DB_PREPARE_FAILED',
119
+ Message = "DB PREPARED QUERY FAILED"
120
+ },
121
+ Data = { Code = "Failed to prepare insert statement" }
122
+ })
123
+ print("Failed to prepare insert statement")
124
+ return json.encode({ Code = 'DB_PREPARE_FAILED' })
125
+ end
126
+
127
+ local step_status = upsert_meta:step()
128
+ if step_status ~= sqlite3.OK and step_status ~= sqlite3.DONE and step_status ~= sqlite3.ROW then
129
+ ao.send({
130
+ Target = msg.From,
131
+ Action = 'DB_STEP_CODE',
132
+ Tags = {
133
+ Status = 'ERROR',
134
+ Message = step_status
135
+ },
136
+ Data = { DB_STEP_MSG = step_status }
137
+ })
138
+ return json.encode({ Code = step_status })
139
+ end
140
+
141
+ ao.send({
142
+ Target = msg.From,
143
+ Action = 'Success',
144
+ Tags = {
145
+ Status = 'Success',
146
+ Message = 'Record Inserted'
147
+ },
148
+ Data = json.encode(names_bound)
149
+ })
150
+
151
+ upsert_meta:finalize()
152
+ if (not profile_id_to_check_for_update) then
153
+ local check = Db:prepare('SELECT 1 FROM ao_profile_authorization WHERE delegate_address = ? LIMIT 1')
154
+ check:bind_values(msg.From)
155
+ if check:step() ~= sqlite3.ROW then
156
+ local insert_auth = Db:prepare(
157
+ 'INSERT INTO ao_profile_authorization (profile_id, delegate_address, role) VALUES (?, ?, ?)')
158
+ insert_auth:bind_values(msg.From, data.AuthorizedAddress, 'Admin')
159
+ insert_auth:step()
160
+ end
161
+ end
162
+ end
163
+
164
+ -- Handlers.add('migrate-database', ... , Db:exec [[ ALTER TABLE _ ADD new_field type ]]
165
+
166
+ Handlers.add('Prepare-Database', Handlers.utils.hasMatchingTag('Action', 'Prepare-Database'),
167
+ function(msg)
168
+ if msg.From ~= Owner and msg.From ~= ao.id then
169
+ ao.send({
170
+ Target = msg.From,
171
+ Action = 'Authorization-Error',
172
+ Tags = {
173
+ Status = 'Error',
174
+ Message = 'Unauthorized to access this handler'
175
+ }
176
+ })
177
+ return
178
+ end
179
+
180
+ --todo create tables for: languages, following, followed, topic-tags, locations, external_links, external_wallets
181
+
182
+ Db:exec [[
183
+ CREATE TABLE IF NOT EXISTS ao_profile_metadata (
184
+ id TEXT PRIMARY KEY NOT NULL,
185
+ username TEXT,
186
+ display_name TEXT,
187
+ description TEXT,
188
+ profile_image TEXT,
189
+ cover_image TEXT,
190
+ date_created INTEGER NOT NULL,
191
+ date_updated INTEGER NOT NULL
192
+ );
193
+ ]]
194
+
195
+ Db:exec [[
196
+ CREATE TABLE IF NOT EXISTS ao_profile_authorization (
197
+ profile_id TEXT NOT NULL,
198
+ delegate_address TEXT NOT NULL,
199
+ role TEXT NOT NULL,
200
+ PRIMARY KEY (profile_id, delegate_address),
201
+ FOREIGN KEY (profile_id) REFERENCES ao_profile_metadata (id) ON DELETE CASCADE
202
+ );
203
+ ]]
204
+
205
+ ao.send({
206
+ Target = Owner,
207
+ Action = 'DB-Init-Success',
208
+ Tags = {
209
+ Status = 'Success',
210
+ Message = 'Created DB'
211
+ }
212
+ })
213
+ end)
214
+
215
+ -- Data - { ProfileIds [] }
216
+ Handlers.add('Get-Metadata-By-ProfileIds', Handlers.utils.hasMatchingTag('Action', 'Get-Metadata-By-ProfileIds'),
217
+ function(msg)
218
+ local decode_check, data = decode_message_data(msg.Data)
219
+
220
+ if decode_check and data then
221
+ if not data.ProfileIds then
222
+ ao.send({
223
+ Target = msg.From,
224
+ Action = 'Input-Error',
225
+ Tags = {
226
+ Status = 'Error',
227
+ Message = 'Invalid arguments, required { ProfileIds }'
228
+ }
229
+ })
230
+ return
231
+ end
232
+
233
+ local metadata = {}
234
+ if data.ProfileIds and #data.ProfileIds > 0 then
235
+ local profileIdList = {}
236
+ for _, id in ipairs(data.ProfileIds) do
237
+ table.insert(profileIdList, string.format("'%s'", id))
238
+ end
239
+ local idString = table.concat(profileIdList, ',')
240
+
241
+ if #idString > 0 then
242
+ local query = string.format('SELECT * FROM ao_profile_metadata WHERE id IN (%s)', idString)
243
+
244
+ local foundRows = false
245
+ for row in Db:nrows(query) do
246
+ foundRows = true
247
+ table.insert(metadata,
248
+ {
249
+ ProfileId = row.id,
250
+ Username = row.username,
251
+ ProfileImage = row.profile_image,
252
+ CoverImage =
253
+ row.cover_image,
254
+ Description = row.description,
255
+ DisplayName = row.display_name
256
+ })
257
+ end
258
+
259
+ if not foundRows then
260
+ print('No rows found matching the criteria.')
261
+ end
262
+
263
+ ao.send({
264
+ Target = msg.From,
265
+ Action = 'Get-Metadata-Success',
266
+ Tags = {
267
+ Status = 'Success',
268
+ Message = 'Metadata retrieved',
269
+ },
270
+ Data = json.encode(metadata)
271
+ })
272
+ else
273
+ print('Profile ID list is empty after validation.')
274
+ end
275
+ else
276
+ print('No ProfileIds provided or the list is empty.')
277
+ end
278
+ else
279
+ ao.send({
280
+ Target = msg.From,
281
+ Action = 'Input-Error',
282
+ Tags = {
283
+ Status = 'Error',
284
+ Message = string.format(
285
+ 'Failed to parse data, received: %s. %s.', msg.Data,
286
+ 'Data must be an object - { ProfileIds }')
287
+ }
288
+ })
289
+ end
290
+ end)
291
+
292
+ -- Data - { Address }
293
+ Handlers.add('Get-Profiles-By-Delegate', Handlers.utils.hasMatchingTag('Action', 'Get-Profiles-By-Delegate'),
294
+ function(msg)
295
+ local decode_check, data = decode_message_data(msg.Data)
296
+
297
+ if decode_check and data then
298
+ if not data.Address then
299
+ ao.send({
300
+ Target = msg.From,
301
+ Action = 'Input-Error',
302
+ Tags = {
303
+ Status = 'Error',
304
+ Message = 'Invalid arguments, required { Address }'
305
+ }
306
+ })
307
+ return
308
+ end
309
+
310
+ local associated_profiles = {}
311
+
312
+ local authorization_lookup = Db:prepare([[
313
+ SELECT profile_id, delegate_address, role
314
+ FROM ao_profile_authorization
315
+ WHERE delegate_address = ?
316
+ ]])
317
+
318
+ authorization_lookup:bind_values(data.Address)
319
+
320
+ for row in authorization_lookup:nrows() do
321
+ table.insert(associated_profiles, {
322
+ ProfileId = row.profile_id,
323
+ CallerAddress = row.delegate_address,
324
+ Role = row.role
325
+ })
326
+ end
327
+
328
+ authorization_lookup:finalize()
329
+
330
+ if #associated_profiles > 0 then
331
+ ao.send({
332
+ Target = msg.From,
333
+ Action = 'Profile-Success',
334
+ Tags = {
335
+ Status = 'Success',
336
+ Message = 'Associated profiles fetched'
337
+ },
338
+ Data = json.encode(associated_profiles)
339
+ })
340
+ else
341
+ ao.send({
342
+ Target = msg.From,
343
+ Action = 'Profile-Error',
344
+ Tags = {
345
+ Status = 'Error',
346
+ Message = 'This wallet address is not associated with a profile'
347
+ }
348
+ })
349
+ end
350
+ else
351
+ ao.send({
352
+ Target = msg.From,
353
+ Action = 'Input-Error',
354
+ Tags = {
355
+ Status = 'Error',
356
+ Message = string.format(
357
+ 'Failed to parse data, received: %s. %s.', msg.Data,
358
+ 'Data must be an object - { Address }')
359
+ }
360
+ })
361
+ end
362
+ end)
363
+
364
+ -- Data - { Addresses }
365
+ Handlers.add('Read-Profiles', Handlers.utils.hasMatchingTag('Action', 'Read-Profiles'),
366
+ function(msg)
367
+ local json = require 'json'
368
+
369
+ local function decode_message_data(data)
370
+ local status, decoded_data = pcall(json.decode, data)
371
+ if not status or type(decoded_data) ~= 'table' then
372
+ return false, nil
373
+ end
374
+ return true, decoded_data
375
+ end
376
+
377
+ local decode_check, data = decode_message_data(msg.Data)
378
+
379
+ if decode_check and data then
380
+ if not data.Addresses or type(data.Addresses) ~= 'table' then
381
+ ao.send({
382
+ Target = msg.From,
383
+ Action = 'Input-Error',
384
+ Tags = {
385
+ Status = 'Error',
386
+ Message = 'Invalid arguments, required { Addresses }'
387
+ }
388
+ })
389
+ return
390
+ end
391
+
392
+ local associated_profiles = {}
393
+
394
+ -- Create placeholders
395
+ local placeholders = {}
396
+ for i = 1, #data.Addresses do
397
+ table.insert(placeholders, '?')
398
+ end
399
+ local placeholders_str = table.concat(placeholders, ', ')
400
+
401
+ -- Prepare the SQL query
402
+ local sql_query = [[
403
+ SELECT profile_id, delegate_address
404
+ FROM ao_profile_authorization
405
+ WHERE delegate_address IN (]] .. placeholders_str .. [[)
406
+ ]]
407
+
408
+ local authorization_lookup = Db:prepare(sql_query)
409
+
410
+ -- Bind values
411
+ for i, address in ipairs(data.Addresses) do
412
+ authorization_lookup:bind(i, address)
413
+ end
414
+
415
+ -- Execute query and gather results
416
+ for row in authorization_lookup:nrows() do
417
+ table.insert(associated_profiles, {
418
+ ProfileId = row.profile_id,
419
+ CallerAddress = row.delegate_address
420
+ })
421
+ end
422
+
423
+ authorization_lookup:finalize()
424
+
425
+ if #associated_profiles > 0 then
426
+ ao.send({
427
+ Target = msg.From,
428
+ Action = 'Profile-Success',
429
+ Tags = {
430
+ Status = 'Success',
431
+ Message = 'Associated profiles fetched'
432
+ },
433
+ Data = json.encode(associated_profiles)
434
+ })
435
+ else
436
+ ao.send({
437
+ Target = msg.From,
438
+ Action = 'Profile-Error',
439
+ Tags = {
440
+ Status = 'Error',
441
+ Message = 'No profiles associated with the provided addresses'
442
+ }
443
+ })
444
+ end
445
+ else
446
+ ao.send({
447
+ Target = msg.From,
448
+ Action = 'Input-Error',
449
+ Tags = {
450
+ Status = 'Error',
451
+ Message = string.format(
452
+ 'Failed to parse data, received: %s. %s.', msg.Data,
453
+ 'Data must be an object - { Addresses }')
454
+ }
455
+ })
456
+ end
457
+ end)
458
+
459
+ -- Create-Profile Handler
460
+ Handlers.add('Create-Profile', Handlers.utils.hasMatchingTag('Action', 'Create-Profile'),
461
+ function(msg)
462
+ process_profile_action(msg, nil)
463
+ end)
464
+
465
+ -- Update-Profile Handler
466
+ Handlers.add('Update-Profile', Handlers.utils.hasMatchingTag('Action', 'Update-Profile'),
467
+ function(msg)
468
+ process_profile_action(msg, msg.Target)
469
+ end)
470
+
471
+ Handlers.add('Count-Profiles', Handlers.utils.hasMatchingTag('Action', 'Count-Profiles'),
472
+ function(msg)
473
+ local count_sql = [[
474
+ SELECT COUNT(*)
475
+ FROM ao_profile_metadata
476
+ ]]
477
+ local stmt = Db:prepare(count_sql)
478
+ local result = stmt:step()
479
+ local count = 0
480
+
481
+ if result == sqlite3.ROW then
482
+ count = stmt:get_value(0)
483
+ else
484
+ count = -1
485
+ end
486
+
487
+ ao.send({
488
+ Target = msg.From,
489
+ Action = 'Count-Profiles-Success',
490
+ Tags = {
491
+ Status = 'Success',
492
+ Message = 'Profiles Counted',
493
+ },
494
+ Data = json.encode({ Count = count })
495
+ })
496
+ return json.encode({ Count = count })
497
+ end)
498
+
499
+ Handlers.add('Read-Metadata', Handlers.utils.hasMatchingTag('Action', 'Read-Metadata'),
500
+ function(msg)
501
+ local metadata = {}
502
+ local status, err = pcall(function()
503
+ for row in Db:nrows('SELECT username, profile_image, cover_image, description, display_name, date_updated, date_created FROM ao_profile_metadata') do
504
+ table.insert(metadata, {
505
+ Username = row.username,
506
+ ProfileImage = row.profile_image,
507
+ CoverImage = row.cover_image,
508
+ Description = row.description,
509
+ DisplayName = row.display_name,
510
+ DateCreated = row.date_created,
511
+ DateUpdated = row.date_updated
512
+ })
513
+ end
514
+ end)
515
+ if not status then
516
+ print("Error: ", err)
517
+ return
518
+ end
519
+ ao.send({
520
+ Target = msg.From,
521
+ Action = 'Read-Metadata-Success',
522
+ Tags = {
523
+ Status = 'Success',
524
+ Message = 'Metadata retrieved',
525
+ },
526
+ Data = json.encode(metadata)
527
+ })
528
+
529
+ return json.encode(metadata)
530
+ end)
531
+
532
+
533
+ Handlers.add('Read-Auth', Handlers.utils.hasMatchingTag('Action', 'Read-Auth'),
534
+ function(msg)
535
+ local metadata = {}
536
+ local status, err = pcall(function()
537
+ for row in Db:nrows('SELECT profile_id, delegate_address, role FROM ao_profile_authorization') do
538
+ table.insert(metadata, {
539
+ ProfileId = row.profile_id,
540
+ CallerAddress = row.delegate_address,
541
+ Role = row.role,
542
+ })
543
+ end
544
+ end)
545
+ if not status then
546
+ print("Error: ", err)
547
+ return
548
+ end
549
+ ao.send({
550
+ Target = msg.From,
551
+ Action = 'Read-Metadata-Success',
552
+ Tags = {
553
+ Status = 'Success',
554
+ Message = 'Metadata retrieved',
555
+ },
556
+ Data = json.encode(metadata)
557
+ })
558
+ return json.encode(metadata)
559
+ end)
560
+
561
+ Handlers.add('Read-Profile', Handlers.utils.hasMatchingTag('Action', 'Read-Profile'),
562
+ function(msg)
563
+ local decode_check, data = decode_message_data(msg.Data)
564
+
565
+ if decode_check ~= true then
566
+ ao.send({
567
+ Target = msg.From,
568
+ Action = 'DB_CODE',
569
+ Tags = {
570
+ Status = 'DECODE_FAILED',
571
+ Message = "Failed to decode data"
572
+ },
573
+ Data = { Code = "DECODE_FAILED" }
574
+ })
575
+ return
576
+ end
577
+
578
+ local selectsql = [[
579
+ SELECT *
580
+ FROM ao_profile_metadata
581
+ WHERE id = ?
582
+ ]]
583
+
584
+ local row
585
+ local select_stmt = Db:prepare(selectsql)
586
+ local bind = -1
587
+ if select_stmt then
588
+ bind = select_stmt:bind_values(data.ProfileId)
589
+ else
590
+ ao.send({
591
+ Target = msg.From,
592
+ Action = 'DB_CODE',
593
+ Tags = {
594
+ Status = 'DB_PREPARE_FAILED',
595
+ Message = "DB PREPARED QUERY FAILED"
596
+ },
597
+ Data = { Code = "Failed to prepare select statement" }
598
+ })
599
+ print("Failed to prepare select statement")
600
+ return json.encode({ Code = 'DB_PREPARE_FAILED' })
601
+ end
602
+
603
+ local step_status = select_stmt:step()
604
+ if step_status ~= sqlite3.OK and step_status ~= sqlite3.DONE and step_status ~= sqlite3.ROW then
605
+ ao.send({
606
+ Target = msg.From,
607
+ Action = 'DB_STEP_CODE',
608
+ Tags = {
609
+ Status = 'ERROR',
610
+ Message = 'sqlite step error'
611
+ },
612
+ Data = { DB_STEP_MSG = step_status }
613
+ })
614
+ return json.encode({ Code = step_status })
615
+ end
616
+
617
+ row = select_stmt:get_named_values()
618
+ local metadata = {
619
+ Username = row.username,
620
+ ProfileImage = row.profile_image,
621
+ CoverImage = row.cover_image,
622
+ Description = row.description,
623
+ DisplayName = row.display_name,
624
+ DateCreated = row.date_created,
625
+ DateUpdated = row.date_updated
626
+ }
627
+ ao.send({
628
+ Target = msg.From,
629
+ Action = 'Success',
630
+ Tags = {
631
+ Status = 'Success',
632
+ Message = 'Record Inserted'
633
+ },
634
+ Data = json.encode(metadata)
635
+ })
636
+ end)
@@ -0,0 +1,21 @@
1
+ {
2
+ "name": "wao",
3
+ "version": "0.1.0",
4
+ "description": "",
5
+ "type": "module",
6
+ "module": "index.js",
7
+ "engines": {
8
+ "node": ">=20.0.0"
9
+ },
10
+ "author": "",
11
+ "license": "MIT",
12
+ "dependencies": {
13
+ "@babel/plugin-transform-modules-commonjs": "^7.24.8",
14
+ "@permaweb/ao-loader": "^0.0.43",
15
+ "@permaweb/aoconnect": "^0.0.61",
16
+ "arbundles": "^0.11.1",
17
+ "arweave": "^1.15.1",
18
+ "base64url": "^3.0.1",
19
+ "ramda": "^0.30.1"
20
+ }
21
+ }