rastack 0.0.16
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/CHANGELOG.md +43013 -0
- package/dist/.prettierrc +7 -0
- package/dist/compile/analyze.d.ts +12 -0
- package/dist/compile/analyze.js +233 -0
- package/dist/compile/index.d.ts +19 -0
- package/dist/compile/index.js +107 -0
- package/dist/compile/manifest.d.ts +4 -0
- package/dist/compile/manifest.js +12 -0
- package/dist/compile/model.d.ts +54 -0
- package/dist/compile/model.js +7 -0
- package/dist/compile/openapi.d.ts +11 -0
- package/dist/compile/openapi.js +233 -0
- package/dist/compile/program.d.ts +10 -0
- package/dist/compile/program.js +61 -0
- package/dist/csv-schema.d.ts +28 -0
- package/dist/csv-schema.js +162 -0
- package/dist/define/index.d.ts +117 -0
- package/dist/define/index.js +74 -0
- package/dist/entity-generation/delete-method.d.ts +1 -0
- package/dist/entity-generation/delete-method.js +31 -0
- package/dist/entity-generation/form.d.ts +13 -0
- package/dist/entity-generation/form.js +136 -0
- package/dist/entity-generation/get-method.d.ts +1 -0
- package/dist/entity-generation/get-method.js +67 -0
- package/dist/entity-generation/imports.d.ts +5 -0
- package/dist/entity-generation/imports.js +91 -0
- package/dist/entity-generation/sync-method.d.ts +30 -0
- package/dist/entity-generation/sync-method.js +158 -0
- package/dist/entity-generation/update-method.d.ts +1 -0
- package/dist/entity-generation/update-method.js +29 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +53 -0
- package/dist/rad-compile.d.ts +11 -0
- package/dist/rad-compile.js +82 -0
- package/dist/rad-wasm-build.d.ts +14 -0
- package/dist/rad-wasm-build.js +74 -0
- package/dist/rad.d.ts +17 -0
- package/dist/rad.js +88 -0
- package/dist/scan.d.ts +12 -0
- package/dist/scan.js +79 -0
- package/dist/schema/camel-to-pastel.d.ts +1 -0
- package/dist/schema/camel-to-pastel.js +7 -0
- package/dist/schema/capitalise-first-letter.d.ts +1 -0
- package/dist/schema/capitalise-first-letter.js +7 -0
- package/dist/schema/extract-response.d.ts +2 -0
- package/dist/schema/extract-response.js +30 -0
- package/dist/schema/fetch-schema.d.ts +7 -0
- package/dist/schema/fetch-schema.js +23 -0
- package/dist/schema/remove-non-model-paths.d.ts +2 -0
- package/dist/schema/remove-non-model-paths.js +15 -0
- package/dist/schema/to-camel-case.d.ts +1 -0
- package/dist/schema/to-camel-case.js +11 -0
- package/dist/schema/to-pastel-case.d.ts +1 -0
- package/dist/schema/to-pastel-case.js +10 -0
- package/dist/schema-convert.d.ts +1 -0
- package/dist/schema-convert.js +63 -0
- package/dist/schema-entities.d.ts +14 -0
- package/dist/schema-entities.js +293 -0
- package/dist/schema-fetch.d.ts +1 -0
- package/dist/schema-fetch.js +81 -0
- package/dist/schema-full.d.ts +1 -0
- package/dist/schema-full.js +45 -0
- package/dist/schema-index.d.ts +1 -0
- package/dist/schema-index.js +34 -0
- package/dist/schema-params.d.ts +1 -0
- package/dist/schema-params.js +100 -0
- package/dist/seed.d.ts +17 -0
- package/dist/seed.js +252 -0
- package/hooks/form/form.ts +207 -0
- package/hooks/form/index.ts +8 -0
- package/hooks/form/interfaces.ts +217 -0
- package/hooks/form/structure.ts +39 -0
- package/hooks/form/validate-schema.ts +49 -0
- package/hooks/index.ts +3 -0
- package/hooks/query/api.ts +42 -0
- package/hooks/query/delete.ts +45 -0
- package/hooks/query/fetch.ts +48 -0
- package/hooks/query/index.ts +21 -0
- package/hooks/query/interfaces.ts +111 -0
- package/hooks/query/list.ts +286 -0
- package/hooks/query/update.ts +88 -0
- package/hooks/query/url.ts +31 -0
- package/hooks/real-time/index.ts +1 -0
- package/hooks/real-time/pusher.ts +43 -0
- package/jest.config.cjs +6 -0
- package/package.json +57 -0
- package/provider/index.ts +13 -0
- package/provider/provider.tsx +187 -0
- package/provider/types.ts +114 -0
- package/provider/warehouse.ts +167 -0
- package/provider/wasm.ts +124 -0
- package/runtime.ts +3 -0
- package/src/.prettierrc +7 -0
- package/src/compile/analyze.ts +224 -0
- package/src/compile/index.ts +86 -0
- package/src/compile/manifest.ts +10 -0
- package/src/compile/model.ts +69 -0
- package/src/compile/openapi.ts +266 -0
- package/src/compile/program.ts +40 -0
- package/src/csv-schema.ts +187 -0
- package/src/define/index.ts +162 -0
- package/src/entity-generation/delete-method.ts +37 -0
- package/src/entity-generation/form.ts +169 -0
- package/src/entity-generation/get-method.ts +80 -0
- package/src/entity-generation/imports.ts +110 -0
- package/src/entity-generation/sync-method.ts +222 -0
- package/src/entity-generation/update-method.ts +38 -0
- package/src/index.ts +77 -0
- package/src/rad-compile.ts +88 -0
- package/src/rad-wasm-build.ts +102 -0
- package/src/rad.ts +101 -0
- package/src/scan.ts +89 -0
- package/src/schema/camel-to-pastel.ts +3 -0
- package/src/schema/capitalise-first-letter.ts +3 -0
- package/src/schema/extract-response.ts +38 -0
- package/src/schema/fetch-schema.ts +12 -0
- package/src/schema/remove-non-model-paths.ts +13 -0
- package/src/schema/to-camel-case.ts +7 -0
- package/src/schema/to-pastel-case.ts +6 -0
- package/src/schema-convert.ts +61 -0
- package/src/schema-entities.ts +401 -0
- package/src/schema-fetch.ts +82 -0
- package/src/schema-full.ts +38 -0
- package/src/schema-index.ts +29 -0
- package/src/schema-params.ts +116 -0
- package/src/seed.ts +297 -0
- package/sync/engine.ts +392 -0
- package/sync/hooks.ts +450 -0
- package/sync/index.ts +8 -0
- package/sync/persistence.ts +237 -0
- package/sync/provider.tsx +91 -0
- package/sync/registry.ts +36 -0
- package/sync/store.ts +126 -0
- package/sync/transactions.ts +300 -0
- package/sync/types.ts +94 -0
- package/test/compile.spec.ts +192 -0
- package/test/csv-schema.spec.ts +143 -0
- package/test/schema-entities.spec.ts +688 -0
- package/tsconfig.json +24 -0
- package/types.ts +19 -0
|
@@ -0,0 +1,293 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
exports.main = exports.generateFiles = exports.generateFolders = exports.collectEntityMeta = void 0;
|
|
13
|
+
const fs_1 = require("fs");
|
|
14
|
+
const path_1 = require("path");
|
|
15
|
+
const extract_response_1 = require("./schema/extract-response");
|
|
16
|
+
const fetch_schema_1 = require("./schema/fetch-schema");
|
|
17
|
+
const remove_non_model_paths_1 = require("./schema/remove-non-model-paths");
|
|
18
|
+
const camel_to_pastel_1 = require("./schema/camel-to-pastel");
|
|
19
|
+
const get_method_1 = require("./entity-generation/get-method");
|
|
20
|
+
const update_method_1 = require("./entity-generation/update-method");
|
|
21
|
+
const imports_1 = require("./entity-generation/imports");
|
|
22
|
+
const form_1 = require("./entity-generation/form");
|
|
23
|
+
const delete_method_1 = require("./entity-generation/delete-method");
|
|
24
|
+
const sync_method_1 = require("./entity-generation/sync-method");
|
|
25
|
+
const to_camel_case_1 = require("./schema/to-camel-case");
|
|
26
|
+
function pathSegments(pathKey) {
|
|
27
|
+
return pathKey.replace(/\/$/, "").split("/");
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Pre-pass over the OpenAPI paths: collects, per entity, the sync mode
|
|
31
|
+
* (from rastack's `x-rastack-sync` vendor extension), confirmed operations,
|
|
32
|
+
* the list/detail URLs, the row schema, and the list/detail operation ids
|
|
33
|
+
* (used to wire cache invalidation for non-sync entities).
|
|
34
|
+
*/
|
|
35
|
+
function collectEntityMeta(paths) {
|
|
36
|
+
const meta = {};
|
|
37
|
+
Object.keys(paths).forEach((pathKey) => {
|
|
38
|
+
const appName = pathKey.split("/")[2];
|
|
39
|
+
const modelName = pathKey.split("/")[4];
|
|
40
|
+
const indexKey = `${appName}|${modelName}`;
|
|
41
|
+
if (!meta[indexKey]) {
|
|
42
|
+
meta[indexKey] = { sync: false, confirmedOperationIds: new Set() };
|
|
43
|
+
}
|
|
44
|
+
const entityMeta = meta[indexKey];
|
|
45
|
+
const segments = pathSegments(pathKey);
|
|
46
|
+
const isListPath = segments.length === 5;
|
|
47
|
+
const isDetailPath = segments.length === 6 && segments[5].startsWith("{");
|
|
48
|
+
if (isListPath) {
|
|
49
|
+
entityMeta.listUrl = pathKey;
|
|
50
|
+
}
|
|
51
|
+
if (isDetailPath) {
|
|
52
|
+
entityMeta.detailUrl = pathKey;
|
|
53
|
+
entityMeta.detailParam = segments[5].slice(1, -1);
|
|
54
|
+
}
|
|
55
|
+
Object.keys(paths[pathKey]).forEach((method) => {
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
const operation = paths[pathKey][method];
|
|
58
|
+
const syncExtension = operation["x-rastack-sync"];
|
|
59
|
+
if (syncExtension === "local" || syncExtension === "confirmed") {
|
|
60
|
+
entityMeta.sync = true;
|
|
61
|
+
}
|
|
62
|
+
if (operation["x-rastack-sync-load"] === "lazy") {
|
|
63
|
+
entityMeta.lazy = true;
|
|
64
|
+
}
|
|
65
|
+
if (operation["x-rastack-sync-client-ids"] === true) {
|
|
66
|
+
entityMeta.clientIds = true;
|
|
67
|
+
}
|
|
68
|
+
if (syncExtension === "confirmed" && operation.operationId) {
|
|
69
|
+
entityMeta.confirmedOperationIds.add(operation.operationId);
|
|
70
|
+
}
|
|
71
|
+
const [responseBodySchema, isList] = (0, extract_response_1.extractResponseBodySchema)(operation);
|
|
72
|
+
const operationId = operation.operationId || "";
|
|
73
|
+
const isPostList = method === "post" &&
|
|
74
|
+
(operationId.includes("List") || operationId.includes("list"));
|
|
75
|
+
if (method === "get" || isPostList) {
|
|
76
|
+
if (isList || isPostList) {
|
|
77
|
+
if (isListPath && !entityMeta.listOperationId) {
|
|
78
|
+
entityMeta.listOperationId = operationId;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
else if (isDetailPath && !entityMeta.detailOperationId) {
|
|
82
|
+
entityMeta.detailOperationId = operationId;
|
|
83
|
+
}
|
|
84
|
+
if (responseBodySchema && !entityMeta.rowSchema) {
|
|
85
|
+
entityMeta.rowSchema = `I${responseBodySchema}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
return meta;
|
|
91
|
+
}
|
|
92
|
+
exports.collectEntityMeta = collectEntityMeta;
|
|
93
|
+
function generateFolders(entitiesPath, paths) {
|
|
94
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
95
|
+
Object.keys(paths).forEach((key) => {
|
|
96
|
+
const appName = key.split("/")[2];
|
|
97
|
+
const modelName = key.split("/")[4];
|
|
98
|
+
const appFolder = (0, path_1.join)(entitiesPath, appName);
|
|
99
|
+
const modelFolder = (0, path_1.join)(appFolder, modelName);
|
|
100
|
+
(0, fs_1.mkdirSync)(appFolder, { recursive: true });
|
|
101
|
+
(0, fs_1.mkdirSync)(modelFolder, { recursive: true });
|
|
102
|
+
});
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
exports.generateFolders = generateFolders;
|
|
106
|
+
function generateFiles(entitiesPath, paths) {
|
|
107
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
108
|
+
const uniqueOperationNames = [];
|
|
109
|
+
const modelFileImports = {};
|
|
110
|
+
const modelFileData = {};
|
|
111
|
+
const keysFileData = {};
|
|
112
|
+
const modelImportsFileData = {};
|
|
113
|
+
const formMutationOperations = {};
|
|
114
|
+
const entityMeta = collectEntityMeta(paths);
|
|
115
|
+
Object.keys(paths).forEach((pathKey) => {
|
|
116
|
+
const appName = pathKey.split("/")[2];
|
|
117
|
+
const modelName = pathKey.split("/")[4];
|
|
118
|
+
const indexKey = `${appName}|${modelName}`;
|
|
119
|
+
if (!formMutationOperations[indexKey]) {
|
|
120
|
+
formMutationOperations[indexKey] = {
|
|
121
|
+
post: {
|
|
122
|
+
operationId: undefined,
|
|
123
|
+
schema: undefined,
|
|
124
|
+
},
|
|
125
|
+
put: {
|
|
126
|
+
operationId: undefined,
|
|
127
|
+
schema: undefined,
|
|
128
|
+
},
|
|
129
|
+
patch: {
|
|
130
|
+
operationId: undefined,
|
|
131
|
+
schema: undefined,
|
|
132
|
+
},
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
if (!modelImportsFileData[appName]) {
|
|
136
|
+
modelImportsFileData[appName] = [modelName];
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
if (!modelImportsFileData[appName].includes(modelName)) {
|
|
140
|
+
modelImportsFileData[appName].push(modelName);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
Object.keys(paths[pathKey]).forEach((method) => {
|
|
144
|
+
var _a, _b, _c, _d;
|
|
145
|
+
// @ts-ignore
|
|
146
|
+
const methodInformation = paths[pathKey][method];
|
|
147
|
+
const methodParameters = methodInformation.parameters;
|
|
148
|
+
const pathParameters = methodParameters
|
|
149
|
+
? methodParameters
|
|
150
|
+
.filter((item) => item.required)
|
|
151
|
+
.filter((item) => item.in === "path")
|
|
152
|
+
.map((item) => item.name)
|
|
153
|
+
: [];
|
|
154
|
+
const requestBody = methodInformation.requestBody;
|
|
155
|
+
// @ts-ignore
|
|
156
|
+
const requestBodySchema = (_c = (_b = (_a = requestBody === null || requestBody === void 0 ? void 0 : requestBody.content) === null || _a === void 0 ? void 0 : _a["application/json"]) === null || _b === void 0 ? void 0 : _b.schema["$ref"]) === null || _c === void 0 ? void 0 : _c.replace("#/components/schemas/", "");
|
|
157
|
+
let [responseBodySchema, isList] = (0, extract_response_1.extractResponseBodySchema)(methodInformation);
|
|
158
|
+
const requiredParameters = methodParameters
|
|
159
|
+
? methodParameters
|
|
160
|
+
.filter((item) => item.required)
|
|
161
|
+
.map((item) => item.name)
|
|
162
|
+
: [];
|
|
163
|
+
const operationId = methodInformation.operationId;
|
|
164
|
+
if (!uniqueOperationNames.includes(operationId)) {
|
|
165
|
+
uniqueOperationNames.push(operationId);
|
|
166
|
+
let apiMethods = "";
|
|
167
|
+
let importStatements = new Set();
|
|
168
|
+
const isPostListEndpoint = method === "post" &&
|
|
169
|
+
(operationId.includes("List") || operationId.includes("list"));
|
|
170
|
+
const isListEndpoint = isList || isPostListEndpoint;
|
|
171
|
+
const meta = entityMeta[indexKey];
|
|
172
|
+
const isSyncEntity = (meta === null || meta === void 0 ? void 0 : meta.sync) === true;
|
|
173
|
+
const isConfirmedOperation = methodInformation["x-rastack-sync"] === "confirmed" &&
|
|
174
|
+
method !== "get";
|
|
175
|
+
const modelCamel = (0, to_camel_case_1.toCamelCase)(modelName);
|
|
176
|
+
const listKeyRef = (meta === null || meta === void 0 ? void 0 : meta.listOperationId)
|
|
177
|
+
? `${modelCamel}QueriesKeys.${meta.listOperationId}`
|
|
178
|
+
: undefined;
|
|
179
|
+
const itemKeyRef = (meta === null || meta === void 0 ? void 0 : meta.detailOperationId)
|
|
180
|
+
? `${modelCamel}QueriesKeys.${meta.detailOperationId}`
|
|
181
|
+
: undefined;
|
|
182
|
+
if (isConfirmedOperation) {
|
|
183
|
+
[apiMethods, importStatements] = (0, sync_method_1.generateConfirmedMethod)(pathKey, method, operationId, requestBodySchema ? `I${requestBodySchema}` : undefined, responseBodySchema ? `I${responseBodySchema}` : undefined);
|
|
184
|
+
formMutationOperations[indexKey] = Object.assign(Object.assign({}, formMutationOperations[indexKey]), { [pathKey]: {
|
|
185
|
+
[method]: {
|
|
186
|
+
operationId: (0, camel_to_pastel_1.camelToPastel)(operationId),
|
|
187
|
+
schema: requestBodySchema ? `I${requestBodySchema}` : "",
|
|
188
|
+
},
|
|
189
|
+
} });
|
|
190
|
+
}
|
|
191
|
+
else if (method === "get" || isPostListEndpoint) {
|
|
192
|
+
if (isSyncEntity && isListEndpoint) {
|
|
193
|
+
[apiMethods, importStatements] = (0, sync_method_1.generateSyncListMethod)(modelName, operationId, meta.rowSchema);
|
|
194
|
+
}
|
|
195
|
+
else if (isSyncEntity && pathKey.includes("{")) {
|
|
196
|
+
const urlParams = ((_d = pathKey.match(/{([^}]+)}/g)) === null || _d === void 0 ? void 0 : _d.map((param) => param.slice(1, -1))) ||
|
|
197
|
+
[];
|
|
198
|
+
[apiMethods, importStatements] = (0, sync_method_1.generateSyncRecordMethod)(modelName, operationId, meta.rowSchema, pathParameters.length > 0 ? pathParameters : urlParams);
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
[apiMethods, importStatements] = (0, get_method_1.generateGetAPIMethod)(pathKey, modelName, operationId, responseBodySchema ? `I${responseBodySchema}` : undefined, isListEndpoint, pathParameters, requiredParameters, method, requestBodySchema !== undefined ? requestBodySchema : "");
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
else if (method === "post" ||
|
|
205
|
+
method === "put" ||
|
|
206
|
+
method === "patch") {
|
|
207
|
+
if (isSyncEntity) {
|
|
208
|
+
[apiMethods, importStatements] = (0, sync_method_1.generateSyncUpdateMethod)(pathKey, method, modelName, operationId, requestBodySchema ? `I${requestBodySchema}` : undefined, responseBodySchema ? `I${responseBodySchema}` : undefined, pathParameters);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
[apiMethods, importStatements] = (0, update_method_1.generateUpdateAPIMethod)(pathKey, method, operationId, requestBodySchema ? `I${requestBodySchema}` : undefined, responseBodySchema ? `I${responseBodySchema}` : undefined, listKeyRef, itemKeyRef);
|
|
212
|
+
}
|
|
213
|
+
formMutationOperations[indexKey] = Object.assign(Object.assign({}, formMutationOperations[indexKey]), { [pathKey]: {
|
|
214
|
+
[method]: {
|
|
215
|
+
operationId: (0, camel_to_pastel_1.camelToPastel)(operationId),
|
|
216
|
+
schema: requestBodySchema ? `I${requestBodySchema}` : "",
|
|
217
|
+
},
|
|
218
|
+
} });
|
|
219
|
+
}
|
|
220
|
+
else if (method === "delete") {
|
|
221
|
+
if (isSyncEntity) {
|
|
222
|
+
[apiMethods, importStatements] = (0, sync_method_1.generateSyncDeleteMethod)(pathKey, modelName, operationId);
|
|
223
|
+
}
|
|
224
|
+
else {
|
|
225
|
+
[apiMethods, importStatements] = (0, delete_method_1.generateDeleteAPIMethod)(pathKey, operationId, listKeyRef);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
modelFileData[indexKey] = (modelFileData[indexKey] || "") + apiMethods;
|
|
229
|
+
modelFileImports[indexKey] = new Set([
|
|
230
|
+
...(modelFileImports[indexKey] || []),
|
|
231
|
+
...importStatements,
|
|
232
|
+
]);
|
|
233
|
+
keysFileData[indexKey] = [
|
|
234
|
+
...(keysFileData[indexKey] || []),
|
|
235
|
+
operationId,
|
|
236
|
+
];
|
|
237
|
+
}
|
|
238
|
+
});
|
|
239
|
+
});
|
|
240
|
+
Object.keys(modelFileData).forEach((key) => {
|
|
241
|
+
var _a;
|
|
242
|
+
const [appName, modelName] = key.split("|");
|
|
243
|
+
const modelFolder = (0, path_1.join)(entitiesPath, appName, modelName);
|
|
244
|
+
const apiFile = (0, path_1.join)(modelFolder, "api.ts");
|
|
245
|
+
const indexFile = (0, path_1.join)(modelFolder, "index.ts");
|
|
246
|
+
const keyImports = (0, imports_1.generateKeyImports)(modelName, keysFileData[key]);
|
|
247
|
+
const [updateFormMethod, importStatements] = (0, form_1.generateUpdateFormMethod)(appName, modelName, formMutationOperations[key]);
|
|
248
|
+
const indexKey = `${appName}|${modelName}`;
|
|
249
|
+
modelFileImports[indexKey] = new Set([
|
|
250
|
+
...(modelFileImports[indexKey] || []),
|
|
251
|
+
...importStatements,
|
|
252
|
+
]);
|
|
253
|
+
let entityDescriptor = "";
|
|
254
|
+
if ((_a = entityMeta[key]) === null || _a === void 0 ? void 0 : _a.sync) {
|
|
255
|
+
const [descriptorCode, descriptorImports] = (0, sync_method_1.generateEntityDescriptor)(appName, modelName, entityMeta[key]);
|
|
256
|
+
entityDescriptor = descriptorCode;
|
|
257
|
+
modelFileImports[indexKey] = new Set([
|
|
258
|
+
...(modelFileImports[indexKey] || []),
|
|
259
|
+
...descriptorImports,
|
|
260
|
+
]);
|
|
261
|
+
}
|
|
262
|
+
const importData = (0, imports_1.generateImportStatements)(modelFileImports[key], modelName);
|
|
263
|
+
const apiFileText = `${importData}\n${keyImports}\n${entityDescriptor}${modelFileData[key]}\n${updateFormMethod}`;
|
|
264
|
+
const indexImports = (0, imports_1.generateIndexImports)(modelName, keysFileData[key]);
|
|
265
|
+
(0, fs_1.writeFileSync)(apiFile, apiFileText, { flag: "w" });
|
|
266
|
+
(0, fs_1.writeFileSync)(indexFile, indexImports, { flag: "w" });
|
|
267
|
+
});
|
|
268
|
+
// create an index file with all the file names per model
|
|
269
|
+
Object.keys(modelImportsFileData).forEach((key) => {
|
|
270
|
+
const modelFolder = (0, path_1.join)(entitiesPath, key);
|
|
271
|
+
const indexFile = (0, path_1.join)(modelFolder, "index.ts");
|
|
272
|
+
const indexImports = (0, imports_1.generateFolderImports)(modelImportsFileData[key]);
|
|
273
|
+
(0, fs_1.writeFileSync)(indexFile, indexImports, { flag: "w" });
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
exports.generateFiles = generateFiles;
|
|
278
|
+
function main(url, entitiesPath) {
|
|
279
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
280
|
+
console.log("Generating Entities");
|
|
281
|
+
const data = yield (0, fetch_schema_1.fetchSchema)(url);
|
|
282
|
+
const filteredPaths = (0, remove_non_model_paths_1.removeNonModelPaths)(data.paths);
|
|
283
|
+
yield generateFolders(entitiesPath, filteredPaths);
|
|
284
|
+
yield generateFiles(entitiesPath, filteredPaths);
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
exports.main = main;
|
|
288
|
+
if (require.main === module) {
|
|
289
|
+
const args = process.argv.slice(2);
|
|
290
|
+
const url = args[0];
|
|
291
|
+
const entitiesPath = args[1];
|
|
292
|
+
main(url, entitiesPath);
|
|
293
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
const fs_1 = require("fs");
|
|
16
|
+
const path_1 = require("path");
|
|
17
|
+
const axios_1 = __importDefault(require("axios"));
|
|
18
|
+
function fetchSchema(url, schemaPath) {
|
|
19
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
20
|
+
const response = yield axios_1.default.get(url);
|
|
21
|
+
(0, fs_1.writeFileSync)(schemaPath, JSON.stringify(response.data, null, 2));
|
|
22
|
+
return response.data;
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function generateFiles(basePath, components) {
|
|
26
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
27
|
+
const schemas = components.schemas;
|
|
28
|
+
Object.keys(schemas).forEach((key) => {
|
|
29
|
+
const schema = schemas[key];
|
|
30
|
+
let schemaKey = key;
|
|
31
|
+
if (key.endsWith("Enum")) {
|
|
32
|
+
schemaKey = key.replace("Enum", "");
|
|
33
|
+
schemaKey = `E${schemaKey}`;
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
schemaKey = `I${schemaKey}`;
|
|
37
|
+
}
|
|
38
|
+
const schemaFolderPath = (0, path_1.join)(basePath, "api-schema");
|
|
39
|
+
const fileName = `${schemaFolderPath}/${schemaKey}.json`;
|
|
40
|
+
(0, fs_1.writeFileSync)(fileName, JSON.stringify(schema, null, 2));
|
|
41
|
+
});
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function replaceReferences(basePath) {
|
|
45
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
46
|
+
const schemaFolderPath = (0, path_1.join)(basePath, "api-schema");
|
|
47
|
+
const schemaFiles = (0, fs_1.readdirSync)(schemaFolderPath);
|
|
48
|
+
schemaFiles.forEach((file) => {
|
|
49
|
+
const filePath = (0, path_1.join)(schemaFolderPath, file);
|
|
50
|
+
const fileContent = JSON.parse((0, fs_1.readFileSync)(filePath, "utf8"));
|
|
51
|
+
let convertedSchema = JSON.stringify(fileContent);
|
|
52
|
+
const searchPattern = /"#\/components\/schemas\/([A-Za-z0-9_-]+)"/g;
|
|
53
|
+
convertedSchema = convertedSchema.replace(searchPattern, (_, matchedSchemaName) => {
|
|
54
|
+
let updatedSchemaName = matchedSchemaName;
|
|
55
|
+
if (updatedSchemaName.endsWith("Enum")) {
|
|
56
|
+
updatedSchemaName = updatedSchemaName.replace("Enum", "");
|
|
57
|
+
updatedSchemaName = `E${updatedSchemaName}`;
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
updatedSchemaName = `I${updatedSchemaName}`;
|
|
61
|
+
}
|
|
62
|
+
return `"${updatedSchemaName}.json"`;
|
|
63
|
+
});
|
|
64
|
+
const writeSchema = JSON.parse(convertedSchema);
|
|
65
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(writeSchema, null, 2));
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
function main() {
|
|
70
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
71
|
+
console.log("Fetching Schema");
|
|
72
|
+
const args = process.argv.slice(2);
|
|
73
|
+
const url = args[0];
|
|
74
|
+
const basePath = args[1];
|
|
75
|
+
const schemaPath = (0, path_1.join)(basePath, "schema.json");
|
|
76
|
+
const { components } = yield fetchSchema(url, schemaPath);
|
|
77
|
+
yield generateFiles(basePath, components);
|
|
78
|
+
yield replaceReferences(basePath);
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const $RefParser = require("@apidevtools/json-schema-ref-parser");
|
|
15
|
+
function generateDereferencedSchema(schemaPath) {
|
|
16
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
17
|
+
try {
|
|
18
|
+
const schemaContent = (0, fs_1.readFileSync)(schemaPath, "utf8");
|
|
19
|
+
const schemaObject = JSON.parse(schemaContent);
|
|
20
|
+
const dereferencedSchema = yield $RefParser.dereference(schemaObject);
|
|
21
|
+
return JSON.stringify(dereferencedSchema, null, 2);
|
|
22
|
+
}
|
|
23
|
+
catch (error) {
|
|
24
|
+
return "";
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function main() {
|
|
29
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
30
|
+
console.log("Resolving Schemas");
|
|
31
|
+
const args = process.argv.slice(2);
|
|
32
|
+
const basePath = args[0];
|
|
33
|
+
const schemaFolderPath = (0, path_1.join)(basePath, "api-schema");
|
|
34
|
+
const outputFolder = (0, path_1.join)(basePath, "form-schema");
|
|
35
|
+
const schemaFiles = (0, fs_1.readdirSync)(schemaFolderPath);
|
|
36
|
+
let compilePromises = schemaFiles.map((schemaFile) => __awaiter(this, void 0, void 0, function* () {
|
|
37
|
+
const schemaFilePath = (0, path_1.join)(schemaFolderPath, schemaFile);
|
|
38
|
+
const generatedCode = yield generateDereferencedSchema(schemaFilePath);
|
|
39
|
+
const outputFilePath = (0, path_1.join)(outputFolder, schemaFile);
|
|
40
|
+
(0, fs_1.writeFileSync)(outputFilePath, generatedCode);
|
|
41
|
+
}));
|
|
42
|
+
let results = yield Promise.all(compilePromises);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const path_1 = require("path");
|
|
13
|
+
const fs_1 = require("fs");
|
|
14
|
+
function main() {
|
|
15
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
16
|
+
console.log("Generating Schema Index");
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
const basePath = args[0];
|
|
19
|
+
const schemaFolderPath = (0, path_1.join)(basePath, "form-schema");
|
|
20
|
+
let indexFileData = 'export * from "./interface";\nexport * from "./params";\n';
|
|
21
|
+
const schemaFiles = (0, fs_1.readdirSync)(schemaFolderPath);
|
|
22
|
+
let compilePromises = schemaFiles.map((schemaFile) => {
|
|
23
|
+
const schemaFileName = schemaFile.replace(".json", "");
|
|
24
|
+
const formSchemaExport = `export { default as Deref${schemaFileName} } from "./form-schema/${schemaFile}";`;
|
|
25
|
+
const schemaExport = `export { default as Schema${schemaFileName} } from "./api-schema/${schemaFile}";`;
|
|
26
|
+
return `${formSchemaExport}\n${schemaExport}`;
|
|
27
|
+
});
|
|
28
|
+
let results = yield Promise.all(compilePromises);
|
|
29
|
+
indexFileData = indexFileData + results.join("\n");
|
|
30
|
+
const outputFile = (0, path_1.join)(basePath, "index.ts");
|
|
31
|
+
(0, fs_1.writeFileSync)(outputFile, indexFileData);
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
main();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
const fs_1 = require("fs");
|
|
13
|
+
const path_1 = require("path");
|
|
14
|
+
const fetch_schema_1 = require("./schema/fetch-schema");
|
|
15
|
+
function generateParams(paths) {
|
|
16
|
+
const pathParam = [];
|
|
17
|
+
Object.keys(paths).map((path) => {
|
|
18
|
+
const pathItem = paths[path];
|
|
19
|
+
console.log(path);
|
|
20
|
+
Object.keys(pathItem).forEach((method) => {
|
|
21
|
+
// @ts-ignore
|
|
22
|
+
const pathOperation = pathItem[method];
|
|
23
|
+
const pathParamData = [];
|
|
24
|
+
if (pathOperation.parameters) {
|
|
25
|
+
pathOperation.parameters.forEach((param) => {
|
|
26
|
+
// @ts-ignore
|
|
27
|
+
const paramObject = param;
|
|
28
|
+
pathParamData.push({
|
|
29
|
+
name: paramObject.name,
|
|
30
|
+
required: paramObject.required || false,
|
|
31
|
+
schema: paramObject.schema,
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
if (pathOperation.operationId) {
|
|
36
|
+
// Operation id to snake case to camelcase and remove the text v1
|
|
37
|
+
const operationId = pathOperation.operationId;
|
|
38
|
+
const camelCaseOperationId = operationId
|
|
39
|
+
.replace(/_v1/g, "")
|
|
40
|
+
.replace(/_([a-z])/g, function (g) {
|
|
41
|
+
return g[1].toUpperCase();
|
|
42
|
+
});
|
|
43
|
+
const capitalizedOperationId = camelCaseOperationId.charAt(0).toUpperCase() +
|
|
44
|
+
camelCaseOperationId.slice(1);
|
|
45
|
+
pathParam.push({
|
|
46
|
+
operationName: capitalizedOperationId,
|
|
47
|
+
paramsArray: pathParamData,
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
return pathParam;
|
|
53
|
+
}
|
|
54
|
+
function generateInterfacesFiles(pathParams, schemaPath) {
|
|
55
|
+
const interfaceFileValues = pathParams.map((pathParam) => {
|
|
56
|
+
const interfaceName = `I${pathParam.operationName}Params`;
|
|
57
|
+
const interfaceValues = pathParam.paramsArray.map((param) => {
|
|
58
|
+
let paramSchemaType = "string";
|
|
59
|
+
if (param.schema) {
|
|
60
|
+
// @ts-ignore
|
|
61
|
+
if (param.schema.type === "array") {
|
|
62
|
+
// @ts-ignore
|
|
63
|
+
if (param.schema.items.enum) {
|
|
64
|
+
// @ts-ignore
|
|
65
|
+
paramSchemaType = param.schema.items.enum
|
|
66
|
+
.map((value) => `"${value}"`)
|
|
67
|
+
.join(" | ");
|
|
68
|
+
paramSchemaType = `(${paramSchemaType})[]`;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
else {
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
if (param.schema.type === "integer") {
|
|
74
|
+
paramSchemaType = "number";
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return `${param.name}${param.required ? "" : "?"}: ${paramSchemaType};`;
|
|
79
|
+
});
|
|
80
|
+
return `export interface ${interfaceName} {
|
|
81
|
+
${interfaceValues.join("\n")}
|
|
82
|
+
}`;
|
|
83
|
+
});
|
|
84
|
+
const interfaceFileValuesString = interfaceFileValues.join("\n");
|
|
85
|
+
const interfaceFile = (0, path_1.join)(schemaPath, `params.ts`);
|
|
86
|
+
(0, fs_1.writeFileSync)(interfaceFile, interfaceFileValuesString, { flag: "w" });
|
|
87
|
+
}
|
|
88
|
+
function main() {
|
|
89
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
console.log("Generating Schema Parameter Definitions");
|
|
91
|
+
const args = process.argv.slice(2);
|
|
92
|
+
const url = args[0];
|
|
93
|
+
const schemaPath = args[1];
|
|
94
|
+
const data = yield (0, fetch_schema_1.fetchSchema)(url);
|
|
95
|
+
const paths = data.paths;
|
|
96
|
+
const pathParams = generateParams(paths);
|
|
97
|
+
generateInterfacesFiles(pathParams, schemaPath);
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
main();
|
package/dist/seed.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* rad seed
|
|
4
|
+
*
|
|
5
|
+
* Loads CSV files from a local directory or GCS bucket into the target
|
|
6
|
+
* Iceberg namespace. Performs schema inference, PII check, and idempotent
|
|
7
|
+
* table creation before writing rows.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* rad seed [--env dev|staging] [--source gs://bucket/ | --source ./myapp-dev/]
|
|
11
|
+
*
|
|
12
|
+
* Environment variables (set via CI secrets or .env):
|
|
13
|
+
* GCP_PROJECT GCP project ID
|
|
14
|
+
* ICEBERG_WAREHOUSE gs://... path to Iceberg warehouse root
|
|
15
|
+
* ICEBERG_CATALOG_URI sqlite:///... or http://... catalog URI
|
|
16
|
+
*/
|
|
17
|
+
export {};
|