MIRROR: javascript for 馃悳's, a tiny runtime with big ambitions
1#include "yyjson.h"
2#include <stdlib.h>
3#include <string.h>
4
5static inline void copy_string_field(yyjson_mut_doc *doc, yyjson_mut_val *dest, yyjson_val *src, const char *key) {
6 yyjson_val *val = yyjson_obj_get(src, key);
7 if (val && yyjson_is_str(val)) {
8 yyjson_mut_obj_add_strncpy(doc, dest, key, yyjson_get_str(val), yyjson_get_len(val));
9 }
10}
11
12static inline void copy_string_array(yyjson_mut_doc *doc, yyjson_mut_val *dest, yyjson_val *src, const char *key) {
13 yyjson_val *arr = yyjson_obj_get(src, key);
14 if (!arr || !yyjson_is_arr(arr)) return;
15
16 yyjson_mut_val *out_arr = yyjson_mut_arr(doc);
17 yyjson_val *elem;
18 size_t idx, max;
19 yyjson_arr_foreach(arr, idx, max, elem) {
20 if (yyjson_is_str(elem)) {
21 yyjson_mut_arr_add_strncpy(doc, out_arr, yyjson_get_str(elem), yyjson_get_len(elem));
22 }
23 }
24 yyjson_mut_obj_add_val(doc, dest, key, out_arr);
25}
26
27static inline void copy_deps_object(yyjson_mut_doc *doc, yyjson_mut_val *dest, yyjson_val *src, const char *key) {
28 yyjson_val *deps = yyjson_obj_get(src, key);
29 if (!deps || !yyjson_is_obj(deps)) return;
30
31 yyjson_mut_val *out_deps = yyjson_mut_obj(doc);
32 yyjson_val *dep_key, *dep_val;
33 size_t idx, max;
34 yyjson_obj_foreach(deps, idx, max, dep_key, dep_val) {
35 const char *k = yyjson_get_str(dep_key);
36 size_t klen = yyjson_get_len(dep_key);
37
38 if (yyjson_is_str(dep_val)) {
39 yyjson_mut_val *mk = yyjson_mut_strncpy(doc, k, klen);
40 yyjson_mut_val *mv = yyjson_mut_strncpy(doc, yyjson_get_str(dep_val), yyjson_get_len(dep_val));
41 yyjson_mut_obj_add(out_deps, mk, mv);
42 } else if (yyjson_is_obj(dep_val)) {
43 yyjson_mut_val *nested = yyjson_mut_obj(doc);
44 yyjson_mut_val *mk = yyjson_mut_strncpy(doc, k, klen);
45 yyjson_mut_obj_add(out_deps, mk, nested);
46
47 yyjson_val *nk, *nv;
48 size_t ni, nm;
49 yyjson_obj_foreach(dep_val, ni, nm, nk, nv) {
50 const char *nks = yyjson_get_str(nk);
51 size_t nkl = yyjson_get_len(nk);
52 if (yyjson_is_str(nv)) {
53 yyjson_mut_val *nmk = yyjson_mut_strncpy(doc, nks, nkl);
54 yyjson_mut_val *nmv = yyjson_mut_strncpy(doc, yyjson_get_str(nv), yyjson_get_len(nv));
55 yyjson_mut_obj_add(nested, nmk, nmv);
56 } else if (yyjson_is_bool(nv)) {
57 yyjson_mut_val *nmk = yyjson_mut_strncpy(doc, nks, nkl);
58 yyjson_mut_obj_add(nested, nmk, yyjson_mut_bool(doc, yyjson_get_bool(nv)));
59 }
60 }
61 }
62 }
63 yyjson_mut_obj_add_val(doc, dest, key, out_deps);
64}
65
66static inline void copy_bin_field(yyjson_mut_doc *doc, yyjson_mut_val *dest, yyjson_val *src) {
67 yyjson_val *bin = yyjson_obj_get(src, "bin");
68 if (!bin) return;
69
70 if (yyjson_is_str(bin)) {
71 yyjson_mut_obj_add_strncpy(doc, dest, "bin", yyjson_get_str(bin), yyjson_get_len(bin));
72 } else if (yyjson_is_obj(bin)) {
73 yyjson_mut_val *out_bin = yyjson_mut_obj(doc);
74 yyjson_val *bk, *bv;
75 size_t idx, max;
76 yyjson_obj_foreach(bin, idx, max, bk, bv) {
77 if (yyjson_is_str(bv)) {
78 yyjson_mut_val *mk = yyjson_mut_strncpy(doc, yyjson_get_str(bk), yyjson_get_len(bk));
79 yyjson_mut_val *mv = yyjson_mut_strncpy(doc, yyjson_get_str(bv), yyjson_get_len(bv));
80 yyjson_mut_obj_add(out_bin, mk, mv);
81 }
82 }
83 yyjson_mut_obj_add_val(doc, dest, "bin", out_bin);
84 }
85}
86
87static inline void copy_dist(yyjson_mut_doc *doc, yyjson_mut_val *dest, yyjson_val *src) {
88 yyjson_val *dist = yyjson_obj_get(src, "dist");
89 if (!dist || !yyjson_is_obj(dist)) return;
90
91 yyjson_mut_val *out_dist = yyjson_mut_obj(doc);
92 copy_string_field(doc, out_dist, dist, "tarball");
93 copy_string_field(doc, out_dist, dist, "integrity");
94 copy_string_field(doc, out_dist, dist, "shasum");
95 yyjson_mut_obj_add_val(doc, dest, "dist", out_dist);
96}
97
98char *strip_npm_metadata(const char *json_data, size_t json_len, size_t *out_len) {
99 yyjson_doc *doc = yyjson_read(json_data, json_len, 0);
100 if (!doc) return NULL;
101
102 yyjson_val *root = yyjson_doc_get_root(doc);
103 if (!root || !yyjson_is_obj(root)) {
104 yyjson_doc_free(doc);
105 return NULL;
106 }
107
108 yyjson_mut_doc *mut_doc = yyjson_mut_doc_new(NULL);
109 if (!mut_doc) {
110 yyjson_doc_free(doc);
111 return NULL;
112 }
113
114 yyjson_mut_val *out_root = yyjson_mut_obj(mut_doc);
115 yyjson_mut_doc_set_root(mut_doc, out_root);
116
117 copy_string_field(mut_doc, out_root, root, "name");
118
119 yyjson_val *versions = yyjson_obj_get(root, "versions");
120 if (versions && yyjson_is_obj(versions)) {
121 yyjson_mut_val *out_versions = yyjson_mut_obj(mut_doc);
122
123 yyjson_val *vkey, *vval;
124 size_t idx, max;
125 yyjson_obj_foreach(versions, idx, max, vkey, vval) {
126 if (!yyjson_is_obj(vval)) continue;
127
128 yyjson_mut_val *out_ver = yyjson_mut_obj(mut_doc);
129 yyjson_mut_val *mk = yyjson_mut_strncpy(mut_doc, yyjson_get_str(vkey), yyjson_get_len(vkey));
130 yyjson_mut_obj_add(out_versions, mk, out_ver);
131
132 copy_string_field(mut_doc, out_ver, vval, "version");
133 copy_deps_object(mut_doc, out_ver, vval, "dependencies");
134 copy_deps_object(mut_doc, out_ver, vval, "peerDependencies");
135 copy_deps_object(mut_doc, out_ver, vval, "optionalDependencies");
136 copy_deps_object(mut_doc, out_ver, vval, "peerDependenciesMeta");
137 copy_dist(mut_doc, out_ver, vval);
138 copy_string_array(mut_doc, out_ver, vval, "os");
139 copy_string_array(mut_doc, out_ver, vval, "cpu");
140 copy_string_array(mut_doc, out_ver, vval, "libc");
141 copy_bin_field(mut_doc, out_ver, vval);
142 }
143 yyjson_mut_obj_add_val(mut_doc, out_root, "versions", out_versions);
144 }
145
146 yyjson_val *dist_tags = yyjson_obj_get(root, "dist-tags");
147 if (dist_tags && yyjson_is_obj(dist_tags)) {
148 yyjson_val *latest = yyjson_obj_get(dist_tags, "latest");
149 if (latest && yyjson_is_str(latest)) {
150 yyjson_mut_val *out_tags = yyjson_mut_obj(mut_doc);
151 yyjson_mut_obj_add_strncpy(mut_doc, out_tags, "latest", yyjson_get_str(latest), yyjson_get_len(latest));
152 yyjson_mut_obj_add_val(mut_doc, out_root, "dist-tags", out_tags);
153 }
154 }
155
156 char *result = yyjson_mut_write(mut_doc, 0, out_len);
157
158 yyjson_mut_doc_free(mut_doc);
159 yyjson_doc_free(doc);
160
161 return result;
162}
163
164void strip_metadata_free(char *ptr) {
165 free(ptr);
166}