@tiangong-lca/cli 0.0.1
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/README.md +368 -0
- package/bin/tiangong.d.ts +1 -0
- package/bin/tiangong.js +32 -0
- package/dist/scripts/assert-full-coverage.js +77 -0
- package/dist/scripts/assert-full-coverage.js.map +1 -0
- package/dist/src/cli.js +2740 -0
- package/dist/src/cli.js.map +1 -0
- package/dist/src/lib/artifacts.js +86 -0
- package/dist/src/lib/artifacts.js.map +1 -0
- package/dist/src/lib/dotenv.js +36 -0
- package/dist/src/lib/dotenv.js.map +1 -0
- package/dist/src/lib/env.js +139 -0
- package/dist/src/lib/env.js.map +1 -0
- package/dist/src/lib/errors.js +38 -0
- package/dist/src/lib/errors.js.map +1 -0
- package/dist/src/lib/flow-build-alias-map.js +299 -0
- package/dist/src/lib/flow-build-alias-map.js.map +1 -0
- package/dist/src/lib/flow-get.js +81 -0
- package/dist/src/lib/flow-get.js.map +1 -0
- package/dist/src/lib/flow-governance.js +164 -0
- package/dist/src/lib/flow-governance.js.map +1 -0
- package/dist/src/lib/flow-list.js +187 -0
- package/dist/src/lib/flow-list.js.map +1 -0
- package/dist/src/lib/flow-publish-reviewed-data.js +808 -0
- package/dist/src/lib/flow-publish-reviewed-data.js.map +1 -0
- package/dist/src/lib/flow-publish-version.js +541 -0
- package/dist/src/lib/flow-publish-version.js.map +1 -0
- package/dist/src/lib/flow-read.js +310 -0
- package/dist/src/lib/flow-read.js.map +1 -0
- package/dist/src/lib/flow-regen-product.js +1396 -0
- package/dist/src/lib/flow-regen-product.js.map +1 -0
- package/dist/src/lib/flow-remediate.js +821 -0
- package/dist/src/lib/flow-remediate.js.map +1 -0
- package/dist/src/lib/http.js +45 -0
- package/dist/src/lib/http.js.map +1 -0
- package/dist/src/lib/io.js +30 -0
- package/dist/src/lib/io.js.map +1 -0
- package/dist/src/lib/kb-search.js +83 -0
- package/dist/src/lib/kb-search.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-auto-build.js +1328 -0
- package/dist/src/lib/lifecyclemodel-auto-build.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-orchestrate.js +1556 -0
- package/dist/src/lib/lifecyclemodel-orchestrate.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-publish-build.js +296 -0
- package/dist/src/lib/lifecyclemodel-publish-build.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-publish-resulting-process.js +101 -0
- package/dist/src/lib/lifecyclemodel-publish-resulting-process.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-resulting-process.js +1152 -0
- package/dist/src/lib/lifecyclemodel-resulting-process.js.map +1 -0
- package/dist/src/lib/lifecyclemodel-validate-build.js +238 -0
- package/dist/src/lib/lifecyclemodel-validate-build.js.map +1 -0
- package/dist/src/lib/llm.js +383 -0
- package/dist/src/lib/llm.js.map +1 -0
- package/dist/src/lib/process-auto-build.js +717 -0
- package/dist/src/lib/process-auto-build.js.map +1 -0
- package/dist/src/lib/process-batch-build.js +409 -0
- package/dist/src/lib/process-batch-build.js.map +1 -0
- package/dist/src/lib/process-get.js +66 -0
- package/dist/src/lib/process-get.js.map +1 -0
- package/dist/src/lib/process-publish-build.js +451 -0
- package/dist/src/lib/process-publish-build.js.map +1 -0
- package/dist/src/lib/process-resume-build.js +364 -0
- package/dist/src/lib/process-resume-build.js.map +1 -0
- package/dist/src/lib/publish.js +562 -0
- package/dist/src/lib/publish.js.map +1 -0
- package/dist/src/lib/remote.js +88 -0
- package/dist/src/lib/remote.js.map +1 -0
- package/dist/src/lib/review-flow.js +1110 -0
- package/dist/src/lib/review-flow.js.map +1 -0
- package/dist/src/lib/review-lifecyclemodel.js +727 -0
- package/dist/src/lib/review-lifecyclemodel.js.map +1 -0
- package/dist/src/lib/review-process.js +702 -0
- package/dist/src/lib/review-process.js.map +1 -0
- package/dist/src/lib/run.js +106 -0
- package/dist/src/lib/run.js.map +1 -0
- package/dist/src/lib/state-lock.js +150 -0
- package/dist/src/lib/state-lock.js.map +1 -0
- package/dist/src/lib/supabase-client.js +269 -0
- package/dist/src/lib/supabase-client.js.map +1 -0
- package/dist/src/lib/supabase-json-ordered-write.js +186 -0
- package/dist/src/lib/supabase-json-ordered-write.js.map +1 -0
- package/dist/src/lib/supabase-rest.js +138 -0
- package/dist/src/lib/supabase-rest.js.map +1 -0
- package/dist/src/lib/supabase-session.js +424 -0
- package/dist/src/lib/supabase-session.js.map +1 -0
- package/dist/src/lib/tidas-sdk-package-validator.js +493 -0
- package/dist/src/lib/tidas-sdk-package-validator.js.map +1 -0
- package/dist/src/lib/unstructured.js +203 -0
- package/dist/src/lib/unstructured.js.map +1 -0
- package/dist/src/lib/user-api-key.js +75 -0
- package/dist/src/lib/user-api-key.js.map +1 -0
- package/dist/src/lib/validation.js +191 -0
- package/dist/src/lib/validation.js.map +1 -0
- package/dist/src/main.js +38 -0
- package/dist/src/main.js.map +1 -0
- package/package.json +81 -0
|
@@ -0,0 +1,310 @@
|
|
|
1
|
+
import { CliError } from './errors.js';
|
|
2
|
+
import { buildSupabaseAuthHeaders, createSupabaseDataClient, runSupabaseArrayQuery, } from './supabase-client.js';
|
|
3
|
+
const TYPE_OF_DATASET_QUERY_PATH = 'json->flowDataSet->modellingAndValidation->LCIMethod->>typeOfDataSet';
|
|
4
|
+
function isRecord(value) {
|
|
5
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
6
|
+
}
|
|
7
|
+
function buildHeaders(publishableKey, accessToken) {
|
|
8
|
+
return buildSupabaseAuthHeaders(publishableKey, accessToken);
|
|
9
|
+
}
|
|
10
|
+
function normalizeTokenList(values) {
|
|
11
|
+
if (!Array.isArray(values)) {
|
|
12
|
+
return [];
|
|
13
|
+
}
|
|
14
|
+
const seen = new Set();
|
|
15
|
+
const normalized = [];
|
|
16
|
+
for (const value of values) {
|
|
17
|
+
const trimmed = typeof value === 'string' ? value.trim() : '';
|
|
18
|
+
if (!trimmed || seen.has(trimmed)) {
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
normalized.push(trimmed);
|
|
22
|
+
seen.add(trimmed);
|
|
23
|
+
}
|
|
24
|
+
return normalized;
|
|
25
|
+
}
|
|
26
|
+
function normalizeStateCodeList(values) {
|
|
27
|
+
if (!Array.isArray(values)) {
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
const normalized = [];
|
|
32
|
+
for (const value of values) {
|
|
33
|
+
if (!Number.isInteger(value) || value < 0 || seen.has(value)) {
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
normalized.push(value);
|
|
37
|
+
seen.add(value);
|
|
38
|
+
}
|
|
39
|
+
return normalized;
|
|
40
|
+
}
|
|
41
|
+
function buildFlowListUrl(restBaseUrl, filters) {
|
|
42
|
+
const url = new URL(`${restBaseUrl.replace(/\/+$/u, '')}/flows`);
|
|
43
|
+
url.searchParams.set('select', 'id,version,user_id,state_code,modified_at,json');
|
|
44
|
+
const ids = normalizeTokenList(filters.ids);
|
|
45
|
+
if (ids.length === 1) {
|
|
46
|
+
url.searchParams.set('id', `eq.${ids[0]}`);
|
|
47
|
+
}
|
|
48
|
+
else if (ids.length > 1) {
|
|
49
|
+
url.searchParams.set('id', `in.(${ids.join(',')})`);
|
|
50
|
+
}
|
|
51
|
+
if (typeof filters.version === 'string' && filters.version.trim()) {
|
|
52
|
+
url.searchParams.set('version', `eq.${filters.version.trim()}`);
|
|
53
|
+
}
|
|
54
|
+
if (typeof filters.userId === 'string' && filters.userId.trim()) {
|
|
55
|
+
url.searchParams.set('user_id', `eq.${filters.userId.trim()}`);
|
|
56
|
+
}
|
|
57
|
+
const stateCodes = normalizeStateCodeList(filters.stateCodes);
|
|
58
|
+
if (stateCodes.length === 1) {
|
|
59
|
+
url.searchParams.set('state_code', `eq.${stateCodes[0]}`);
|
|
60
|
+
}
|
|
61
|
+
else if (stateCodes.length > 1) {
|
|
62
|
+
url.searchParams.set('state_code', `in.(${stateCodes.join(',')})`);
|
|
63
|
+
}
|
|
64
|
+
const typeOfDataset = normalizeTokenList(filters.typeOfDataset);
|
|
65
|
+
if (typeOfDataset.length === 1) {
|
|
66
|
+
url.searchParams.set(TYPE_OF_DATASET_QUERY_PATH, `eq.${typeOfDataset[0]}`);
|
|
67
|
+
}
|
|
68
|
+
else if (typeOfDataset.length > 1) {
|
|
69
|
+
url.searchParams.set(TYPE_OF_DATASET_QUERY_PATH, `in.(${typeOfDataset.join(',')})`);
|
|
70
|
+
}
|
|
71
|
+
if (typeof filters.order === 'string' && filters.order.trim()) {
|
|
72
|
+
url.searchParams.set('order', filters.order.trim());
|
|
73
|
+
}
|
|
74
|
+
if (Number.isInteger(filters.limit) && filters.limit > 0) {
|
|
75
|
+
url.searchParams.set('limit', String(filters.limit));
|
|
76
|
+
}
|
|
77
|
+
if (Number.isInteger(filters.offset) && filters.offset >= 0) {
|
|
78
|
+
url.searchParams.set('offset', String(filters.offset));
|
|
79
|
+
}
|
|
80
|
+
return url.toString();
|
|
81
|
+
}
|
|
82
|
+
function parseFlowRows(payload, url) {
|
|
83
|
+
if (!Array.isArray(payload)) {
|
|
84
|
+
throw new CliError(`Supabase REST response was not a JSON array for ${url}`, {
|
|
85
|
+
code: 'SUPABASE_REST_RESPONSE_INVALID',
|
|
86
|
+
exitCode: 1,
|
|
87
|
+
details: payload,
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return payload.map((item, index) => {
|
|
91
|
+
if (!isRecord(item)) {
|
|
92
|
+
throw new CliError(`Supabase REST row ${index} was not a JSON object for ${url}`, {
|
|
93
|
+
code: 'SUPABASE_REST_RESPONSE_INVALID',
|
|
94
|
+
exitCode: 1,
|
|
95
|
+
details: item,
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
return {
|
|
99
|
+
id: typeof item.id === 'string' ? item.id : '',
|
|
100
|
+
version: typeof item.version === 'string' ? item.version : '',
|
|
101
|
+
user_id: typeof item.user_id === 'string' ? item.user_id : null,
|
|
102
|
+
state_code: typeof item.state_code === 'number' ? item.state_code : null,
|
|
103
|
+
modified_at: typeof item.modified_at === 'string' ? item.modified_at : null,
|
|
104
|
+
json: item.json,
|
|
105
|
+
};
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function normalizeSupabaseFlowPayload(payload, lookupKey) {
|
|
109
|
+
if (typeof payload === 'string') {
|
|
110
|
+
try {
|
|
111
|
+
const parsed = JSON.parse(payload);
|
|
112
|
+
if (!isRecord(parsed)) {
|
|
113
|
+
throw new CliError(`Supabase REST payload was not a JSON object for ${lookupKey}.`, {
|
|
114
|
+
code: 'SUPABASE_REST_PAYLOAD_INVALID',
|
|
115
|
+
exitCode: 1,
|
|
116
|
+
details: parsed,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
return parsed;
|
|
120
|
+
}
|
|
121
|
+
catch (error) {
|
|
122
|
+
if (error instanceof CliError) {
|
|
123
|
+
throw error;
|
|
124
|
+
}
|
|
125
|
+
throw new CliError(`Supabase REST payload was not valid JSON for ${lookupKey}.`, {
|
|
126
|
+
code: 'SUPABASE_REST_PAYLOAD_INVALID_JSON',
|
|
127
|
+
exitCode: 1,
|
|
128
|
+
details: String(error),
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (!isRecord(payload)) {
|
|
133
|
+
throw new CliError(`Supabase REST payload was missing json for ${lookupKey}.`, {
|
|
134
|
+
code: 'SUPABASE_REST_PAYLOAD_MISSING',
|
|
135
|
+
exitCode: 1,
|
|
136
|
+
details: payload,
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
return payload;
|
|
140
|
+
}
|
|
141
|
+
function applyOrder(query, orderValue) {
|
|
142
|
+
const normalizedOrder = typeof orderValue === 'string' ? orderValue.trim() : '';
|
|
143
|
+
if (!normalizedOrder) {
|
|
144
|
+
return query;
|
|
145
|
+
}
|
|
146
|
+
let nextQuery = query;
|
|
147
|
+
for (const rawToken of normalizedOrder.split(',')) {
|
|
148
|
+
const token = rawToken.trim();
|
|
149
|
+
if (!token) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
const [column, direction, nulls] = token.split('.');
|
|
153
|
+
if (!column) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
nextQuery = nextQuery.order(column, {
|
|
157
|
+
ascending: direction !== 'desc',
|
|
158
|
+
nullsFirst: nulls === 'nullsfirst' ? true : nulls === 'nullslast' ? false : undefined,
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
return nextQuery;
|
|
162
|
+
}
|
|
163
|
+
async function listFlowRows(options) {
|
|
164
|
+
const { client, restBaseUrl } = createSupabaseDataClient(options.runtime, options.fetchImpl, options.timeoutMs);
|
|
165
|
+
const sourceUrl = buildFlowListUrl(restBaseUrl, options.filters);
|
|
166
|
+
let query = client.from('flows').select('id,version,user_id,state_code,modified_at,json');
|
|
167
|
+
const ids = normalizeTokenList(options.filters.ids);
|
|
168
|
+
if (ids.length === 1) {
|
|
169
|
+
query = query.eq('id', ids[0]);
|
|
170
|
+
}
|
|
171
|
+
else if (ids.length > 1) {
|
|
172
|
+
query = query.filter('id', 'in', `(${ids.join(',')})`);
|
|
173
|
+
}
|
|
174
|
+
if (typeof options.filters.version === 'string' && options.filters.version.trim()) {
|
|
175
|
+
query = query.eq('version', options.filters.version.trim());
|
|
176
|
+
}
|
|
177
|
+
if (typeof options.filters.userId === 'string' && options.filters.userId.trim()) {
|
|
178
|
+
query = query.eq('user_id', options.filters.userId.trim());
|
|
179
|
+
}
|
|
180
|
+
const stateCodes = normalizeStateCodeList(options.filters.stateCodes);
|
|
181
|
+
if (stateCodes.length === 1) {
|
|
182
|
+
query = query.eq('state_code', stateCodes[0]);
|
|
183
|
+
}
|
|
184
|
+
else if (stateCodes.length > 1) {
|
|
185
|
+
query = query.filter('state_code', 'in', `(${stateCodes.join(',')})`);
|
|
186
|
+
}
|
|
187
|
+
const typeOfDataset = normalizeTokenList(options.filters.typeOfDataset);
|
|
188
|
+
if (typeOfDataset.length === 1) {
|
|
189
|
+
query = query.filter(TYPE_OF_DATASET_QUERY_PATH, 'eq', typeOfDataset[0]);
|
|
190
|
+
}
|
|
191
|
+
else if (typeOfDataset.length > 1) {
|
|
192
|
+
query = query.filter(TYPE_OF_DATASET_QUERY_PATH, 'in', `(${typeOfDataset.join(',')})`);
|
|
193
|
+
}
|
|
194
|
+
query = applyOrder(query, options.filters.order ?? null);
|
|
195
|
+
const limit = Number.isInteger(options.filters.limit) && options.filters.limit > 0
|
|
196
|
+
? options.filters.limit
|
|
197
|
+
: null;
|
|
198
|
+
const offset = Number.isInteger(options.filters.offset) && options.filters.offset >= 0
|
|
199
|
+
? options.filters.offset
|
|
200
|
+
: null;
|
|
201
|
+
if (limit !== null && offset !== null) {
|
|
202
|
+
query = query.limit(limit);
|
|
203
|
+
query.url.searchParams.set('offset', String(offset));
|
|
204
|
+
}
|
|
205
|
+
else if (limit !== null) {
|
|
206
|
+
query = query.limit(limit);
|
|
207
|
+
}
|
|
208
|
+
const rows = parseFlowRows(await runSupabaseArrayQuery(query, sourceUrl), sourceUrl);
|
|
209
|
+
return { rows, sourceUrl };
|
|
210
|
+
}
|
|
211
|
+
function buildAmbiguousMatchDetails(rows) {
|
|
212
|
+
return rows.map((row) => ({
|
|
213
|
+
id: row.id,
|
|
214
|
+
version: row.version,
|
|
215
|
+
user_id: row.user_id,
|
|
216
|
+
state_code: row.state_code,
|
|
217
|
+
}));
|
|
218
|
+
}
|
|
219
|
+
function latestRowsAreAmbiguous(rows) {
|
|
220
|
+
return rows.length > 1 && rows[0]?.version === rows[1]?.version;
|
|
221
|
+
}
|
|
222
|
+
async function fetchOneFlowRow(options) {
|
|
223
|
+
const stateCodes = Number.isInteger(options.stateCode) && options.stateCode >= 0
|
|
224
|
+
? [options.stateCode]
|
|
225
|
+
: [];
|
|
226
|
+
const sharedFilters = {
|
|
227
|
+
ids: [options.id],
|
|
228
|
+
userId: options.userId ?? null,
|
|
229
|
+
stateCodes,
|
|
230
|
+
};
|
|
231
|
+
if (options.version) {
|
|
232
|
+
const exact = await listFlowRows({
|
|
233
|
+
runtime: options.runtime,
|
|
234
|
+
filters: {
|
|
235
|
+
...sharedFilters,
|
|
236
|
+
version: options.version,
|
|
237
|
+
order: 'version.desc',
|
|
238
|
+
limit: 2,
|
|
239
|
+
offset: 0,
|
|
240
|
+
},
|
|
241
|
+
timeoutMs: options.timeoutMs,
|
|
242
|
+
fetchImpl: options.fetchImpl,
|
|
243
|
+
});
|
|
244
|
+
if (exact.rows.length === 1) {
|
|
245
|
+
return {
|
|
246
|
+
row: exact.rows[0],
|
|
247
|
+
sourceUrl: exact.sourceUrl,
|
|
248
|
+
resolution: 'remote_supabase_exact',
|
|
249
|
+
};
|
|
250
|
+
}
|
|
251
|
+
if (exact.rows.length > 1) {
|
|
252
|
+
throw new CliError(`Multiple visible flow rows matched ${options.id}@${options.version}. Add a stricter --state-code or --user-id filter.`, {
|
|
253
|
+
code: 'FLOW_GET_AMBIGUOUS',
|
|
254
|
+
exitCode: 2,
|
|
255
|
+
details: {
|
|
256
|
+
flow_id: options.id,
|
|
257
|
+
version: options.version,
|
|
258
|
+
matches: buildAmbiguousMatchDetails(exact.rows),
|
|
259
|
+
source_url: exact.sourceUrl,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
if (!options.fallbackToLatest) {
|
|
264
|
+
return null;
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
const latest = await listFlowRows({
|
|
268
|
+
runtime: options.runtime,
|
|
269
|
+
filters: {
|
|
270
|
+
...sharedFilters,
|
|
271
|
+
order: 'version.desc',
|
|
272
|
+
limit: 2,
|
|
273
|
+
offset: 0,
|
|
274
|
+
},
|
|
275
|
+
timeoutMs: options.timeoutMs,
|
|
276
|
+
fetchImpl: options.fetchImpl,
|
|
277
|
+
});
|
|
278
|
+
if (latest.rows.length === 0) {
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
if (latestRowsAreAmbiguous(latest.rows)) {
|
|
282
|
+
throw new CliError(`Multiple visible flow rows matched the latest version for ${options.id}. Add a stricter --state-code or --user-id filter.`, {
|
|
283
|
+
code: 'FLOW_GET_AMBIGUOUS',
|
|
284
|
+
exitCode: 2,
|
|
285
|
+
details: {
|
|
286
|
+
flow_id: options.id,
|
|
287
|
+
version: latest.rows[0].version,
|
|
288
|
+
matches: buildAmbiguousMatchDetails(latest.rows),
|
|
289
|
+
source_url: latest.sourceUrl,
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
row: latest.rows[0],
|
|
295
|
+
sourceUrl: latest.sourceUrl,
|
|
296
|
+
resolution: options.version ? 'remote_supabase_latest_fallback' : 'remote_supabase_latest',
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
export { buildFlowListUrl, buildHeaders, buildAmbiguousMatchDetails, fetchOneFlowRow, latestRowsAreAmbiguous, listFlowRows, normalizeStateCodeList, normalizeSupabaseFlowPayload, normalizeTokenList, parseFlowRows, };
|
|
300
|
+
export const __testInternals = {
|
|
301
|
+
buildFlowListUrl,
|
|
302
|
+
buildHeaders,
|
|
303
|
+
buildAmbiguousMatchDetails,
|
|
304
|
+
latestRowsAreAmbiguous,
|
|
305
|
+
normalizeStateCodeList,
|
|
306
|
+
normalizeSupabaseFlowPayload,
|
|
307
|
+
normalizeTokenList,
|
|
308
|
+
parseFlowRows,
|
|
309
|
+
};
|
|
310
|
+
//# sourceMappingURL=flow-read.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"flow-read.js","sourceRoot":"","sources":["../../../src/lib/flow-read.ts"],"names":[],"mappings":"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","sourcesContent":["import { CliError } from './errors.js';\nimport type { FetchLike } from './http.js';\nimport {\n buildSupabaseAuthHeaders,\n createSupabaseDataClient,\n runSupabaseArrayQuery,\n type SupabaseDataRuntime,\n} from './supabase-client.js';\n\ntype JsonObject = Record<string, unknown>;\n\nconst TYPE_OF_DATASET_QUERY_PATH =\n 'json->flowDataSet->modellingAndValidation->LCIMethod->>typeOfDataSet';\n\nexport type SupabaseFlowRow = {\n id: string;\n version: string;\n user_id: string | null;\n state_code: number | null;\n modified_at: string | null;\n json: unknown;\n};\n\nexport type FlowListQueryFilters = {\n ids?: string[];\n version?: string | null;\n userId?: string | null;\n stateCodes?: number[];\n typeOfDataset?: string[];\n order?: string | null;\n limit?: number | null;\n offset?: number | null;\n};\n\nexport type SupabaseFlowLookup = {\n row: SupabaseFlowRow;\n sourceUrl: string;\n resolution:\n | 'remote_supabase_exact'\n | 'remote_supabase_latest'\n | 'remote_supabase_latest_fallback';\n};\n\ntype QueryWithUrl = {\n url: URL;\n limit: (count: number) => QueryWithUrl;\n};\n\nfunction isRecord(value: unknown): value is JsonObject {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction buildHeaders(publishableKey: string, accessToken: string): Record<string, string> {\n return buildSupabaseAuthHeaders(publishableKey, accessToken);\n}\n\nfunction normalizeTokenList(values: readonly string[] | undefined): string[] {\n if (!Array.isArray(values)) {\n return [];\n }\n\n const seen = new Set<string>();\n const normalized: string[] = [];\n for (const value of values) {\n const trimmed = typeof value === 'string' ? value.trim() : '';\n if (!trimmed || seen.has(trimmed)) {\n continue;\n }\n normalized.push(trimmed);\n seen.add(trimmed);\n }\n return normalized;\n}\n\nfunction normalizeStateCodeList(values: readonly number[] | undefined): number[] {\n if (!Array.isArray(values)) {\n return [];\n }\n\n const seen = new Set<number>();\n const normalized: number[] = [];\n for (const value of values) {\n if (!Number.isInteger(value) || value < 0 || seen.has(value)) {\n continue;\n }\n normalized.push(value);\n seen.add(value);\n }\n return normalized;\n}\n\nfunction buildFlowListUrl(restBaseUrl: string, filters: FlowListQueryFilters): string {\n const url = new URL(`${restBaseUrl.replace(/\\/+$/u, '')}/flows`);\n url.searchParams.set('select', 'id,version,user_id,state_code,modified_at,json');\n\n const ids = normalizeTokenList(filters.ids);\n if (ids.length === 1) {\n url.searchParams.set('id', `eq.${ids[0]}`);\n } else if (ids.length > 1) {\n url.searchParams.set('id', `in.(${ids.join(',')})`);\n }\n\n if (typeof filters.version === 'string' && filters.version.trim()) {\n url.searchParams.set('version', `eq.${filters.version.trim()}`);\n }\n\n if (typeof filters.userId === 'string' && filters.userId.trim()) {\n url.searchParams.set('user_id', `eq.${filters.userId.trim()}`);\n }\n\n const stateCodes = normalizeStateCodeList(filters.stateCodes);\n if (stateCodes.length === 1) {\n url.searchParams.set('state_code', `eq.${stateCodes[0]}`);\n } else if (stateCodes.length > 1) {\n url.searchParams.set('state_code', `in.(${stateCodes.join(',')})`);\n }\n\n const typeOfDataset = normalizeTokenList(filters.typeOfDataset);\n if (typeOfDataset.length === 1) {\n url.searchParams.set(TYPE_OF_DATASET_QUERY_PATH, `eq.${typeOfDataset[0]}`);\n } else if (typeOfDataset.length > 1) {\n url.searchParams.set(TYPE_OF_DATASET_QUERY_PATH, `in.(${typeOfDataset.join(',')})`);\n }\n\n if (typeof filters.order === 'string' && filters.order.trim()) {\n url.searchParams.set('order', filters.order.trim());\n }\n\n if (Number.isInteger(filters.limit) && (filters.limit as number) > 0) {\n url.searchParams.set('limit', String(filters.limit));\n }\n\n if (Number.isInteger(filters.offset) && (filters.offset as number) >= 0) {\n url.searchParams.set('offset', String(filters.offset));\n }\n\n return url.toString();\n}\n\nfunction parseFlowRows(payload: unknown, url: string): SupabaseFlowRow[] {\n if (!Array.isArray(payload)) {\n throw new CliError(`Supabase REST response was not a JSON array for ${url}`, {\n code: 'SUPABASE_REST_RESPONSE_INVALID',\n exitCode: 1,\n details: payload,\n });\n }\n\n return payload.map((item, index) => {\n if (!isRecord(item)) {\n throw new CliError(`Supabase REST row ${index} was not a JSON object for ${url}`, {\n code: 'SUPABASE_REST_RESPONSE_INVALID',\n exitCode: 1,\n details: item,\n });\n }\n\n return {\n id: typeof item.id === 'string' ? item.id : '',\n version: typeof item.version === 'string' ? item.version : '',\n user_id: typeof item.user_id === 'string' ? item.user_id : null,\n state_code: typeof item.state_code === 'number' ? item.state_code : null,\n modified_at: typeof item.modified_at === 'string' ? item.modified_at : null,\n json: item.json,\n };\n });\n}\n\nfunction normalizeSupabaseFlowPayload(payload: unknown, lookupKey: string): JsonObject {\n if (typeof payload === 'string') {\n try {\n const parsed = JSON.parse(payload);\n if (!isRecord(parsed)) {\n throw new CliError(`Supabase REST payload was not a JSON object for ${lookupKey}.`, {\n code: 'SUPABASE_REST_PAYLOAD_INVALID',\n exitCode: 1,\n details: parsed,\n });\n }\n return parsed;\n } catch (error) {\n if (error instanceof CliError) {\n throw error;\n }\n\n throw new CliError(`Supabase REST payload was not valid JSON for ${lookupKey}.`, {\n code: 'SUPABASE_REST_PAYLOAD_INVALID_JSON',\n exitCode: 1,\n details: String(error),\n });\n }\n }\n\n if (!isRecord(payload)) {\n throw new CliError(`Supabase REST payload was missing json for ${lookupKey}.`, {\n code: 'SUPABASE_REST_PAYLOAD_MISSING',\n exitCode: 1,\n details: payload,\n });\n }\n\n return payload;\n}\n\nfunction applyOrder<Query extends { order: (column: string, options?: object) => Query }>(\n query: Query,\n orderValue: string | null | undefined,\n): Query {\n const normalizedOrder = typeof orderValue === 'string' ? orderValue.trim() : '';\n if (!normalizedOrder) {\n return query;\n }\n\n let nextQuery = query;\n for (const rawToken of normalizedOrder.split(',')) {\n const token = rawToken.trim();\n if (!token) {\n continue;\n }\n\n const [column, direction, nulls] = token.split('.');\n if (!column) {\n continue;\n }\n\n nextQuery = nextQuery.order(column, {\n ascending: direction !== 'desc',\n nullsFirst: nulls === 'nullsfirst' ? true : nulls === 'nullslast' ? false : undefined,\n });\n }\n\n return nextQuery;\n}\n\nasync function listFlowRows(options: {\n runtime: SupabaseDataRuntime;\n filters: FlowListQueryFilters;\n timeoutMs: number;\n fetchImpl: FetchLike;\n}): Promise<{ rows: SupabaseFlowRow[]; sourceUrl: string }> {\n const { client, restBaseUrl } = createSupabaseDataClient(\n options.runtime,\n options.fetchImpl,\n options.timeoutMs,\n );\n const sourceUrl = buildFlowListUrl(restBaseUrl, options.filters);\n let query = client.from('flows').select('id,version,user_id,state_code,modified_at,json');\n\n const ids = normalizeTokenList(options.filters.ids);\n if (ids.length === 1) {\n query = query.eq('id', ids[0] as string);\n } else if (ids.length > 1) {\n query = query.filter('id', 'in', `(${ids.join(',')})`);\n }\n\n if (typeof options.filters.version === 'string' && options.filters.version.trim()) {\n query = query.eq('version', options.filters.version.trim());\n }\n\n if (typeof options.filters.userId === 'string' && options.filters.userId.trim()) {\n query = query.eq('user_id', options.filters.userId.trim());\n }\n\n const stateCodes = normalizeStateCodeList(options.filters.stateCodes);\n if (stateCodes.length === 1) {\n query = query.eq('state_code', stateCodes[0] as number);\n } else if (stateCodes.length > 1) {\n query = query.filter('state_code', 'in', `(${stateCodes.join(',')})`);\n }\n\n const typeOfDataset = normalizeTokenList(options.filters.typeOfDataset);\n if (typeOfDataset.length === 1) {\n query = query.filter(TYPE_OF_DATASET_QUERY_PATH, 'eq', typeOfDataset[0] as string);\n } else if (typeOfDataset.length > 1) {\n query = query.filter(TYPE_OF_DATASET_QUERY_PATH, 'in', `(${typeOfDataset.join(',')})`);\n }\n\n query = applyOrder(query, options.filters.order ?? null);\n\n const limit =\n Number.isInteger(options.filters.limit) && (options.filters.limit as number) > 0\n ? (options.filters.limit as number)\n : null;\n const offset =\n Number.isInteger(options.filters.offset) && (options.filters.offset as number) >= 0\n ? (options.filters.offset as number)\n : null;\n\n if (limit !== null && offset !== null) {\n query = query.limit(limit);\n (query as unknown as QueryWithUrl).url.searchParams.set('offset', String(offset));\n } else if (limit !== null) {\n query = query.limit(limit);\n }\n\n const rows = parseFlowRows(await runSupabaseArrayQuery(query, sourceUrl), sourceUrl);\n return { rows, sourceUrl };\n}\n\nfunction buildAmbiguousMatchDetails(rows: SupabaseFlowRow[]): Array<{\n id: string;\n version: string;\n user_id: string | null;\n state_code: number | null;\n}> {\n return rows.map((row) => ({\n id: row.id,\n version: row.version,\n user_id: row.user_id,\n state_code: row.state_code,\n }));\n}\n\nfunction latestRowsAreAmbiguous(rows: SupabaseFlowRow[]): boolean {\n return rows.length > 1 && rows[0]?.version === rows[1]?.version;\n}\n\nasync function fetchOneFlowRow(options: {\n runtime: SupabaseDataRuntime;\n id: string;\n version?: string | null;\n userId?: string | null;\n stateCode?: number | null;\n timeoutMs: number;\n fetchImpl: FetchLike;\n fallbackToLatest?: boolean;\n}): Promise<SupabaseFlowLookup | null> {\n const stateCodes =\n Number.isInteger(options.stateCode) && (options.stateCode as number) >= 0\n ? [options.stateCode as number]\n : [];\n const sharedFilters = {\n ids: [options.id],\n userId: options.userId ?? null,\n stateCodes,\n } satisfies FlowListQueryFilters;\n\n if (options.version) {\n const exact = await listFlowRows({\n runtime: options.runtime,\n filters: {\n ...sharedFilters,\n version: options.version,\n order: 'version.desc',\n limit: 2,\n offset: 0,\n },\n timeoutMs: options.timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n\n if (exact.rows.length === 1) {\n return {\n row: exact.rows[0] as SupabaseFlowRow,\n sourceUrl: exact.sourceUrl,\n resolution: 'remote_supabase_exact',\n };\n }\n\n if (exact.rows.length > 1) {\n throw new CliError(\n `Multiple visible flow rows matched ${options.id}@${options.version}. Add a stricter --state-code or --user-id filter.`,\n {\n code: 'FLOW_GET_AMBIGUOUS',\n exitCode: 2,\n details: {\n flow_id: options.id,\n version: options.version,\n matches: buildAmbiguousMatchDetails(exact.rows),\n source_url: exact.sourceUrl,\n },\n },\n );\n }\n\n if (!options.fallbackToLatest) {\n return null;\n }\n }\n\n const latest = await listFlowRows({\n runtime: options.runtime,\n filters: {\n ...sharedFilters,\n order: 'version.desc',\n limit: 2,\n offset: 0,\n },\n timeoutMs: options.timeoutMs,\n fetchImpl: options.fetchImpl,\n });\n\n if (latest.rows.length === 0) {\n return null;\n }\n\n if (latestRowsAreAmbiguous(latest.rows)) {\n throw new CliError(\n `Multiple visible flow rows matched the latest version for ${options.id}. Add a stricter --state-code or --user-id filter.`,\n {\n code: 'FLOW_GET_AMBIGUOUS',\n exitCode: 2,\n details: {\n flow_id: options.id,\n version: latest.rows[0].version,\n matches: buildAmbiguousMatchDetails(latest.rows),\n source_url: latest.sourceUrl,\n },\n },\n );\n }\n\n return {\n row: latest.rows[0] as SupabaseFlowRow,\n sourceUrl: latest.sourceUrl,\n resolution: options.version ? 'remote_supabase_latest_fallback' : 'remote_supabase_latest',\n };\n}\n\nexport {\n buildFlowListUrl,\n buildHeaders,\n buildAmbiguousMatchDetails,\n fetchOneFlowRow,\n latestRowsAreAmbiguous,\n listFlowRows,\n normalizeStateCodeList,\n normalizeSupabaseFlowPayload,\n normalizeTokenList,\n parseFlowRows,\n};\n\nexport const __testInternals = {\n buildFlowListUrl,\n buildHeaders,\n buildAmbiguousMatchDetails,\n latestRowsAreAmbiguous,\n normalizeStateCodeList,\n normalizeSupabaseFlowPayload,\n normalizeTokenList,\n parseFlowRows,\n};\n\nexport type { SupabaseDataRuntime };\n"]}
|