@codecks/fetch 0.0.4 → 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.
- package/dist/index.d.ts +3 -3
- package/dist/index.js +53 -36
- package/package.json +9 -1
package/dist/index.d.ts
CHANGED
|
@@ -2755,7 +2755,7 @@ type Filter<T extends AnyDesc, TMap extends ModelMap$3> = SimpleFilter<T, TMap>
|
|
|
2755
2755
|
//#region src/query-type.d.ts
|
|
2756
2756
|
type ModelMap$2 = Record<string, AnyDesc>;
|
|
2757
2757
|
interface ModelQuery<T extends AnyDesc, TMap extends ModelMap$2> {
|
|
2758
|
-
fields?: (keyof T["fields"])[];
|
|
2758
|
+
fields?: (keyof T["fields"] & string)[];
|
|
2759
2759
|
relations?: RelQuery<T, TMap>;
|
|
2760
2760
|
}
|
|
2761
2761
|
interface SimpleHasManyQuery<T extends AnyDesc, TMap extends ModelMap$2> extends ModelQuery<T, TMap> {
|
|
@@ -2873,7 +2873,7 @@ declare const _rootDesc: ModelDesc<"_root", {}, {
|
|
|
2873
2873
|
}>;
|
|
2874
2874
|
}, []>;
|
|
2875
2875
|
//#endregion
|
|
2876
|
-
//#region src/loader-utils.d.ts
|
|
2876
|
+
//#region src/loaders/loader-utils.d.ts
|
|
2877
2877
|
type ModelMap$1 = typeof modelMap;
|
|
2878
2878
|
type DataLoader = {
|
|
2879
2879
|
fetchModel: <K extends keyof ModelMap$1, Id extends string, const Q extends ModelQuery<ModelMap$1[K], ModelMap$1>>(model: K, id: Id[], q: Q) => Promise<Record<Id, InferModelQuery<ModelMap$1[K], Q, ModelMap$1>>>;
|
|
@@ -2888,7 +2888,7 @@ type FetchOptions = {
|
|
|
2888
2888
|
timeout?: number;
|
|
2889
2889
|
};
|
|
2890
2890
|
//#endregion
|
|
2891
|
-
//#region src/simple-loader.d.ts
|
|
2891
|
+
//#region src/loaders/simple-loader.d.ts
|
|
2892
2892
|
type SimpleLoaderOptions = FetchOptions;
|
|
2893
2893
|
//#endregion
|
|
2894
2894
|
//#region src/index.d.ts
|
package/dist/index.js
CHANGED
|
@@ -2952,7 +2952,7 @@ const modelMap = {
|
|
|
2952
2952
|
};
|
|
2953
2953
|
|
|
2954
2954
|
//#endregion
|
|
2955
|
-
//#region src/loader-utils.ts
|
|
2955
|
+
//#region src/loaders/loader-utils.ts
|
|
2956
2956
|
const configuredFetch = async (opts, url, init = {}) => {
|
|
2957
2957
|
const fetchImpl = opts.fetch || globalThis.fetch;
|
|
2958
2958
|
const headers = new Headers(init.headers);
|
|
@@ -2965,6 +2965,10 @@ const configuredFetch = async (opts, url, init = {}) => {
|
|
|
2965
2965
|
return fetchImpl(fullUrl, {
|
|
2966
2966
|
...init,
|
|
2967
2967
|
headers
|
|
2968
|
+
}).then(async (r) => {
|
|
2969
|
+
const content = await r.json();
|
|
2970
|
+
if (r.status !== 200) throw new Error(`[${r.status}] ${JSON.stringify(content)}`);
|
|
2971
|
+
return content;
|
|
2968
2972
|
});
|
|
2969
2973
|
};
|
|
2970
2974
|
|
|
@@ -3031,7 +3035,16 @@ var ModelPool = class {
|
|
|
3031
3035
|
|
|
3032
3036
|
//#endregion
|
|
3033
3037
|
//#region src/query-helpers.ts
|
|
3038
|
+
const normalizeQuery = (q) => {
|
|
3039
|
+
return JSON.stringify(q);
|
|
3040
|
+
};
|
|
3034
3041
|
const getRelKey = (r, k) => {
|
|
3042
|
+
const getSuffix = () => {
|
|
3043
|
+
if (r.type === "exists") return `exists:`;
|
|
3044
|
+
if (r.type === "count") return `count:`;
|
|
3045
|
+
return "";
|
|
3046
|
+
};
|
|
3047
|
+
const suffix = getSuffix();
|
|
3035
3048
|
const isPlainKey = () => {
|
|
3036
3049
|
if (r.type === "first") return false;
|
|
3037
3050
|
if (r.filter && Object.keys(r.filter).length > 0) return false;
|
|
@@ -3040,7 +3053,7 @@ const getRelKey = (r, k) => {
|
|
|
3040
3053
|
}
|
|
3041
3054
|
return true;
|
|
3042
3055
|
};
|
|
3043
|
-
if (isPlainKey()) return k
|
|
3056
|
+
if (isPlainKey()) return `${suffix}${k}`;
|
|
3044
3057
|
const q = { ...r.filter };
|
|
3045
3058
|
if (r.type === "first") {
|
|
3046
3059
|
q.$first = true;
|
|
@@ -3051,41 +3064,53 @@ const getRelKey = (r, k) => {
|
|
|
3051
3064
|
if (r.offset) q.$offset = r.offset;
|
|
3052
3065
|
if (r.orderBy) q.$order = r.orderBy;
|
|
3053
3066
|
}
|
|
3054
|
-
return `${k}(${
|
|
3067
|
+
return `${suffix}${k}(${normalizeQuery(q)})`;
|
|
3068
|
+
};
|
|
3069
|
+
const processRelations = (rels) => {
|
|
3070
|
+
const result = {};
|
|
3071
|
+
for (const [key, relq] of Object.entries(rels)) {
|
|
3072
|
+
const asArray = Array.isArray(relq) ? relq : [relq];
|
|
3073
|
+
for (const rel of asArray) {
|
|
3074
|
+
if (!rel) continue;
|
|
3075
|
+
result[getRelKey(rel, key)] = makeRelQuerySerializable(rel);
|
|
3076
|
+
}
|
|
3077
|
+
}
|
|
3078
|
+
return result;
|
|
3055
3079
|
};
|
|
3056
|
-
const
|
|
3080
|
+
const makeModelQuerySerializable = (q) => {
|
|
3081
|
+
if (!q.relations) return q;
|
|
3082
|
+
return {
|
|
3083
|
+
...q,
|
|
3084
|
+
relations: processRelations(q.relations)
|
|
3085
|
+
};
|
|
3086
|
+
};
|
|
3087
|
+
const makeRelQuerySerializable = (r) => {
|
|
3088
|
+
if (r.type === "exists" || r.type === "count") return { asField: true };
|
|
3089
|
+
return {
|
|
3090
|
+
asField: false,
|
|
3091
|
+
fields: r.fields,
|
|
3092
|
+
relations: r.relations ? processRelations(r.relations) : void 0
|
|
3093
|
+
};
|
|
3094
|
+
};
|
|
3095
|
+
const serializeModel = (q) => {
|
|
3057
3096
|
const list = q.fields ? [...q.fields] : [];
|
|
3058
3097
|
if (!q.relations) return list;
|
|
3059
3098
|
const relObj = {};
|
|
3060
|
-
Object.entries(q.relations).forEach(([k,
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
switch (r?.type) {
|
|
3064
|
-
case "count": {
|
|
3065
|
-
list.push(`count:${getRelKey(r, k)}`);
|
|
3066
|
-
break;
|
|
3067
|
-
}
|
|
3068
|
-
case "exists": {
|
|
3069
|
-
list.push(`exists:${getRelKey(r, k)}`);
|
|
3070
|
-
break;
|
|
3071
|
-
}
|
|
3072
|
-
default:
|
|
3073
|
-
relObj[getRelKey(r, k)] = serializeModel(r, modelDesc);
|
|
3074
|
-
break;
|
|
3075
|
-
}
|
|
3076
|
-
});
|
|
3099
|
+
Object.entries(q.relations).forEach(([k, r]) => {
|
|
3100
|
+
if (r.asField) list.push(k);
|
|
3101
|
+
else relObj[k] = serializeModel(r);
|
|
3077
3102
|
});
|
|
3078
3103
|
if (Object.keys(relObj).length) list.push(relObj);
|
|
3079
3104
|
return list;
|
|
3080
3105
|
};
|
|
3081
|
-
const serializeInstanceQuery = (q, instances
|
|
3106
|
+
const serializeInstanceQuery = (q, instances) => {
|
|
3082
3107
|
return Object.fromEntries(instances.map((instance) => {
|
|
3083
3108
|
const name = instance["~model"];
|
|
3084
3109
|
const getKey = () => {
|
|
3085
3110
|
if (name === "_root") return "_root";
|
|
3086
3111
|
return `${name}(${instance["~key"]})`;
|
|
3087
3112
|
};
|
|
3088
|
-
return [getKey(), serializeModel(q
|
|
3113
|
+
return [getKey(), serializeModel(q)];
|
|
3089
3114
|
}));
|
|
3090
3115
|
};
|
|
3091
3116
|
|
|
@@ -3124,12 +3149,9 @@ const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
|
|
|
3124
3149
|
const relKey = getRelKey(relEntry, relName);
|
|
3125
3150
|
const val = instance[relKey];
|
|
3126
3151
|
switch (relEntry.type) {
|
|
3127
|
-
case "count":
|
|
3128
|
-
result[asName] = instance[`count:${relKey}`];
|
|
3129
|
-
break;
|
|
3130
|
-
}
|
|
3152
|
+
case "count":
|
|
3131
3153
|
case "exists": {
|
|
3132
|
-
result[asName] = instance[
|
|
3154
|
+
result[asName] = instance[relKey];
|
|
3133
3155
|
break;
|
|
3134
3156
|
}
|
|
3135
3157
|
case "first":
|
|
@@ -3149,19 +3171,14 @@ const reconcileInstanceQuery = (query, response, instanceModel, key, store) => {
|
|
|
3149
3171
|
};
|
|
3150
3172
|
|
|
3151
3173
|
//#endregion
|
|
3152
|
-
//#region src/simple-loader.ts
|
|
3174
|
+
//#region src/loaders/simple-loader.ts
|
|
3153
3175
|
const createSimpleLoader = (opts = {}) => {
|
|
3154
3176
|
const fetchWithQuery = async (query) => {
|
|
3155
|
-
|
|
3177
|
+
return configuredFetch(opts, "", {
|
|
3156
3178
|
method: "POST",
|
|
3157
3179
|
headers: { "Content-Type": "application/json" },
|
|
3158
3180
|
body: JSON.stringify({ query })
|
|
3159
|
-
}).then(async (r) => {
|
|
3160
|
-
const content = await r.json();
|
|
3161
|
-
if (r.status !== 200) throw new Error(`[${r.status}] ${JSON.stringify(content)}`);
|
|
3162
|
-
return content;
|
|
3163
3181
|
});
|
|
3164
|
-
return response;
|
|
3165
3182
|
};
|
|
3166
3183
|
return { fetchModel: async (model, ids, q) => {
|
|
3167
3184
|
const modelDesc = modelMap[model];
|
|
@@ -3169,7 +3186,7 @@ const createSimpleLoader = (opts = {}) => {
|
|
|
3169
3186
|
"~model": model,
|
|
3170
3187
|
"~key": id$1
|
|
3171
3188
|
}));
|
|
3172
|
-
const response = await fetchWithQuery(serializeInstanceQuery(q, instances
|
|
3189
|
+
const response = await fetchWithQuery(serializeInstanceQuery(makeModelQuerySerializable(q), instances));
|
|
3173
3190
|
const pool = new ModelPool(modelMap);
|
|
3174
3191
|
pool.add(response);
|
|
3175
3192
|
return Object.fromEntries(ids.map((id$1) => [id$1, reconcileInstanceQuery(q, response, modelDesc, id$1, pool)]));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codecks/fetch",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Quickly create deeply nested queries for the Codecks API with advanced TypeScript support",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -21,6 +21,10 @@
|
|
|
21
21
|
"types": "./dist/index.d.ts",
|
|
22
22
|
"exports": {
|
|
23
23
|
".": "./dist/index.js",
|
|
24
|
+
"./_exploration/store": "./dist/_exploration/store.js",
|
|
25
|
+
"./_exploration/loader": "./dist/_exploration/loader.js",
|
|
26
|
+
"./_exploration/api-requester": "./dist/_exploration/api-requester.js",
|
|
27
|
+
"./_exploration/react": "./dist/_exploration/create-hooks.js",
|
|
24
28
|
"./package.json": "./package.json"
|
|
25
29
|
},
|
|
26
30
|
"publishConfig": {
|
|
@@ -41,11 +45,15 @@
|
|
|
41
45
|
"devDependencies": {
|
|
42
46
|
"@changesets/cli": "^2.29.7",
|
|
43
47
|
"@types/node": "^22.15.17",
|
|
48
|
+
"@types/react": "^19.2.2",
|
|
44
49
|
"msw": "^2.10.4",
|
|
45
50
|
"prettier": "^3.6.2",
|
|
46
51
|
"tsdown": "^0.11.9",
|
|
47
52
|
"typescript": "^5.9.2",
|
|
48
53
|
"vite-node": "^3.2.4",
|
|
49
54
|
"vitest": "^3.1.3"
|
|
55
|
+
},
|
|
56
|
+
"peerDependencies": {
|
|
57
|
+
"react": "^19.0.0"
|
|
50
58
|
}
|
|
51
59
|
}
|