feat: docker compose maybe

This commit is contained in:
2023-11-13 16:10:04 -05:00
parent 180b261e40
commit b625ccd8d6
8031 changed files with 2182966 additions and 0 deletions

390
node_modules/code-red/src/index.js generated vendored Normal file
View File

@ -0,0 +1,390 @@
import * as acorn from 'acorn';
import { walk } from 'estree-walker';
import { id, re } from './utils/id.js';
import { get_comment_handlers } from './utils/comments.js';
/** @typedef {import('estree').Expression} Expression */
/** @typedef {import('estree').Node} Node */
/** @typedef {import('estree').ObjectExpression} ObjectExpression */
/** @typedef {import('estree').Property} Property */
/** @typedef {import('estree').SpreadElement} SpreadElement */
/** @typedef {import('./utils/comments').CommentWithLocation} CommentWithLocation */
/** @type {Record<string, string>} */
const sigils = {
'@': 'AT',
'#': 'HASH'
};
/** @param {TemplateStringsArray} strings */
const join = (strings) => {
let str = strings[0];
for (let i = 1; i < strings.length; i += 1) {
str += `_${id}_${i - 1}_${strings[i]}`;
}
return str.replace(
/([@#])(\w+)/g,
(_m, sigil, name) => `_${id}_${sigils[sigil]}_${name}`
);
};
/**
* @param {any[]} array
* @param {any[]} target
*/
const flatten_body = (array, target) => {
for (let i = 0; i < array.length; i += 1) {
const statement = array[i];
if (Array.isArray(statement)) {
flatten_body(statement, target);
continue;
}
if (statement.type === 'ExpressionStatement') {
if (statement.expression === EMPTY) continue;
if (Array.isArray(statement.expression)) {
// TODO this is hacktacular
let node = statement.expression[0];
while (Array.isArray(node)) node = node[0];
if (node) node.leadingComments = statement.leadingComments;
flatten_body(statement.expression, target);
continue;
}
if (/(Expression|Literal)$/.test(statement.expression.type)) {
target.push(statement);
continue;
}
if (statement.leadingComments)
statement.expression.leadingComments = statement.leadingComments;
if (statement.trailingComments)
statement.expression.trailingComments = statement.trailingComments;
target.push(statement.expression);
continue;
}
target.push(statement);
}
return target;
};
/**
* @param {any[]} array
* @param {any[]} target
*/
const flatten_properties = (array, target) => {
for (let i = 0; i < array.length; i += 1) {
const property = array[i];
if (property.value === EMPTY) continue;
if (property.key === property.value && Array.isArray(property.key)) {
flatten_properties(property.key, target);
continue;
}
target.push(property);
}
return target;
};
/**
* @param {any[]} nodes
* @param {any[]} target
*/
const flatten = (nodes, target) => {
for (let i = 0; i < nodes.length; i += 1) {
const node = nodes[i];
if (node === EMPTY) continue;
if (Array.isArray(node)) {
flatten(node, target);
continue;
}
target.push(node);
}
return target;
};
const EMPTY = { type: 'Empty' };
/**
*
* @param {CommentWithLocation[]} comments
* @param {string} raw
* @returns {any}
*/
const acorn_opts = (comments, raw) => {
const { onComment } = get_comment_handlers(comments, raw);
return {
ecmaVersion: 2022,
sourceType: 'module',
allowAwaitOutsideFunction: true,
allowImportExportEverywhere: true,
allowReturnOutsideFunction: true,
onComment
};
};
/**
* @param {string} raw
* @param {Node} node
* @param {any[]} values
* @param {CommentWithLocation[]} comments
*/
const inject = (raw, node, values, comments) => {
comments.forEach((comment) => {
comment.value = comment.value.replace(re, (m, i) =>
+i in values ? values[+i] : m
);
});
const { enter, leave } = get_comment_handlers(comments, raw);
return walk(node, {
enter,
/** @param {any} node */
leave(node) {
if (node.type === 'Identifier') {
re.lastIndex = 0;
const match = re.exec(node.name);
if (match) {
if (match[1]) {
if (+match[1] in values) {
let value = values[+match[1]];
if (typeof value === 'string') {
value = {
type: 'Identifier',
name: value,
leadingComments: node.leadingComments,
trailingComments: node.trailingComments
};
} else if (typeof value === 'number') {
value = {
type: 'Literal',
value,
leadingComments: node.leadingComments,
trailingComments: node.trailingComments
};
}
this.replace(value || EMPTY);
}
} else {
node.name = `${match[2] ? `@` : `#`}${match[4]}`;
}
}
}
if (node.type === 'Literal') {
if (typeof node.value === 'string') {
re.lastIndex = 0;
const new_value = /** @type {string} */ (node.value).replace(
re,
(m, i) => (+i in values ? values[+i] : m)
);
const has_changed = new_value !== node.value;
node.value = new_value;
if (has_changed && node.raw) {
// preserve the quotes
node.raw = `${node.raw[0]}${JSON.stringify(node.value).slice(
1,
-1
)}${node.raw[node.raw.length - 1]}`;
}
}
}
if (node.type === 'TemplateElement') {
re.lastIndex = 0;
node.value.raw = /** @type {string} */ (node.value.raw).replace(
re,
(m, i) => (+i in values ? values[+i] : m)
);
}
if (node.type === 'Program' || node.type === 'BlockStatement') {
node.body = flatten_body(node.body, []);
}
if (node.type === 'ObjectExpression' || node.type === 'ObjectPattern') {
node.properties = flatten_properties(node.properties, []);
}
if (node.type === 'ArrayExpression' || node.type === 'ArrayPattern') {
node.elements = flatten(node.elements, []);
}
if (
node.type === 'FunctionExpression' ||
node.type === 'FunctionDeclaration' ||
node.type === 'ArrowFunctionExpression'
) {
node.params = flatten(node.params, []);
}
if (node.type === 'CallExpression' || node.type === 'NewExpression') {
node.arguments = flatten(node.arguments, []);
}
if (
node.type === 'ImportDeclaration' ||
node.type === 'ExportNamedDeclaration'
) {
node.specifiers = flatten(node.specifiers, []);
}
if (node.type === 'ForStatement') {
node.init = node.init === EMPTY ? null : node.init;
node.test = node.test === EMPTY ? null : node.test;
node.update = node.update === EMPTY ? null : node.update;
}
leave(node);
}
});
};
/**
*
* @param {TemplateStringsArray} strings
* @param {any[]} values
* @returns {Node[]}
*/
export function b(strings, ...values) {
const str = join(strings);
/** @type {CommentWithLocation[]} */
const comments = [];
try {
let ast = /** @type {any} */ (acorn.parse(str, acorn_opts(comments, str)));
ast = inject(str, ast, values, comments);
return ast.body;
} catch (err) {
handle_error(str, err);
}
}
/**
*
* @param {TemplateStringsArray} strings
* @param {any[]} values
* @returns {Expression & { start: Number, end: number }}
*/
export function x(strings, ...values) {
const str = join(strings);
/** @type {CommentWithLocation[]} */
const comments = [];
try {
let expression =
/** @type {Expression & { start: Number, end: number }} */ (
acorn.parseExpressionAt(str, 0, acorn_opts(comments, str))
);
const match = /\S+/.exec(str.slice(expression.end));
if (match) {
throw new Error(`Unexpected token '${match[0]}'`);
}
expression = /** @type {Expression & { start: Number, end: number }} */ (
inject(str, expression, values, comments)
);
return expression;
} catch (err) {
handle_error(str, err);
}
}
/**
*
* @param {TemplateStringsArray} strings
* @param {any[]} values
* @returns {(Property | SpreadElement) & { start: Number, end: number }}
*/
export function p(strings, ...values) {
const str = `{${join(strings)}}`;
/** @type {CommentWithLocation[]} */
const comments = [];
try {
let expression = /** @type {any} */ (
acorn.parseExpressionAt(str, 0, acorn_opts(comments, str))
);
expression = inject(str, expression, values, comments);
return expression.properties[0];
} catch (err) {
handle_error(str, err);
}
}
/**
* @param {string} str
* @param {Error} err
*/
function handle_error(str, err) {
// TODO location/code frame
re.lastIndex = 0;
str = str.replace(re, (m, i, at, hash, name) => {
if (at) return `@${name}`;
if (hash) return `#${name}`;
return '${...}';
});
console.log(`failed to parse:\n${str}`);
throw err;
}
export { print } from './print/index.js';
/**
* @param {string} source
* @param {any} opts
*/
export const parse = (source, opts) => {
/** @type {CommentWithLocation[]} */
const comments = [];
const { onComment, enter, leave } = get_comment_handlers(comments, source);
const ast = /** @type {any} */ (acorn.parse(source, { onComment, ...opts }));
walk(ast, { enter, leave });
return ast;
};
/**
* @param {string} source
* @param {number} index
* @param {any} opts
*/
export const parseExpressionAt = (source, index, opts) => {
/** @type {CommentWithLocation[]} */
const comments = [];
const { onComment, enter, leave } = get_comment_handlers(comments, source);
const ast = /** @type {any} */ (
acorn.parseExpressionAt(source, index, { onComment, ...opts })
);
walk(ast, { enter, leave });
return ast;
};

1513
node_modules/code-red/src/print/handlers.js generated vendored Executable file

File diff suppressed because it is too large Load Diff

145
node_modules/code-red/src/print/index.js generated vendored Normal file
View File

@ -0,0 +1,145 @@
import * as perisopic from 'periscopic';
import { handle } from './handlers.js';
import { encode } from '@jridgewell/sourcemap-codec';
/** @type {(str?: string) => string} str */
let btoa = () => {
throw new Error(
'Unsupported environment: `window.btoa` or `Buffer` should be supported.'
);
};
if (typeof window !== 'undefined' && typeof window.btoa === 'function') {
btoa = (str) => window.btoa(unescape(encodeURIComponent(str)));
} else if (typeof Buffer === 'function') {
btoa = (str) => Buffer.from(str, 'utf-8').toString('base64');
}
/** @typedef {import('estree').Node} Node */
/**
* @typedef {{
* file?: string;
* sourceMapSource?: string;
* sourceMapContent?: string;
* sourceMapEncodeMappings?: boolean; // default true
* getName?: (name: string) => string;
* }} PrintOptions
*/
/**
* @param {Node} node
* @param {PrintOptions} opts
* @returns {{ code: string, map: any }} // TODO
*/
export function print(node, opts = {}) {
if (Array.isArray(node)) {
return print(
{
type: 'Program',
body: node,
sourceType: 'module'
},
opts
);
}
const {
getName = /** @param {string} x */ (x) => {
throw new Error(`Unhandled sigil @${x}`);
}
} = opts;
let { map: scope_map, scope } = perisopic.analyze(node);
const deconflicted = new WeakMap();
const chunks = handle(node, {
indent: '',
getName,
scope,
scope_map,
deconflicted,
comments: []
});
/** @typedef {[number, number, number, number]} Segment */
let code = '';
let current_column = 0;
/** @type {Segment[][]} */
let mappings = [];
/** @type {Segment[]} */
let current_line = [];
for (let i = 0; i < chunks.length; i += 1) {
const chunk = chunks[i];
code += chunk.content;
if (chunk.loc) {
current_line.push([
current_column,
0, // source index is always zero
chunk.loc.start.line - 1,
chunk.loc.start.column
]);
}
for (let i = 0; i < chunk.content.length; i += 1) {
if (chunk.content[i] === '\n') {
mappings.push(current_line);
current_line = [];
current_column = 0;
} else {
current_column += 1;
}
}
if (chunk.loc) {
current_line.push([
current_column,
0, // source index is always zero
chunk.loc.end.line - 1,
chunk.loc.end.column
]);
}
}
mappings.push(current_line);
const map = {
version: 3,
/** @type {string[]} */
names: [],
sources: [opts.sourceMapSource || null],
sourcesContent: [opts.sourceMapContent || null],
mappings:
opts.sourceMapEncodeMappings == undefined || opts.sourceMapEncodeMappings
? encode(mappings)
: mappings
};
Object.defineProperties(map, {
toString: {
enumerable: false,
value: function toString() {
return JSON.stringify(this);
}
},
toUrl: {
enumerable: false,
value: function toUrl() {
return (
'data:application/json;charset=utf-8;base64,' + btoa(this.toString())
);
}
}
});
return {
code,
map
};
}

86
node_modules/code-red/src/utils/comments.js generated vendored Normal file
View File

@ -0,0 +1,86 @@
import { re } from './id.js';
/** @typedef {import('estree').Comment} Comment */
/** @typedef {import('estree').Node} Node */
/**
* @typedef {Node & {
* start: number;
* end: number;
* has_trailing_newline?: boolean
* }} NodeWithLocation
*/
/**
* @typedef {Comment & {
* start: number;
* end: number;
* has_trailing_newline?: boolean
* }} CommentWithLocation
*/
/**
* @param {CommentWithLocation[]} comments
* @param {string} raw
*/
export const get_comment_handlers = (comments, raw) => ({
// pass to acorn options
/**
* @param {boolean} block
* @param {string} value
* @param {number} start
* @param {number} end
*/
onComment: (block, value, start, end) => {
if (block && /\n/.test(value)) {
let a = start;
while (a > 0 && raw[a - 1] !== '\n') a -= 1;
let b = a;
while (/[ \t]/.test(raw[b])) b += 1;
const indentation = raw.slice(a, b);
value = value.replace(new RegExp(`^${indentation}`, 'gm'), '');
}
comments.push({ type: block ? 'Block' : 'Line', value, start, end });
},
// pass to estree-walker options
/** @param {NodeWithLocation} node */
enter(node) {
let comment;
while (comments[0] && comments[0].start < node.start) {
comment = comments.shift();
comment.value = comment.value.replace(
re,
(match, id, at, hash, value) => {
if (hash) return `#${value}`;
if (at) return `@${value}`;
return match;
}
);
const next = comments[0] || node;
comment.has_trailing_newline =
comment.type === 'Line' ||
/\n/.test(raw.slice(comment.end, next.start));
(node.leadingComments || (node.leadingComments = [])).push(comment);
}
},
/** @param {NodeWithLocation} node */
leave(node) {
if (comments[0]) {
const slice = raw.slice(node.end, comments[0].start);
if (/^[,) \t]*$/.test(slice)) {
node.trailingComments = [comments.shift()];
}
}
}
});

3
node_modules/code-red/src/utils/id.js generated vendored Normal file
View File

@ -0,0 +1,3 @@
// generate an ID that is, to all intents and purposes, unique
export const id = Math.round(Math.random() * 1e20).toString(36);
export const re = new RegExp(`_${id}_(?:(\\d+)|(AT)|(HASH))_(\\w+)?`, 'g');

12
node_modules/code-red/src/utils/push_array.js generated vendored Normal file
View File

@ -0,0 +1,12 @@
/**
* Does `array.push` for all `items`. Needed because `array.push(...items)` throws
* "Maximum call stack size exceeded" when `items` is too big of an array.
*
* @param {any[]} array
* @param {any[]} items
*/
export function push_array(array, items) {
for (let i = 0; i < items.length; i++) {
array.push(items[i]);
}
}